Root/target/linux/generic/patches-2.6.39/025-bcma_backport.patch

1--- /dev/null
2+++ b/Documentation/ABI/testing/sysfs-bus-bcma
3@@ -0,0 +1,31 @@
4+What: /sys/bus/bcma/devices/.../manuf
5+Date: May 2011
6+KernelVersion: 2.6.40
7+Contact: Rafał Miłecki <zajec5@gmail.com>
8+Description:
9+ Each BCMA core has it's manufacturer id. See
10+ include/linux/bcma/bcma.h for possible values.
11+
12+What: /sys/bus/bcma/devices/.../id
13+Date: May 2011
14+KernelVersion: 2.6.40
15+Contact: Rafał Miłecki <zajec5@gmail.com>
16+Description:
17+ There are a few types of BCMA cores, they can be identified by
18+ id field.
19+
20+What: /sys/bus/bcma/devices/.../rev
21+Date: May 2011
22+KernelVersion: 2.6.40
23+Contact: Rafał Miłecki <zajec5@gmail.com>
24+Description:
25+ BCMA cores of the same type can still slightly differ depending
26+ on their revision. Use it for detailed programming.
27+
28+What: /sys/bus/bcma/devices/.../class
29+Date: May 2011
30+KernelVersion: 2.6.40
31+Contact: Rafał Miłecki <zajec5@gmail.com>
32+Description:
33+ Each BCMA core is identified by few fields, including class it
34+ belongs to. See include/linux/bcma/bcma.h for possible values.
35--- a/MAINTAINERS
36+++ b/MAINTAINERS
37@@ -5832,6 +5832,13 @@ S: Maintained
38 F: drivers/ssb/
39 F: include/linux/ssb/
40 
41+BROADCOM SPECIFIC AMBA DRIVER (BCMA)
42+M: Rafał Miłecki <zajec5@gmail.com>
43+L: linux-wireless@vger.kernel.org
44+S: Maintained
45+F: drivers/bcma/
46+F: include/linux/bcma/
47+
48 SONY VAIO CONTROL DEVICE DRIVER
49 M: Mattia Dongili <malattia@linux.it>
50 L: platform-driver-x86@vger.kernel.org
51--- a/drivers/Kconfig
52+++ b/drivers/Kconfig
53@@ -68,6 +68,8 @@ source "drivers/watchdog/Kconfig"
54 
55 source "drivers/ssb/Kconfig"
56 
57+source "drivers/bcma/Kconfig"
58+
59 source "drivers/mfd/Kconfig"
60 
61 source "drivers/regulator/Kconfig"
62--- a/drivers/Makefile
63+++ b/drivers/Makefile
64@@ -110,6 +110,7 @@ obj-$(CONFIG_HID) += hid/
65 obj-$(CONFIG_PPC_PS3) += ps3/
66 obj-$(CONFIG_OF) += of/
67 obj-$(CONFIG_SSB) += ssb/
68+obj-$(CONFIG_BCMA) += bcma/
69 obj-$(CONFIG_VHOST_NET) += vhost/
70 obj-$(CONFIG_VLYNQ) += vlynq/
71 obj-$(CONFIG_STAGING) += staging/
72--- /dev/null
73+++ b/drivers/bcma/Kconfig
74@@ -0,0 +1,44 @@
75+config BCMA_POSSIBLE
76+ bool
77+ depends on HAS_IOMEM && HAS_DMA
78+ default y
79+
80+menu "Broadcom specific AMBA"
81+ depends on BCMA_POSSIBLE
82+
83+config BCMA
84+ tristate "BCMA support"
85+ depends on BCMA_POSSIBLE
86+ help
87+ Bus driver for Broadcom specific Advanced Microcontroller Bus
88+ Architecture.
89+
90+# Support for Block-I/O. SELECT this from the driver that needs it.
91+config BCMA_BLOCKIO
92+ bool
93+ depends on BCMA
94+
95+config BCMA_HOST_PCI_POSSIBLE
96+ bool
97+ depends on BCMA && PCI = y
98+ default y
99+
100+config BCMA_HOST_PCI
101+ bool "Support for BCMA on PCI-host bus"
102+ depends on BCMA_HOST_PCI_POSSIBLE
103+
104+config BCMA_DRIVER_PCI_HOSTMODE
105+ bool "Driver for PCI core working in hostmode"
106+ depends on BCMA && MIPS
107+ help
108+ PCI core hostmode operation (external PCI bus).
109+
110+config BCMA_DEBUG
111+ bool "BCMA debugging"
112+ depends on BCMA
113+ help
114+ This turns on additional debugging messages.
115+
116+ If unsure, say N
117+
118+endmenu
119--- /dev/null
120+++ b/drivers/bcma/Makefile
121@@ -0,0 +1,8 @@
122+bcma-y += main.o scan.o core.o sprom.o
123+bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
124+bcma-y += driver_pci.o
125+bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
126+bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
127+obj-$(CONFIG_BCMA) += bcma.o
128+
129+ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
130--- /dev/null
131+++ b/drivers/bcma/README
132@@ -0,0 +1,19 @@
133+Broadcom introduced new bus as replacement for older SSB. It is based on AMBA,
134+however from programming point of view there is nothing AMBA specific we use.
135+
136+Standard AMBA drivers are platform specific, have hardcoded addresses and use
137+AMBA standard fields like CID and PID.
138+
139+In case of Broadcom's cards every device consists of:
140+1) Broadcom specific AMBA device. It is put on AMBA bus, but can not be treated
141+ as standard AMBA device. Reading it's CID or PID can cause machine lockup.
142+2) AMBA standard devices called ports or wrappers. They have CIDs (AMBA_CID)
143+ and PIDs (0x103BB369), but we do not use that info for anything. One of that
144+ devices is used for managing Broadcom specific core.
145+
146+Addresses of AMBA devices are not hardcoded in driver and have to be read from
147+EPROM.
148+
149+In this situation we decided to introduce separated bus. It can contain up to
150+16 devices identified by Broadcom specific fields: manufacturer, id, revision
151+and class.
152--- /dev/null
153+++ b/drivers/bcma/TODO
154@@ -0,0 +1,3 @@
155+- Interrupts
156+- Defines for PCI core driver
157+- Create kernel Documentation (use info from README)
158--- /dev/null
159+++ b/drivers/bcma/bcma_private.h
160@@ -0,0 +1,35 @@
161+#ifndef LINUX_BCMA_PRIVATE_H_
162+#define LINUX_BCMA_PRIVATE_H_
163+
164+#ifndef pr_fmt
165+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
166+#endif
167+
168+#include <linux/bcma/bcma.h>
169+#include <linux/delay.h>
170+
171+#define BCMA_CORE_SIZE 0x1000
172+
173+struct bcma_bus;
174+
175+/* main.c */
176+int bcma_bus_register(struct bcma_bus *bus);
177+void bcma_bus_unregister(struct bcma_bus *bus);
178+
179+/* scan.c */
180+int bcma_bus_scan(struct bcma_bus *bus);
181+
182+/* sprom.c */
183+int bcma_sprom_get(struct bcma_bus *bus);
184+
185+#ifdef CONFIG_BCMA_HOST_PCI
186+/* host_pci.c */
187+extern int __init bcma_host_pci_init(void);
188+extern void __exit bcma_host_pci_exit(void);
189+#endif /* CONFIG_BCMA_HOST_PCI */
190+
191+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
192+void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
193+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
194+
195+#endif
196--- /dev/null
197+++ b/drivers/bcma/core.c
198@@ -0,0 +1,124 @@
199+/*
200+ * Broadcom specific AMBA
201+ * Core ops
202+ *
203+ * Licensed under the GNU/GPL. See COPYING for details.
204+ */
205+
206+#include "bcma_private.h"
207+#include <linux/bcma/bcma.h>
208+
209+bool bcma_core_is_enabled(struct bcma_device *core)
210+{
211+ if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
212+ != BCMA_IOCTL_CLK)
213+ return false;
214+ if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
215+ return false;
216+ return true;
217+}
218+EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
219+
220+void bcma_core_disable(struct bcma_device *core, u32 flags)
221+{
222+ if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
223+ return;
224+
225+ bcma_awrite32(core, BCMA_IOCTL, flags);
226+ bcma_aread32(core, BCMA_IOCTL);
227+ udelay(10);
228+
229+ bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
230+ udelay(1);
231+}
232+EXPORT_SYMBOL_GPL(bcma_core_disable);
233+
234+int bcma_core_enable(struct bcma_device *core, u32 flags)
235+{
236+ bcma_core_disable(core, flags);
237+
238+ bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
239+ bcma_aread32(core, BCMA_IOCTL);
240+
241+ bcma_awrite32(core, BCMA_RESET_CTL, 0);
242+ udelay(1);
243+
244+ bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
245+ bcma_aread32(core, BCMA_IOCTL);
246+ udelay(1);
247+
248+ return 0;
249+}
250+EXPORT_SYMBOL_GPL(bcma_core_enable);
251+
252+void bcma_core_set_clockmode(struct bcma_device *core,
253+ enum bcma_clkmode clkmode)
254+{
255+ u16 i;
256+
257+ WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
258+ core->id.id != BCMA_CORE_PCIE &&
259+ core->id.id != BCMA_CORE_80211);
260+
261+ switch (clkmode) {
262+ case BCMA_CLKMODE_FAST:
263+ bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
264+ udelay(64);
265+ for (i = 0; i < 1500; i++) {
266+ if (bcma_read32(core, BCMA_CLKCTLST) &
267+ BCMA_CLKCTLST_HAVEHT) {
268+ i = 0;
269+ break;
270+ }
271+ udelay(10);
272+ }
273+ if (i)
274+ pr_err("HT force timeout\n");
275+ break;
276+ case BCMA_CLKMODE_DYNAMIC:
277+ pr_warn("Dynamic clockmode not supported yet!\n");
278+ break;
279+ }
280+}
281+EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
282+
283+void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
284+{
285+ u16 i;
286+
287+ WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
288+ WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
289+
290+ if (on) {
291+ bcma_set32(core, BCMA_CLKCTLST, req);
292+ for (i = 0; i < 10000; i++) {
293+ if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
294+ status) {
295+ i = 0;
296+ break;
297+ }
298+ udelay(10);
299+ }
300+ if (i)
301+ pr_err("PLL enable timeout\n");
302+ } else {
303+ pr_warn("Disabling PLL not supported yet!\n");
304+ }
305+}
306+EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
307+
308+u32 bcma_core_dma_translation(struct bcma_device *core)
309+{
310+ switch (core->bus->hosttype) {
311+ case BCMA_HOSTTYPE_PCI:
312+ if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
313+ return BCMA_DMA_TRANSLATION_DMA64_CMT;
314+ else
315+ return BCMA_DMA_TRANSLATION_DMA32_CMT;
316+ default:
317+ pr_err("DMA translation unknown for host %d\n",
318+ core->bus->hosttype);
319+ }
320+ return BCMA_DMA_TRANSLATION_NONE;
321+}
322+EXPORT_SYMBOL(bcma_core_dma_translation);
323--- /dev/null
324+++ b/drivers/bcma/driver_chipcommon.c
325@@ -0,0 +1,103 @@
326+/*
327+ * Broadcom specific AMBA
328+ * ChipCommon core driver
329+ *
330+ * Copyright 2005, Broadcom Corporation
331+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
332+ *
333+ * Licensed under the GNU/GPL. See COPYING for details.
334+ */
335+
336+#include "bcma_private.h"
337+#include <linux/bcma/bcma.h>
338+
339+static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
340+ u32 mask, u32 value)
341+{
342+ value &= mask;
343+ value |= bcma_cc_read32(cc, offset) & ~mask;
344+ bcma_cc_write32(cc, offset, value);
345+
346+ return value;
347+}
348+
349+void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
350+{
351+ u32 leddc_on = 10;
352+ u32 leddc_off = 90;
353+
354+ if (cc->core->id.rev >= 11)
355+ cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
356+ cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
357+ if (cc->core->id.rev >= 35)
358+ cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
359+
360+ if (cc->core->id.rev >= 20) {
361+ bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
362+ bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
363+ }
364+
365+ if (cc->capabilities & BCMA_CC_CAP_PMU)
366+ bcma_pmu_init(cc);
367+ if (cc->capabilities & BCMA_CC_CAP_PCTL)
368+ pr_err("Power control not implemented!\n");
369+
370+ if (cc->core->id.rev >= 16) {
371+ if (cc->core->bus->sprom.leddc_on_time &&
372+ cc->core->bus->sprom.leddc_off_time) {
373+ leddc_on = cc->core->bus->sprom.leddc_on_time;
374+ leddc_off = cc->core->bus->sprom.leddc_off_time;
375+ }
376+ bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
377+ ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
378+ (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
379+ }
380+}
381+
382+/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
383+void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
384+{
385+ /* instant NMI */
386+ bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
387+}
388+
389+void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
390+{
391+ bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
392+}
393+
394+u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
395+{
396+ return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
397+}
398+
399+u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
400+{
401+ return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
402+}
403+
404+u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
405+{
406+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
407+}
408+
409+u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
410+{
411+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
412+}
413+
414+u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
415+{
416+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
417+}
418+EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
419+
420+u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
421+{
422+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
423+}
424+
425+u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
426+{
427+ return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
428+}
429--- /dev/null
430+++ b/drivers/bcma/driver_chipcommon_pmu.c
431@@ -0,0 +1,138 @@
432+/*
433+ * Broadcom specific AMBA
434+ * ChipCommon Power Management Unit driver
435+ *
436+ * Copyright 2009, Michael Buesch <mb@bu3sch.de>
437+ * Copyright 2007, Broadcom Corporation
438+ *
439+ * Licensed under the GNU/GPL. See COPYING for details.
440+ */
441+
442+#include "bcma_private.h"
443+#include <linux/bcma/bcma.h>
444+
445+static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
446+ u32 offset, u32 mask, u32 set)
447+{
448+ u32 value;
449+
450+ bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
451+ bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
452+ bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
453+ value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
454+ value &= mask;
455+ value |= set;
456+ bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
457+ bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
458+}
459+
460+static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
461+{
462+ struct bcma_bus *bus = cc->core->bus;
463+
464+ switch (bus->chipinfo.id) {
465+ case 0x4313:
466+ case 0x4331:
467+ case 43224:
468+ case 43225:
469+ break;
470+ default:
471+ pr_err("PLL init unknown for device 0x%04X\n",
472+ bus->chipinfo.id);
473+ }
474+}
475+
476+static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
477+{
478+ struct bcma_bus *bus = cc->core->bus;
479+ u32 min_msk = 0, max_msk = 0;
480+
481+ switch (bus->chipinfo.id) {
482+ case 0x4313:
483+ min_msk = 0x200D;
484+ max_msk = 0xFFFF;
485+ break;
486+ case 43224:
487+ case 43225:
488+ break;
489+ default:
490+ pr_err("PMU resource config unknown for device 0x%04X\n",
491+ bus->chipinfo.id);
492+ }
493+
494+ /* Set the resource masks. */
495+ if (min_msk)
496+ bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
497+ if (max_msk)
498+ bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
499+}
500+
501+void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
502+{
503+ struct bcma_bus *bus = cc->core->bus;
504+
505+ switch (bus->chipinfo.id) {
506+ case 0x4313:
507+ case 0x4331:
508+ case 43224:
509+ case 43225:
510+ break;
511+ default:
512+ pr_err("PMU switch/regulators init unknown for device "
513+ "0x%04X\n", bus->chipinfo.id);
514+ }
515+}
516+
517+void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
518+{
519+ struct bcma_bus *bus = cc->core->bus;
520+
521+ switch (bus->chipinfo.id) {
522+ case 0x4313:
523+ bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
524+ break;
525+ case 0x4331:
526+ pr_err("Enabling Ext PA lines not implemented\n");
527+ break;
528+ case 43224:
529+ if (bus->chipinfo.rev == 0) {
530+ pr_err("Workarounds for 43224 rev 0 not fully "
531+ "implemented\n");
532+ bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
533+ } else {
534+ bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
535+ }
536+ break;
537+ case 43225:
538+ break;
539+ default:
540+ pr_err("Workarounds unknown for device 0x%04X\n",
541+ bus->chipinfo.id);
542+ }
543+}
544+
545+void bcma_pmu_init(struct bcma_drv_cc *cc)
546+{
547+ u32 pmucap;
548+
549+ pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
550+ cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
551+
552+ pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
553+ pmucap);
554+
555+ if (cc->pmu.rev == 1)
556+ bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
557+ ~BCMA_CC_PMU_CTL_NOILPONW);
558+ else
559+ bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
560+ BCMA_CC_PMU_CTL_NOILPONW);
561+
562+ if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2)
563+ pr_err("Fix for 4329b0 bad LPOM state not implemented!\n");
564+
565+ bcma_pmu_pll_init(cc);
566+ bcma_pmu_resources_init(cc);
567+ bcma_pmu_swreg_init(cc);
568+ bcma_pmu_workarounds(cc);
569+}
570--- /dev/null
571+++ b/drivers/bcma/driver_pci.c
572@@ -0,0 +1,223 @@
573+/*
574+ * Broadcom specific AMBA
575+ * PCI Core
576+ *
577+ * Copyright 2005, Broadcom Corporation
578+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
579+ *
580+ * Licensed under the GNU/GPL. See COPYING for details.
581+ */
582+
583+#include "bcma_private.h"
584+#include <linux/bcma/bcma.h>
585+
586+/**************************************************
587+ * R/W ops.
588+ **************************************************/
589+
590+static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
591+{
592+ pcicore_write32(pc, 0x130, address);
593+ pcicore_read32(pc, 0x130);
594+ return pcicore_read32(pc, 0x134);
595+}
596+
597+#if 0
598+static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
599+{
600+ pcicore_write32(pc, 0x130, address);
601+ pcicore_read32(pc, 0x130);
602+ pcicore_write32(pc, 0x134, data);
603+}
604+#endif
605+
606+static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
607+{
608+ const u16 mdio_control = 0x128;
609+ const u16 mdio_data = 0x12C;
610+ u32 v;
611+ int i;
612+
613+ v = (1 << 30); /* Start of Transaction */
614+ v |= (1 << 28); /* Write Transaction */
615+ v |= (1 << 17); /* Turnaround */
616+ v |= (0x1F << 18);
617+ v |= (phy << 4);
618+ pcicore_write32(pc, mdio_data, v);
619+
620+ udelay(10);
621+ for (i = 0; i < 200; i++) {
622+ v = pcicore_read32(pc, mdio_control);
623+ if (v & 0x100 /* Trans complete */)
624+ break;
625+ msleep(1);
626+ }
627+}
628+
629+static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
630+{
631+ const u16 mdio_control = 0x128;
632+ const u16 mdio_data = 0x12C;
633+ int max_retries = 10;
634+ u16 ret = 0;
635+ u32 v;
636+ int i;
637+
638+ v = 0x80; /* Enable Preamble Sequence */
639+ v |= 0x2; /* MDIO Clock Divisor */
640+ pcicore_write32(pc, mdio_control, v);
641+
642+ if (pc->core->id.rev >= 10) {
643+ max_retries = 200;
644+ bcma_pcie_mdio_set_phy(pc, device);
645+ }
646+
647+ v = (1 << 30); /* Start of Transaction */
648+ v |= (1 << 29); /* Read Transaction */
649+ v |= (1 << 17); /* Turnaround */
650+ if (pc->core->id.rev < 10)
651+ v |= (u32)device << 22;
652+ v |= (u32)address << 18;
653+ pcicore_write32(pc, mdio_data, v);
654+ /* Wait for the device to complete the transaction */
655+ udelay(10);
656+ for (i = 0; i < max_retries; i++) {
657+ v = pcicore_read32(pc, mdio_control);
658+ if (v & 0x100 /* Trans complete */) {
659+ udelay(10);
660+ ret = pcicore_read32(pc, mdio_data);
661+ break;
662+ }
663+ msleep(1);
664+ }
665+ pcicore_write32(pc, mdio_control, 0);
666+ return ret;
667+}
668+
669+static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
670+ u8 address, u16 data)
671+{
672+ const u16 mdio_control = 0x128;
673+ const u16 mdio_data = 0x12C;
674+ int max_retries = 10;
675+ u32 v;
676+ int i;
677+
678+ v = 0x80; /* Enable Preamble Sequence */
679+ v |= 0x2; /* MDIO Clock Divisor */
680+ pcicore_write32(pc, mdio_control, v);
681+
682+ if (pc->core->id.rev >= 10) {
683+ max_retries = 200;
684+ bcma_pcie_mdio_set_phy(pc, device);
685+ }
686+
687+ v = (1 << 30); /* Start of Transaction */
688+ v |= (1 << 28); /* Write Transaction */
689+ v |= (1 << 17); /* Turnaround */
690+ if (pc->core->id.rev < 10)
691+ v |= (u32)device << 22;
692+ v |= (u32)address << 18;
693+ v |= data;
694+ pcicore_write32(pc, mdio_data, v);
695+ /* Wait for the device to complete the transaction */
696+ udelay(10);
697+ for (i = 0; i < max_retries; i++) {
698+ v = pcicore_read32(pc, mdio_control);
699+ if (v & 0x100 /* Trans complete */)
700+ break;
701+ msleep(1);
702+ }
703+ pcicore_write32(pc, mdio_control, 0);
704+}
705+
706+/**************************************************
707+ * Workarounds.
708+ **************************************************/
709+
710+static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
711+{
712+ return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
713+}
714+
715+static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
716+{
717+ const u8 serdes_pll_device = 0x1D;
718+ const u8 serdes_rx_device = 0x1F;
719+ u16 tmp;
720+
721+ bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
722+ bcma_pcicore_polarity_workaround(pc));
723+ tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
724+ if (tmp & 0x4000)
725+ bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
726+}
727+
728+/**************************************************
729+ * Init.
730+ **************************************************/
731+
732+static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
733+{
734+ bcma_pcicore_serdes_workaround(pc);
735+}
736+
737+static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
738+{
739+ struct bcma_bus *bus = pc->core->bus;
740+ u16 chipid_top;
741+
742+ chipid_top = (bus->chipinfo.id & 0xFF00);
743+ if (chipid_top != 0x4700 &&
744+ chipid_top != 0x5300)
745+ return false;
746+
747+ if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
748+ return false;
749+
750+#if 0
751+ /* TODO: on BCMA we use address from EROM instead of magic formula */
752+ u32 tmp;
753+ return !mips_busprobe32(tmp, (bus->mmio +
754+ (pc->core->core_index * BCMA_CORE_SIZE)));
755+#endif
756+
757+ return true;
758+}
759+
760+void bcma_core_pci_init(struct bcma_drv_pci *pc)
761+{
762+ if (bcma_core_pci_is_in_hostmode(pc)) {
763+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
764+ bcma_core_pci_hostmode_init(pc);
765+#else
766+ pr_err("Driver compiled without support for hostmode PCI\n");
767+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
768+ } else {
769+ bcma_core_pci_clientmode_init(pc);
770+ }
771+}
772+
773+int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
774+ bool enable)
775+{
776+ struct pci_dev *pdev = pc->core->bus->host_pci;
777+ u32 coremask, tmp;
778+ int err;
779+
780+ err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
781+ if (err)
782+ goto out;
783+
784+ coremask = BIT(core->core_index) << 8;
785+ if (enable)
786+ tmp |= coremask;
787+ else
788+ tmp &= ~coremask;
789+
790+ err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
791+
792+out:
793+ return err;
794+}
795+EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
796--- /dev/null
797+++ b/drivers/bcma/host_pci.c
798@@ -0,0 +1,251 @@
799+/*
800+ * Broadcom specific AMBA
801+ * PCI Host
802+ *
803+ * Licensed under the GNU/GPL. See COPYING for details.
804+ */
805+
806+#include "bcma_private.h"
807+#include <linux/slab.h>
808+#include <linux/bcma/bcma.h>
809+#include <linux/pci.h>
810+
811+static void bcma_host_pci_switch_core(struct bcma_device *core)
812+{
813+ pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN,
814+ core->addr);
815+ pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2,
816+ core->wrap);
817+ core->bus->mapped_core = core;
818+ pr_debug("Switched to core: 0x%X\n", core->id.id);
819+}
820+
821+static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
822+{
823+ if (core->bus->mapped_core != core)
824+ bcma_host_pci_switch_core(core);
825+ return ioread8(core->bus->mmio + offset);
826+}
827+
828+static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
829+{
830+ if (core->bus->mapped_core != core)
831+ bcma_host_pci_switch_core(core);
832+ return ioread16(core->bus->mmio + offset);
833+}
834+
835+static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
836+{
837+ if (core->bus->mapped_core != core)
838+ bcma_host_pci_switch_core(core);
839+ return ioread32(core->bus->mmio + offset);
840+}
841+
842+static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
843+ u8 value)
844+{
845+ if (core->bus->mapped_core != core)
846+ bcma_host_pci_switch_core(core);
847+ iowrite8(value, core->bus->mmio + offset);
848+}
849+
850+static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
851+ u16 value)
852+{
853+ if (core->bus->mapped_core != core)
854+ bcma_host_pci_switch_core(core);
855+ iowrite16(value, core->bus->mmio + offset);
856+}
857+
858+static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
859+ u32 value)
860+{
861+ if (core->bus->mapped_core != core)
862+ bcma_host_pci_switch_core(core);
863+ iowrite32(value, core->bus->mmio + offset);
864+}
865+
866+#ifdef CONFIG_BCMA_BLOCKIO
867+void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
868+ size_t count, u16 offset, u8 reg_width)
869+{
870+ void __iomem *addr = core->bus->mmio + offset;
871+ if (core->bus->mapped_core != core)
872+ bcma_host_pci_switch_core(core);
873+ switch (reg_width) {
874+ case sizeof(u8):
875+ ioread8_rep(addr, buffer, count);
876+ break;
877+ case sizeof(u16):
878+ WARN_ON(count & 1);
879+ ioread16_rep(addr, buffer, count >> 1);
880+ break;
881+ case sizeof(u32):
882+ WARN_ON(count & 3);
883+ ioread32_rep(addr, buffer, count >> 2);
884+ break;
885+ default:
886+ WARN_ON(1);
887+ }
888+}
889+
890+void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
891+ size_t count, u16 offset, u8 reg_width)
892+{
893+ void __iomem *addr = core->bus->mmio + offset;
894+ if (core->bus->mapped_core != core)
895+ bcma_host_pci_switch_core(core);
896+ switch (reg_width) {
897+ case sizeof(u8):
898+ iowrite8_rep(addr, buffer, count);
899+ break;
900+ case sizeof(u16):
901+ WARN_ON(count & 1);
902+ iowrite16_rep(addr, buffer, count >> 1);
903+ break;
904+ case sizeof(u32):
905+ WARN_ON(count & 3);
906+ iowrite32_rep(addr, buffer, count >> 2);
907+ break;
908+ default:
909+ WARN_ON(1);
910+ }
911+}
912+#endif
913+
914+static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
915+{
916+ if (core->bus->mapped_core != core)
917+ bcma_host_pci_switch_core(core);
918+ return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
919+}
920+
921+static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset,
922+ u32 value)
923+{
924+ if (core->bus->mapped_core != core)
925+ bcma_host_pci_switch_core(core);
926+ iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
927+}
928+
929+const struct bcma_host_ops bcma_host_pci_ops = {
930+ .read8 = bcma_host_pci_read8,
931+ .read16 = bcma_host_pci_read16,
932+ .read32 = bcma_host_pci_read32,
933+ .write8 = bcma_host_pci_write8,
934+ .write16 = bcma_host_pci_write16,
935+ .write32 = bcma_host_pci_write32,
936+#ifdef CONFIG_BCMA_BLOCKIO
937+ .block_read = bcma_host_pci_block_read,
938+ .block_write = bcma_host_pci_block_write,
939+#endif
940+ .aread32 = bcma_host_pci_aread32,
941+ .awrite32 = bcma_host_pci_awrite32,
942+};
943+
944+static int bcma_host_pci_probe(struct pci_dev *dev,
945+ const struct pci_device_id *id)
946+{
947+ struct bcma_bus *bus;
948+ int err = -ENOMEM;
949+ const char *name;
950+ u32 val;
951+
952+ /* Alloc */
953+ bus = kzalloc(sizeof(*bus), GFP_KERNEL);
954+ if (!bus)
955+ goto out;
956+
957+ /* Basic PCI configuration */
958+ err = pci_enable_device(dev);
959+ if (err)
960+ goto err_kfree_bus;
961+
962+ name = dev_name(&dev->dev);
963+ if (dev->driver && dev->driver->name)
964+ name = dev->driver->name;
965+ err = pci_request_regions(dev, name);
966+ if (err)
967+ goto err_pci_disable;
968+ pci_set_master(dev);
969+
970+ /* Disable the RETRY_TIMEOUT register (0x41) to keep
971+ * PCI Tx retries from interfering with C3 CPU state */
972+ pci_read_config_dword(dev, 0x40, &val);
973+ if ((val & 0x0000ff00) != 0)
974+ pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
975+
976+ /* SSB needed additional powering up, do we have any AMBA PCI cards? */
977+ if (!pci_is_pcie(dev))
978+ pr_err("PCI card detected, report problems.\n");
979+
980+ /* Map MMIO */
981+ err = -ENOMEM;
982+ bus->mmio = pci_iomap(dev, 0, ~0UL);
983+ if (!bus->mmio)
984+ goto err_pci_release_regions;
985+
986+ /* Host specific */
987+ bus->host_pci = dev;
988+ bus->hosttype = BCMA_HOSTTYPE_PCI;
989+ bus->ops = &bcma_host_pci_ops;
990+
991+ /* Register */
992+ err = bcma_bus_register(bus);
993+ if (err)
994+ goto err_pci_unmap_mmio;
995+
996+ pci_set_drvdata(dev, bus);
997+
998+out:
999+ return err;
1000+
1001+err_pci_unmap_mmio:
1002+ pci_iounmap(dev, bus->mmio);
1003+err_pci_release_regions:
1004+ pci_release_regions(dev);
1005+err_pci_disable:
1006+ pci_disable_device(dev);
1007+err_kfree_bus:
1008+ kfree(bus);
1009+ return err;
1010+}
1011+
1012+static void bcma_host_pci_remove(struct pci_dev *dev)
1013+{
1014+ struct bcma_bus *bus = pci_get_drvdata(dev);
1015+
1016+ bcma_bus_unregister(bus);
1017+ pci_iounmap(dev, bus->mmio);
1018+ pci_release_regions(dev);
1019+ pci_disable_device(dev);
1020+ kfree(bus);
1021+ pci_set_drvdata(dev, NULL);
1022+}
1023+
1024+static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
1025+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
1026+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
1027+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
1028+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
1029+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
1030+ { 0, },
1031+};
1032+MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
1033+
1034+static struct pci_driver bcma_pci_bridge_driver = {
1035+ .name = "bcma-pci-bridge",
1036+ .id_table = bcma_pci_bridge_tbl,
1037+ .probe = bcma_host_pci_probe,
1038+ .remove = bcma_host_pci_remove,
1039+};
1040+
1041+int __init bcma_host_pci_init(void)
1042+{
1043+ return pci_register_driver(&bcma_pci_bridge_driver);
1044+}
1045+
1046+void __exit bcma_host_pci_exit(void)
1047+{
1048+ pci_unregister_driver(&bcma_pci_bridge_driver);
1049+}
1050--- /dev/null
1051+++ b/drivers/bcma/main.c
1052@@ -0,0 +1,257 @@
1053+/*
1054+ * Broadcom specific AMBA
1055+ * Bus subsystem
1056+ *
1057+ * Licensed under the GNU/GPL. See COPYING for details.
1058+ */
1059+
1060+#include "bcma_private.h"
1061+#include <linux/bcma/bcma.h>
1062+#include <linux/slab.h>
1063+
1064+MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
1065+MODULE_LICENSE("GPL");
1066+
1067+static int bcma_bus_match(struct device *dev, struct device_driver *drv);
1068+static int bcma_device_probe(struct device *dev);
1069+static int bcma_device_remove(struct device *dev);
1070+
1071+static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
1072+{
1073+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1074+ return sprintf(buf, "0x%03X\n", core->id.manuf);
1075+}
1076+static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
1077+{
1078+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1079+ return sprintf(buf, "0x%03X\n", core->id.id);
1080+}
1081+static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
1082+{
1083+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1084+ return sprintf(buf, "0x%02X\n", core->id.rev);
1085+}
1086+static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
1087+{
1088+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1089+ return sprintf(buf, "0x%X\n", core->id.class);
1090+}
1091+static struct device_attribute bcma_device_attrs[] = {
1092+ __ATTR_RO(manuf),
1093+ __ATTR_RO(id),
1094+ __ATTR_RO(rev),
1095+ __ATTR_RO(class),
1096+ __ATTR_NULL,
1097+};
1098+
1099+static struct bus_type bcma_bus_type = {
1100+ .name = "bcma",
1101+ .match = bcma_bus_match,
1102+ .probe = bcma_device_probe,
1103+ .remove = bcma_device_remove,
1104+ .dev_attrs = bcma_device_attrs,
1105+};
1106+
1107+static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
1108+{
1109+ struct bcma_device *core;
1110+
1111+ list_for_each_entry(core, &bus->cores, list) {
1112+ if (core->id.id == coreid)
1113+ return core;
1114+ }
1115+ return NULL;
1116+}
1117+
1118+static void bcma_release_core_dev(struct device *dev)
1119+{
1120+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1121+ kfree(core);
1122+}
1123+
1124+static int bcma_register_cores(struct bcma_bus *bus)
1125+{
1126+ struct bcma_device *core;
1127+ int err, dev_id = 0;
1128+
1129+ list_for_each_entry(core, &bus->cores, list) {
1130+ /* We support that cores ourself */
1131+ switch (core->id.id) {
1132+ case BCMA_CORE_CHIPCOMMON:
1133+ case BCMA_CORE_PCI:
1134+ case BCMA_CORE_PCIE:
1135+ continue;
1136+ }
1137+
1138+ core->dev.release = bcma_release_core_dev;
1139+ core->dev.bus = &bcma_bus_type;
1140+ dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
1141+
1142+ switch (bus->hosttype) {
1143+ case BCMA_HOSTTYPE_PCI:
1144+ core->dev.parent = &bus->host_pci->dev;
1145+ core->dma_dev = &bus->host_pci->dev;
1146+ core->irq = bus->host_pci->irq;
1147+ break;
1148+ case BCMA_HOSTTYPE_NONE:
1149+ case BCMA_HOSTTYPE_SDIO:
1150+ break;
1151+ }
1152+
1153+ err = device_register(&core->dev);
1154+ if (err) {
1155+ pr_err("Could not register dev for core 0x%03X\n",
1156+ core->id.id);
1157+ continue;
1158+ }
1159+ core->dev_registered = true;
1160+ dev_id++;
1161+ }
1162+
1163+ return 0;
1164+}
1165+
1166+static void bcma_unregister_cores(struct bcma_bus *bus)
1167+{
1168+ struct bcma_device *core;
1169+
1170+ list_for_each_entry(core, &bus->cores, list) {
1171+ if (core->dev_registered)
1172+ device_unregister(&core->dev);
1173+ }
1174+}
1175+
1176+int bcma_bus_register(struct bcma_bus *bus)
1177+{
1178+ int err;
1179+ struct bcma_device *core;
1180+
1181+ /* Scan for devices (cores) */
1182+ err = bcma_bus_scan(bus);
1183+ if (err) {
1184+ pr_err("Failed to scan: %d\n", err);
1185+ return -1;
1186+ }
1187+
1188+ /* Init CC core */
1189+ core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1190+ if (core) {
1191+ bus->drv_cc.core = core;
1192+ bcma_core_chipcommon_init(&bus->drv_cc);
1193+ }
1194+
1195+ /* Init PCIE core */
1196+ core = bcma_find_core(bus, BCMA_CORE_PCIE);
1197+ if (core) {
1198+ bus->drv_pci.core = core;
1199+ bcma_core_pci_init(&bus->drv_pci);
1200+ }
1201+
1202+ /* Try to get SPROM */
1203+ err = bcma_sprom_get(bus);
1204+ if (err == -ENOENT) {
1205+ pr_err("No SPROM available\n");
1206+ } else if (err) {
1207+ pr_err("Failed to get SPROM: %d\n", err);
1208+ return -ENOENT;
1209+ }
1210+
1211+ /* Register found cores */
1212+ bcma_register_cores(bus);
1213+
1214+ pr_info("Bus registered\n");
1215+
1216+ return 0;
1217+}
1218+
1219+void bcma_bus_unregister(struct bcma_bus *bus)
1220+{
1221+ bcma_unregister_cores(bus);
1222+}
1223+
1224+int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
1225+{
1226+ drv->drv.name = drv->name;
1227+ drv->drv.bus = &bcma_bus_type;
1228+ drv->drv.owner = owner;
1229+
1230+ return driver_register(&drv->drv);
1231+}
1232+EXPORT_SYMBOL_GPL(__bcma_driver_register);
1233+
1234+void bcma_driver_unregister(struct bcma_driver *drv)
1235+{
1236+ driver_unregister(&drv->drv);
1237+}
1238+EXPORT_SYMBOL_GPL(bcma_driver_unregister);
1239+
1240+static int bcma_bus_match(struct device *dev, struct device_driver *drv)
1241+{
1242+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1243+ struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
1244+ const struct bcma_device_id *cid = &core->id;
1245+ const struct bcma_device_id *did;
1246+
1247+ for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
1248+ if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
1249+ (did->id == cid->id || did->id == BCMA_ANY_ID) &&
1250+ (did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
1251+ (did->class == cid->class || did->class == BCMA_ANY_CLASS))
1252+ return 1;
1253+ }
1254+ return 0;
1255+}
1256+
1257+static int bcma_device_probe(struct device *dev)
1258+{
1259+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1260+ struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
1261+ drv);
1262+ int err = 0;
1263+
1264+ if (adrv->probe)
1265+ err = adrv->probe(core);
1266+
1267+ return err;
1268+}
1269+
1270+static int bcma_device_remove(struct device *dev)
1271+{
1272+ struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1273+ struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
1274+ drv);
1275+
1276+ if (adrv->remove)
1277+ adrv->remove(core);
1278+
1279+ return 0;
1280+}
1281+
1282+static int __init bcma_modinit(void)
1283+{
1284+ int err;
1285+
1286+ err = bus_register(&bcma_bus_type);
1287+ if (err)
1288+ return err;
1289+
1290+#ifdef CONFIG_BCMA_HOST_PCI
1291+ err = bcma_host_pci_init();
1292+ if (err) {
1293+ pr_err("PCI host initialization failed\n");
1294+ err = 0;
1295+ }
1296+#endif
1297+
1298+ return err;
1299+}
1300+fs_initcall(bcma_modinit);
1301+
1302+static void __exit bcma_modexit(void)
1303+{
1304+#ifdef CONFIG_BCMA_HOST_PCI
1305+ bcma_host_pci_exit();
1306+#endif
1307+ bus_unregister(&bcma_bus_type);
1308+}
1309+module_exit(bcma_modexit)
1310--- /dev/null
1311+++ b/drivers/bcma/scan.c
1312@@ -0,0 +1,360 @@
1313+/*
1314+ * Broadcom specific AMBA
1315+ * Bus scanning
1316+ *
1317+ * Licensed under the GNU/GPL. See COPYING for details.
1318+ */
1319+
1320+#include "scan.h"
1321+#include "bcma_private.h"
1322+
1323+#include <linux/bcma/bcma.h>
1324+#include <linux/bcma/bcma_regs.h>
1325+#include <linux/pci.h>
1326+#include <linux/io.h>
1327+#include <linux/dma-mapping.h>
1328+#include <linux/slab.h>
1329+
1330+struct bcma_device_id_name {
1331+ u16 id;
1332+ const char *name;
1333+};
1334+struct bcma_device_id_name bcma_device_names[] = {
1335+ { BCMA_CORE_OOB_ROUTER, "OOB Router" },
1336+ { BCMA_CORE_INVALID, "Invalid" },
1337+ { BCMA_CORE_CHIPCOMMON, "ChipCommon" },
1338+ { BCMA_CORE_ILINE20, "ILine 20" },
1339+ { BCMA_CORE_SRAM, "SRAM" },
1340+ { BCMA_CORE_SDRAM, "SDRAM" },
1341+ { BCMA_CORE_PCI, "PCI" },
1342+ { BCMA_CORE_MIPS, "MIPS" },
1343+ { BCMA_CORE_ETHERNET, "Fast Ethernet" },
1344+ { BCMA_CORE_V90, "V90" },
1345+ { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
1346+ { BCMA_CORE_ADSL, "ADSL" },
1347+ { BCMA_CORE_ILINE100, "ILine 100" },
1348+ { BCMA_CORE_IPSEC, "IPSEC" },
1349+ { BCMA_CORE_UTOPIA, "UTOPIA" },
1350+ { BCMA_CORE_PCMCIA, "PCMCIA" },
1351+ { BCMA_CORE_INTERNAL_MEM, "Internal Memory" },
1352+ { BCMA_CORE_MEMC_SDRAM, "MEMC SDRAM" },
1353+ { BCMA_CORE_OFDM, "OFDM" },
1354+ { BCMA_CORE_EXTIF, "EXTIF" },
1355+ { BCMA_CORE_80211, "IEEE 802.11" },
1356+ { BCMA_CORE_PHY_A, "PHY A" },
1357+ { BCMA_CORE_PHY_B, "PHY B" },
1358+ { BCMA_CORE_PHY_G, "PHY G" },
1359+ { BCMA_CORE_MIPS_3302, "MIPS 3302" },
1360+ { BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
1361+ { BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
1362+ { BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
1363+ { BCMA_CORE_USB20_DEV, "USB 2.0 Device" },
1364+ { BCMA_CORE_SDIO_HOST, "SDIO Host" },
1365+ { BCMA_CORE_ROBOSWITCH, "Roboswitch" },
1366+ { BCMA_CORE_PARA_ATA, "PATA" },
1367+ { BCMA_CORE_SATA_XORDMA, "SATA XOR-DMA" },
1368+ { BCMA_CORE_ETHERNET_GBIT, "GBit Ethernet" },
1369+ { BCMA_CORE_PCIE, "PCIe" },
1370+ { BCMA_CORE_PHY_N, "PHY N" },
1371+ { BCMA_CORE_SRAM_CTL, "SRAM Controller" },
1372+ { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
1373+ { BCMA_CORE_ARM_1176, "ARM 1176" },
1374+ { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
1375+ { BCMA_CORE_PHY_LP, "PHY LP" },
1376+ { BCMA_CORE_PMU, "PMU" },
1377+ { BCMA_CORE_PHY_SSN, "PHY SSN" },
1378+ { BCMA_CORE_SDIO_DEV, "SDIO Device" },
1379+ { BCMA_CORE_ARM_CM3, "ARM CM3" },
1380+ { BCMA_CORE_PHY_HT, "PHY HT" },
1381+ { BCMA_CORE_MIPS_74K, "MIPS 74K" },
1382+ { BCMA_CORE_MAC_GBIT, "GBit MAC" },
1383+ { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
1384+ { BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
1385+ { BCMA_CORE_OCP_OCP_BRIDGE, "OCP to OCP Bridge" },
1386+ { BCMA_CORE_SHARED_COMMON, "Common Shared" },
1387+ { BCMA_CORE_OCP_AHB_BRIDGE, "OCP to AHB Bridge" },
1388+ { BCMA_CORE_SPI_HOST, "SPI Host" },
1389+ { BCMA_CORE_I2S, "I2S" },
1390+ { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
1391+ { BCMA_CORE_SHIM, "SHIM" },
1392+ { BCMA_CORE_DEFAULT, "Default" },
1393+};
1394+const char *bcma_device_name(struct bcma_device_id *id)
1395+{
1396+ int i;
1397+
1398+ if (id->manuf == BCMA_MANUF_BCM) {
1399+ for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
1400+ if (bcma_device_names[i].id == id->id)
1401+ return bcma_device_names[i].name;
1402+ }
1403+ }
1404+ return "UNKNOWN";
1405+}
1406+
1407+static u32 bcma_scan_read32(struct bcma_bus *bus, u8 current_coreidx,
1408+ u16 offset)
1409+{
1410+ return readl(bus->mmio + offset);
1411+}
1412+
1413+static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
1414+{
1415+ if (bus->hosttype == BCMA_HOSTTYPE_PCI)
1416+ pci_write_config_dword(bus->host_pci, BCMA_PCI_BAR0_WIN,
1417+ addr);
1418+}
1419+
1420+static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr)
1421+{
1422+ u32 ent = readl(*eromptr);
1423+ (*eromptr)++;
1424+ return ent;
1425+}
1426+
1427+static void bcma_erom_push_ent(u32 **eromptr)
1428+{
1429+ (*eromptr)--;
1430+}
1431+
1432+static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr)
1433+{
1434+ u32 ent = bcma_erom_get_ent(bus, eromptr);
1435+ if (!(ent & SCAN_ER_VALID))
1436+ return -ENOENT;
1437+ if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_CI)
1438+ return -ENOENT;
1439+ return ent;
1440+}
1441+
1442+static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr)
1443+{
1444+ u32 ent = bcma_erom_get_ent(bus, eromptr);
1445+ bcma_erom_push_ent(eromptr);
1446+ return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID));
1447+}
1448+
1449+static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr)
1450+{
1451+ u32 ent = bcma_erom_get_ent(bus, eromptr);
1452+ bcma_erom_push_ent(eromptr);
1453+ return (((ent & SCAN_ER_VALID)) &&
1454+ ((ent & SCAN_ER_TAGX) == SCAN_ER_TAG_ADDR) &&
1455+ ((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE));
1456+}
1457+
1458+static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr)
1459+{
1460+ u32 ent;
1461+ while (1) {
1462+ ent = bcma_erom_get_ent(bus, eromptr);
1463+ if ((ent & SCAN_ER_VALID) &&
1464+ ((ent & SCAN_ER_TAG) == SCAN_ER_TAG_CI))
1465+ break;
1466+ if (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID))
1467+ break;
1468+ }
1469+ bcma_erom_push_ent(eromptr);
1470+}
1471+
1472+static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr)
1473+{
1474+ u32 ent = bcma_erom_get_ent(bus, eromptr);
1475+ if (!(ent & SCAN_ER_VALID))
1476+ return -ENOENT;
1477+ if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_MP)
1478+ return -ENOENT;
1479+ return ent;
1480+}
1481+
1482+static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
1483+ u32 type, u8 port)
1484+{
1485+ u32 addrl, addrh, sizel, sizeh = 0;
1486+ u32 size;
1487+
1488+ u32 ent = bcma_erom_get_ent(bus, eromptr);
1489+ if ((!(ent & SCAN_ER_VALID)) ||
1490+ ((ent & SCAN_ER_TAGX) != SCAN_ER_TAG_ADDR) ||
1491+ ((ent & SCAN_ADDR_TYPE) != type) ||
1492+ (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
1493+ bcma_erom_push_ent(eromptr);
1494+ return -EINVAL;
1495+ }
1496+
1497+ addrl = ent & SCAN_ADDR_ADDR;
1498+ if (ent & SCAN_ADDR_AG32)
1499+ addrh = bcma_erom_get_ent(bus, eromptr);
1500+ else
1501+ addrh = 0;
1502+
1503+ if ((ent & SCAN_ADDR_SZ) == SCAN_ADDR_SZ_SZD) {
1504+ size = bcma_erom_get_ent(bus, eromptr);
1505+ sizel = size & SCAN_SIZE_SZ;
1506+ if (size & SCAN_SIZE_SG32)
1507+ sizeh = bcma_erom_get_ent(bus, eromptr);
1508+ } else
1509+ sizel = SCAN_ADDR_SZ_BASE <<
1510+ ((ent & SCAN_ADDR_SZ) >> SCAN_ADDR_SZ_SHIFT);
1511+
1512+ return addrl;
1513+}
1514+
1515+int bcma_bus_scan(struct bcma_bus *bus)
1516+{
1517+ u32 erombase;
1518+ u32 __iomem *eromptr, *eromend;
1519+
1520+ s32 cia, cib;
1521+ u8 ports[2], wrappers[2];
1522+
1523+ s32 tmp;
1524+ u8 i, j;
1525+
1526+ int err;
1527+
1528+ INIT_LIST_HEAD(&bus->cores);
1529+ bus->nr_cores = 0;
1530+
1531+ bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
1532+
1533+ tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
1534+ bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1535+ bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1536+ bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1537+
1538+ erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1539+ eromptr = bus->mmio;
1540+ eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1541+
1542+ bcma_scan_switch_core(bus, erombase);
1543+
1544+ while (eromptr < eromend) {
1545+ struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
1546+ if (!core)
1547+ return -ENOMEM;
1548+ INIT_LIST_HEAD(&core->list);
1549+ core->bus = bus;
1550+
1551+ /* get CIs */
1552+ cia = bcma_erom_get_ci(bus, &eromptr);
1553+ if (cia < 0) {
1554+ bcma_erom_push_ent(&eromptr);
1555+ if (bcma_erom_is_end(bus, &eromptr))
1556+ break;
1557+ err= -EILSEQ;
1558+ goto out;
1559+ }
1560+ cib = bcma_erom_get_ci(bus, &eromptr);
1561+ if (cib < 0) {
1562+ err= -EILSEQ;
1563+ goto out;
1564+ }
1565+
1566+ /* parse CIs */
1567+ core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1568+ core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1569+ core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1570+ ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1571+ ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1572+ wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1573+ wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1574+ core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1575+
1576+ if (((core->id.manuf == BCMA_MANUF_ARM) &&
1577+ (core->id.id == 0xFFF)) ||
1578+ (ports[1] == 0)) {
1579+ bcma_erom_skip_component(bus, &eromptr);
1580+ continue;
1581+ }
1582+
1583+ /* check if component is a core at all */
1584+ if (wrappers[0] + wrappers[1] == 0) {
1585+ /* we could save addrl of the router
1586+ if (cid == BCMA_CORE_OOB_ROUTER)
1587+ */
1588+ bcma_erom_skip_component(bus, &eromptr);
1589+ continue;
1590+ }
1591+
1592+ if (bcma_erom_is_bridge(bus, &eromptr)) {
1593+ bcma_erom_skip_component(bus, &eromptr);
1594+ continue;
1595+ }
1596+
1597+ /* get & parse master ports */
1598+ for (i = 0; i < ports[0]; i++) {
1599+ u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
1600+ if (mst_port_d < 0) {
1601+ err= -EILSEQ;
1602+ goto out;
1603+ }
1604+ }
1605+
1606+ /* get & parse slave ports */
1607+ for (i = 0; i < ports[1]; i++) {
1608+ for (j = 0; ; j++) {
1609+ tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1610+ SCAN_ADDR_TYPE_SLAVE, i);
1611+ if (tmp < 0) {
1612+ /* no more entries for port _i_ */
1613+ /* pr_debug("erom: slave port %d "
1614+ * "has %d descriptors\n", i, j); */
1615+ break;
1616+ } else {
1617+ if (i == 0 && j == 0)
1618+ core->addr = tmp;
1619+ }
1620+ }
1621+ }
1622+
1623+ /* get & parse master wrappers */
1624+ for (i = 0; i < wrappers[0]; i++) {
1625+ for (j = 0; ; j++) {
1626+ tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1627+ SCAN_ADDR_TYPE_MWRAP, i);
1628+ if (tmp < 0) {
1629+ /* no more entries for port _i_ */
1630+ /* pr_debug("erom: master wrapper %d "
1631+ * "has %d descriptors\n", i, j); */
1632+ break;
1633+ } else {
1634+ if (i == 0 && j == 0)
1635+ core->wrap = tmp;
1636+ }
1637+ }
1638+ }
1639+
1640+ /* get & parse slave wrappers */
1641+ for (i = 0; i < wrappers[1]; i++) {
1642+ u8 hack = (ports[1] == 1) ? 0 : 1;
1643+ for (j = 0; ; j++) {
1644+ tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1645+ SCAN_ADDR_TYPE_SWRAP, i + hack);
1646+ if (tmp < 0) {
1647+ /* no more entries for port _i_ */
1648+ /* pr_debug("erom: master wrapper %d "
1649+ * has %d descriptors\n", i, j); */
1650+ break;
1651+ } else {
1652+ if (wrappers[0] == 0 && !i && !j)
1653+ core->wrap = tmp;
1654+ }
1655+ }
1656+ }
1657+
1658+ pr_info("Core %d found: %s "
1659+ "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1660+ bus->nr_cores, bcma_device_name(&core->id),
1661+ core->id.manuf, core->id.id, core->id.rev,
1662+ core->id.class);
1663+
1664+ core->core_index = bus->nr_cores++;
1665+ list_add(&core->list, &bus->cores);
1666+ continue;
1667+out:
1668+ return err;
1669+ }
1670+
1671+ return 0;
1672+}
1673--- /dev/null
1674+++ b/drivers/bcma/scan.h
1675@@ -0,0 +1,56 @@
1676+#ifndef BCMA_SCAN_H_
1677+#define BCMA_SCAN_H_
1678+
1679+#define BCMA_ADDR_BASE 0x18000000
1680+#define BCMA_WRAP_BASE 0x18100000
1681+
1682+#define SCAN_ER_VALID 0x00000001
1683+#define SCAN_ER_TAGX 0x00000006 /* we have to ignore 0x8 bit when checking tag for SCAN_ER_TAG_ADDR */
1684+#define SCAN_ER_TAG 0x0000000E
1685+#define SCAN_ER_TAG_CI 0x00000000
1686+#define SCAN_ER_TAG_MP 0x00000002
1687+#define SCAN_ER_TAG_ADDR 0x00000004
1688+#define SCAN_ER_TAG_END 0x0000000E
1689+#define SCAN_ER_BAD 0xFFFFFFFF
1690+
1691+#define SCAN_CIA_CLASS 0x000000F0
1692+#define SCAN_CIA_CLASS_SHIFT 4
1693+#define SCAN_CIA_ID 0x000FFF00
1694+#define SCAN_CIA_ID_SHIFT 8
1695+#define SCAN_CIA_MANUF 0xFFF00000
1696+#define SCAN_CIA_MANUF_SHIFT 20
1697+
1698+#define SCAN_CIB_NMP 0x000001F0
1699+#define SCAN_CIB_NMP_SHIFT 4
1700+#define SCAN_CIB_NSP 0x00003E00
1701+#define SCAN_CIB_NSP_SHIFT 9
1702+#define SCAN_CIB_NMW 0x0007C000
1703+#define SCAN_CIB_NMW_SHIFT 14
1704+#define SCAN_CIB_NSW 0x00F80000
1705+#define SCAN_CIB_NSW_SHIFT 17
1706+#define SCAN_CIB_REV 0xFF000000
1707+#define SCAN_CIB_REV_SHIFT 24
1708+
1709+#define SCAN_ADDR_AG32 0x00000008
1710+#define SCAN_ADDR_SZ 0x00000030
1711+#define SCAN_ADDR_SZ_SHIFT 4
1712+#define SCAN_ADDR_SZ_4K 0x00000000
1713+#define SCAN_ADDR_SZ_8K 0x00000010
1714+#define SCAN_ADDR_SZ_16K 0x00000020
1715+#define SCAN_ADDR_SZ_SZD 0x00000030
1716+#define SCAN_ADDR_TYPE 0x000000C0
1717+#define SCAN_ADDR_TYPE_SLAVE 0x00000000
1718+#define SCAN_ADDR_TYPE_BRIDGE 0x00000040
1719+#define SCAN_ADDR_TYPE_SWRAP 0x00000080
1720+#define SCAN_ADDR_TYPE_MWRAP 0x000000C0
1721+#define SCAN_ADDR_PORT 0x00000F00
1722+#define SCAN_ADDR_PORT_SHIFT 8
1723+#define SCAN_ADDR_ADDR 0xFFFFF000
1724+
1725+#define SCAN_ADDR_SZ_BASE 0x00001000 /* 4KB */
1726+
1727+#define SCAN_SIZE_SZ_ALIGN 0x00000FFF
1728+#define SCAN_SIZE_SZ 0xFFFFF000
1729+#define SCAN_SIZE_SG32 0x00000008
1730+
1731+#endif /* BCMA_SCAN_H_ */
1732--- /dev/null
1733+++ b/include/linux/bcma/bcma.h
1734@@ -0,0 +1,271 @@
1735+#ifndef LINUX_BCMA_H_
1736+#define LINUX_BCMA_H_
1737+
1738+#include <linux/pci.h>
1739+#include <linux/mod_devicetable.h>
1740+
1741+#include <linux/bcma/bcma_driver_chipcommon.h>
1742+#include <linux/bcma/bcma_driver_pci.h>
1743+#include <linux/ssb/ssb.h> /* SPROM sharing */
1744+
1745+#include "bcma_regs.h"
1746+
1747+struct bcma_device;
1748+struct bcma_bus;
1749+
1750+enum bcma_hosttype {
1751+ BCMA_HOSTTYPE_NONE,
1752+ BCMA_HOSTTYPE_PCI,
1753+ BCMA_HOSTTYPE_SDIO,
1754+};
1755+
1756+struct bcma_chipinfo {
1757+ u16 id;
1758+ u8 rev;
1759+ u8 pkg;
1760+};
1761+
1762+enum bcma_clkmode {
1763+ BCMA_CLKMODE_FAST,
1764+ BCMA_CLKMODE_DYNAMIC,
1765+};
1766+
1767+struct bcma_host_ops {
1768+ u8 (*read8)(struct bcma_device *core, u16 offset);
1769+ u16 (*read16)(struct bcma_device *core, u16 offset);
1770+ u32 (*read32)(struct bcma_device *core, u16 offset);
1771+ void (*write8)(struct bcma_device *core, u16 offset, u8 value);
1772+ void (*write16)(struct bcma_device *core, u16 offset, u16 value);
1773+ void (*write32)(struct bcma_device *core, u16 offset, u32 value);
1774+#ifdef CONFIG_BCMA_BLOCKIO
1775+ void (*block_read)(struct bcma_device *core, void *buffer,
1776+ size_t count, u16 offset, u8 reg_width);
1777+ void (*block_write)(struct bcma_device *core, const void *buffer,
1778+ size_t count, u16 offset, u8 reg_width);
1779+#endif
1780+ /* Agent ops */
1781+ u32 (*aread32)(struct bcma_device *core, u16 offset);
1782+ void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
1783+};
1784+
1785+/* Core manufacturers */
1786+#define BCMA_MANUF_ARM 0x43B
1787+#define BCMA_MANUF_MIPS 0x4A7
1788+#define BCMA_MANUF_BCM 0x4BF
1789+
1790+/* Core class values. */
1791+#define BCMA_CL_SIM 0x0
1792+#define BCMA_CL_EROM 0x1
1793+#define BCMA_CL_CORESIGHT 0x9
1794+#define BCMA_CL_VERIF 0xB
1795+#define BCMA_CL_OPTIMO 0xD
1796+#define BCMA_CL_GEN 0xE
1797+#define BCMA_CL_PRIMECELL 0xF
1798+
1799+/* Core-ID values. */
1800+#define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */
1801+#define BCMA_CORE_INVALID 0x700
1802+#define BCMA_CORE_CHIPCOMMON 0x800
1803+#define BCMA_CORE_ILINE20 0x801
1804+#define BCMA_CORE_SRAM 0x802
1805+#define BCMA_CORE_SDRAM 0x803
1806+#define BCMA_CORE_PCI 0x804
1807+#define BCMA_CORE_MIPS 0x805
1808+#define BCMA_CORE_ETHERNET 0x806
1809+#define BCMA_CORE_V90 0x807
1810+#define BCMA_CORE_USB11_HOSTDEV 0x808
1811+#define BCMA_CORE_ADSL 0x809
1812+#define BCMA_CORE_ILINE100 0x80A
1813+#define BCMA_CORE_IPSEC 0x80B
1814+#define BCMA_CORE_UTOPIA 0x80C
1815+#define BCMA_CORE_PCMCIA 0x80D
1816+#define BCMA_CORE_INTERNAL_MEM 0x80E
1817+#define BCMA_CORE_MEMC_SDRAM 0x80F
1818+#define BCMA_CORE_OFDM 0x810
1819+#define BCMA_CORE_EXTIF 0x811
1820+#define BCMA_CORE_80211 0x812
1821+#define BCMA_CORE_PHY_A 0x813
1822+#define BCMA_CORE_PHY_B 0x814
1823+#define BCMA_CORE_PHY_G 0x815
1824+#define BCMA_CORE_MIPS_3302 0x816
1825+#define BCMA_CORE_USB11_HOST 0x817
1826+#define BCMA_CORE_USB11_DEV 0x818
1827+#define BCMA_CORE_USB20_HOST 0x819
1828+#define BCMA_CORE_USB20_DEV 0x81A
1829+#define BCMA_CORE_SDIO_HOST 0x81B
1830+#define BCMA_CORE_ROBOSWITCH 0x81C
1831+#define BCMA_CORE_PARA_ATA 0x81D
1832+#define BCMA_CORE_SATA_XORDMA 0x81E
1833+#define BCMA_CORE_ETHERNET_GBIT 0x81F
1834+#define BCMA_CORE_PCIE 0x820
1835+#define BCMA_CORE_PHY_N 0x821
1836+#define BCMA_CORE_SRAM_CTL 0x822
1837+#define BCMA_CORE_MINI_MACPHY 0x823
1838+#define BCMA_CORE_ARM_1176 0x824
1839+#define BCMA_CORE_ARM_7TDMI 0x825
1840+#define BCMA_CORE_PHY_LP 0x826
1841+#define BCMA_CORE_PMU 0x827
1842+#define BCMA_CORE_PHY_SSN 0x828
1843+#define BCMA_CORE_SDIO_DEV 0x829
1844+#define BCMA_CORE_ARM_CM3 0x82A
1845+#define BCMA_CORE_PHY_HT 0x82B
1846+#define BCMA_CORE_MIPS_74K 0x82C
1847+#define BCMA_CORE_MAC_GBIT 0x82D
1848+#define BCMA_CORE_DDR12_MEM_CTL 0x82E
1849+#define BCMA_CORE_PCIE_RC 0x82F /* PCIe Root Complex */
1850+#define BCMA_CORE_OCP_OCP_BRIDGE 0x830
1851+#define BCMA_CORE_SHARED_COMMON 0x831
1852+#define BCMA_CORE_OCP_AHB_BRIDGE 0x832
1853+#define BCMA_CORE_SPI_HOST 0x833
1854+#define BCMA_CORE_I2S 0x834
1855+#define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */
1856+#define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */
1857+#define BCMA_CORE_DEFAULT 0xFFF
1858+
1859+#define BCMA_MAX_NR_CORES 16
1860+
1861+struct bcma_device {
1862+ struct bcma_bus *bus;
1863+ struct bcma_device_id id;
1864+
1865+ struct device dev;
1866+ struct device *dma_dev;
1867+ unsigned int irq;
1868+ bool dev_registered;
1869+
1870+ u8 core_index;
1871+
1872+ u32 addr;
1873+ u32 wrap;
1874+
1875+ void *drvdata;
1876+ struct list_head list;
1877+};
1878+
1879+static inline void *bcma_get_drvdata(struct bcma_device *core)
1880+{
1881+ return core->drvdata;
1882+}
1883+static inline void bcma_set_drvdata(struct bcma_device *core, void *drvdata)
1884+{
1885+ core->drvdata = drvdata;
1886+}
1887+
1888+struct bcma_driver {
1889+ const char *name;
1890+ const struct bcma_device_id *id_table;
1891+
1892+ int (*probe)(struct bcma_device *dev);
1893+ void (*remove)(struct bcma_device *dev);
1894+ int (*suspend)(struct bcma_device *dev, pm_message_t state);
1895+ int (*resume)(struct bcma_device *dev);
1896+ void (*shutdown)(struct bcma_device *dev);
1897+
1898+ struct device_driver drv;
1899+};
1900+extern
1901+int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
1902+static inline int bcma_driver_register(struct bcma_driver *drv)
1903+{
1904+ return __bcma_driver_register(drv, THIS_MODULE);
1905+}
1906+extern void bcma_driver_unregister(struct bcma_driver *drv);
1907+
1908+struct bcma_bus {
1909+ /* The MMIO area. */
1910+ void __iomem *mmio;
1911+
1912+ const struct bcma_host_ops *ops;
1913+
1914+ enum bcma_hosttype hosttype;
1915+ union {
1916+ /* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */
1917+ struct pci_dev *host_pci;
1918+ /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
1919+ struct sdio_func *host_sdio;
1920+ };
1921+
1922+ struct bcma_chipinfo chipinfo;
1923+
1924+ struct bcma_device *mapped_core;
1925+ struct list_head cores;
1926+ u8 nr_cores;
1927+
1928+ struct bcma_drv_cc drv_cc;
1929+ struct bcma_drv_pci drv_pci;
1930+
1931+ /* We decided to share SPROM struct with SSB as long as we do not need
1932+ * any hacks for BCMA. This simplifies drivers code. */
1933+ struct ssb_sprom sprom;
1934+};
1935+
1936+extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
1937+{
1938+ return core->bus->ops->read8(core, offset);
1939+}
1940+extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
1941+{
1942+ return core->bus->ops->read16(core, offset);
1943+}
1944+extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
1945+{
1946+ return core->bus->ops->read32(core, offset);
1947+}
1948+extern inline
1949+void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
1950+{
1951+ core->bus->ops->write8(core, offset, value);
1952+}
1953+extern inline
1954+void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
1955+{
1956+ core->bus->ops->write16(core, offset, value);
1957+}
1958+extern inline
1959+void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
1960+{
1961+ core->bus->ops->write32(core, offset, value);
1962+}
1963+#ifdef CONFIG_BCMA_BLOCKIO
1964+extern inline void bcma_block_read(struct bcma_device *core, void *buffer,
1965+ size_t count, u16 offset, u8 reg_width)
1966+{
1967+ core->bus->ops->block_read(core, buffer, count, offset, reg_width);
1968+}
1969+extern inline void bcma_block_write(struct bcma_device *core, const void *buffer,
1970+ size_t count, u16 offset, u8 reg_width)
1971+{
1972+ core->bus->ops->block_write(core, buffer, count, offset, reg_width);
1973+}
1974+#endif
1975+extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
1976+{
1977+ return core->bus->ops->aread32(core, offset);
1978+}
1979+extern inline
1980+void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
1981+{
1982+ core->bus->ops->awrite32(core, offset, value);
1983+}
1984+
1985+#define bcma_mask32(cc, offset, mask) \
1986+ bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
1987+#define bcma_set32(cc, offset, set) \
1988+ bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
1989+#define bcma_maskset32(cc, offset, mask, set) \
1990+ bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
1991+
1992+extern bool bcma_core_is_enabled(struct bcma_device *core);
1993+extern void bcma_core_disable(struct bcma_device *core, u32 flags);
1994+extern int bcma_core_enable(struct bcma_device *core, u32 flags);
1995+extern void bcma_core_set_clockmode(struct bcma_device *core,
1996+ enum bcma_clkmode clkmode);
1997+extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
1998+ bool on);
1999+#define BCMA_DMA_TRANSLATION_MASK 0xC0000000
2000+#define BCMA_DMA_TRANSLATION_NONE 0x00000000
2001+#define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */
2002+#define BCMA_DMA_TRANSLATION_DMA64_CMT 0x80000000 /* Client Mode Translation for 64-bit DMA */
2003+extern u32 bcma_core_dma_translation(struct bcma_device *core);
2004+
2005+#endif /* LINUX_BCMA_H_ */
2006--- /dev/null
2007+++ b/include/linux/bcma/bcma_driver_chipcommon.h
2008@@ -0,0 +1,296 @@
2009+#ifndef LINUX_BCMA_DRIVER_CC_H_
2010+#define LINUX_BCMA_DRIVER_CC_H_
2011+
2012+/** ChipCommon core registers. **/
2013+#define BCMA_CC_ID 0x0000
2014+#define BCMA_CC_ID_ID 0x0000FFFF
2015+#define BCMA_CC_ID_ID_SHIFT 0
2016+#define BCMA_CC_ID_REV 0x000F0000
2017+#define BCMA_CC_ID_REV_SHIFT 16
2018+#define BCMA_CC_ID_PKG 0x00F00000
2019+#define BCMA_CC_ID_PKG_SHIFT 20
2020+#define BCMA_CC_ID_NRCORES 0x0F000000
2021+#define BCMA_CC_ID_NRCORES_SHIFT 24
2022+#define BCMA_CC_ID_TYPE 0xF0000000
2023+#define BCMA_CC_ID_TYPE_SHIFT 28
2024+#define BCMA_CC_CAP 0x0004 /* Capabilities */
2025+#define BCMA_CC_CAP_NRUART 0x00000003 /* # of UARTs */
2026+#define BCMA_CC_CAP_MIPSEB 0x00000004 /* MIPS in BigEndian Mode */
2027+#define BCMA_CC_CAP_UARTCLK 0x00000018 /* UART clock select */
2028+#define BCMA_CC_CAP_UARTCLK_INT 0x00000008 /* UARTs are driven by internal divided clock */
2029+#define BCMA_CC_CAP_UARTGPIO 0x00000020 /* UARTs on GPIO 15-12 */
2030+#define BCMA_CC_CAP_EXTBUS 0x000000C0 /* External buses present */
2031+#define BCMA_CC_CAP_FLASHT 0x00000700 /* Flash Type */
2032+#define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
2033+#define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
2034+#define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
2035+#define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
2036+#define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
2037+#define BCMA_PLLTYPE_NONE 0x00000000
2038+#define BCMA_PLLTYPE_1 0x00010000 /* 48Mhz base, 3 dividers */
2039+#define BCMA_PLLTYPE_2 0x00020000 /* 48Mhz, 4 dividers */
2040+#define BCMA_PLLTYPE_3 0x00030000 /* 25Mhz, 2 dividers */
2041+#define BCMA_PLLTYPE_4 0x00008000 /* 48Mhz, 4 dividers */
2042+#define BCMA_PLLTYPE_5 0x00018000 /* 25Mhz, 4 dividers */
2043+#define BCMA_PLLTYPE_6 0x00028000 /* 100/200 or 120/240 only */
2044+#define BCMA_PLLTYPE_7 0x00038000 /* 25Mhz, 4 dividers */
2045+#define BCMA_CC_CAP_PCTL 0x00040000 /* Power Control */
2046+#define BCMA_CC_CAP_OTPS 0x00380000 /* OTP size */
2047+#define BCMA_CC_CAP_OTPS_SHIFT 19
2048+#define BCMA_CC_CAP_OTPS_BASE 5
2049+#define BCMA_CC_CAP_JTAGM 0x00400000 /* JTAG master present */
2050+#define BCMA_CC_CAP_BROM 0x00800000 /* Internal boot ROM active */
2051+#define BCMA_CC_CAP_64BIT 0x08000000 /* 64-bit Backplane */
2052+#define BCMA_CC_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */
2053+#define BCMA_CC_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */
2054+#define BCMA_CC_CAP_SPROM 0x40000000 /* SPROM present */
2055+#define BCMA_CC_CORECTL 0x0008
2056+#define BCMA_CC_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
2057+#define BCMA_CC_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
2058+#define BCMA_CC_CORECTL_UARTCLKEN 0x00000008 /* UART clock enable (rev >= 21) */
2059+#define BCMA_CC_BIST 0x000C
2060+#define BCMA_CC_OTPS 0x0010 /* OTP status */
2061+#define BCMA_CC_OTPS_PROGFAIL 0x80000000
2062+#define BCMA_CC_OTPS_PROTECT 0x00000007
2063+#define BCMA_CC_OTPS_HW_PROTECT 0x00000001
2064+#define BCMA_CC_OTPS_SW_PROTECT 0x00000002
2065+#define BCMA_CC_OTPS_CID_PROTECT 0x00000004
2066+#define BCMA_CC_OTPC 0x0014 /* OTP control */
2067+#define BCMA_CC_OTPC_RECWAIT 0xFF000000
2068+#define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00
2069+#define BCMA_CC_OTPC_PRW_SHIFT 8
2070+#define BCMA_CC_OTPC_MAXFAIL 0x00000038
2071+#define BCMA_CC_OTPC_VSEL 0x00000006
2072+#define BCMA_CC_OTPC_SELVL 0x00000001
2073+#define BCMA_CC_OTPP 0x0018 /* OTP prog */
2074+#define BCMA_CC_OTPP_COL 0x000000FF
2075+#define BCMA_CC_OTPP_ROW 0x0000FF00
2076+#define BCMA_CC_OTPP_ROW_SHIFT 8
2077+#define BCMA_CC_OTPP_READERR 0x10000000
2078+#define BCMA_CC_OTPP_VALUE 0x20000000
2079+#define BCMA_CC_OTPP_READ 0x40000000
2080+#define BCMA_CC_OTPP_START 0x80000000
2081+#define BCMA_CC_OTPP_BUSY 0x80000000
2082+#define BCMA_CC_IRQSTAT 0x0020
2083+#define BCMA_CC_IRQMASK 0x0024
2084+#define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */
2085+#define BCMA_CC_IRQ_EXT 0x00000002 /* ro: ext intr pin (corerev >= 3) */
2086+#define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */
2087+#define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */
2088+#define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */
2089+#define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */
2090+#define BCMA_CC_JCMD_START 0x80000000
2091+#define BCMA_CC_JCMD_BUSY 0x80000000
2092+#define BCMA_CC_JCMD_PAUSE 0x40000000
2093+#define BCMA_CC_JCMD0_ACC_MASK 0x0000F000
2094+#define BCMA_CC_JCMD0_ACC_IRDR 0x00000000
2095+#define BCMA_CC_JCMD0_ACC_DR 0x00001000
2096+#define BCMA_CC_JCMD0_ACC_IR 0x00002000
2097+#define BCMA_CC_JCMD0_ACC_RESET 0x00003000
2098+#define BCMA_CC_JCMD0_ACC_IRPDR 0x00004000
2099+#define BCMA_CC_JCMD0_ACC_PDR 0x00005000
2100+#define BCMA_CC_JCMD0_IRW_MASK 0x00000F00
2101+#define BCMA_CC_JCMD_ACC_MASK 0x000F0000 /* Changes for corerev 11 */
2102+#define BCMA_CC_JCMD_ACC_IRDR 0x00000000
2103+#define BCMA_CC_JCMD_ACC_DR 0x00010000
2104+#define BCMA_CC_JCMD_ACC_IR 0x00020000
2105+#define BCMA_CC_JCMD_ACC_RESET 0x00030000
2106+#define BCMA_CC_JCMD_ACC_IRPDR 0x00040000
2107+#define BCMA_CC_JCMD_ACC_PDR 0x00050000
2108+#define BCMA_CC_JCMD_IRW_MASK 0x00001F00
2109+#define BCMA_CC_JCMD_IRW_SHIFT 8
2110+#define BCMA_CC_JCMD_DRW_MASK 0x0000003F
2111+#define BCMA_CC_JIR 0x0034 /* Rev >= 10 only */
2112+#define BCMA_CC_JDR 0x0038 /* Rev >= 10 only */
2113+#define BCMA_CC_JCTL 0x003C /* Rev >= 10 only */
2114+#define BCMA_CC_JCTL_FORCE_CLK 4 /* Force clock */
2115+#define BCMA_CC_JCTL_EXT_EN 2 /* Enable external targets */
2116+#define BCMA_CC_JCTL_EN 1 /* Enable Jtag master */
2117+#define BCMA_CC_FLASHCTL 0x0040
2118+#define BCMA_CC_FLASHCTL_START 0x80000000
2119+#define BCMA_CC_FLASHCTL_BUSY BCMA_CC_FLASHCTL_START
2120+#define BCMA_CC_FLASHADDR 0x0044
2121+#define BCMA_CC_FLASHDATA 0x0048
2122+#define BCMA_CC_BCAST_ADDR 0x0050
2123+#define BCMA_CC_BCAST_DATA 0x0054
2124+#define BCMA_CC_GPIOPULLUP 0x0058 /* Rev >= 20 only */
2125+#define BCMA_CC_GPIOPULLDOWN 0x005C /* Rev >= 20 only */
2126+#define BCMA_CC_GPIOIN 0x0060
2127+#define BCMA_CC_GPIOOUT 0x0064
2128+#define BCMA_CC_GPIOOUTEN 0x0068
2129+#define BCMA_CC_GPIOCTL 0x006C
2130+#define BCMA_CC_GPIOPOL 0x0070
2131+#define BCMA_CC_GPIOIRQ 0x0074
2132+#define BCMA_CC_WATCHDOG 0x0080
2133+#define BCMA_CC_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */
2134+#define BCMA_CC_GPIOTIMER_OFFTIME 0x0000FFFF
2135+#define BCMA_CC_GPIOTIMER_OFFTIME_SHIFT 0
2136+#define BCMA_CC_GPIOTIMER_ONTIME 0xFFFF0000
2137+#define BCMA_CC_GPIOTIMER_ONTIME_SHIFT 16
2138+#define BCMA_CC_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */
2139+#define BCMA_CC_CLOCK_N 0x0090
2140+#define BCMA_CC_CLOCK_SB 0x0094
2141+#define BCMA_CC_CLOCK_PCI 0x0098
2142+#define BCMA_CC_CLOCK_M2 0x009C
2143+#define BCMA_CC_CLOCK_MIPS 0x00A0
2144+#define BCMA_CC_CLKDIV 0x00A4 /* Rev >= 3 only */
2145+#define BCMA_CC_CLKDIV_SFLASH 0x0F000000
2146+#define BCMA_CC_CLKDIV_SFLASH_SHIFT 24
2147+#define BCMA_CC_CLKDIV_OTP 0x000F0000
2148+#define BCMA_CC_CLKDIV_OTP_SHIFT 16
2149+#define BCMA_CC_CLKDIV_JTAG 0x00000F00
2150+#define BCMA_CC_CLKDIV_JTAG_SHIFT 8
2151+#define BCMA_CC_CLKDIV_UART 0x000000FF
2152+#define BCMA_CC_CAP_EXT 0x00AC /* Capabilities */
2153+#define BCMA_CC_PLLONDELAY 0x00B0 /* Rev >= 4 only */
2154+#define BCMA_CC_FREFSELDELAY 0x00B4 /* Rev >= 4 only */
2155+#define BCMA_CC_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */
2156+#define BCMA_CC_SLOWCLKCTL_SRC 0x00000007 /* slow clock source mask */
2157+#define BCMA_CC_SLOWCLKCTL_SRC_LPO 0x00000000 /* source of slow clock is LPO */
2158+#define BCMA_CC_SLOWCLKCTL_SRC_XTAL 0x00000001 /* source of slow clock is crystal */
2159+#define BCMA_CC_SLOECLKCTL_SRC_PCI 0x00000002 /* source of slow clock is PCI */
2160+#define BCMA_CC_SLOWCLKCTL_LPOFREQ 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
2161+#define BCMA_CC_SLOWCLKCTL_LPOPD 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
2162+#define BCMA_CC_SLOWCLKCTL_FSLOW 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
2163+#define BCMA_CC_SLOWCLKCTL_IPLL 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
2164+#define BCMA_CC_SLOWCLKCTL_ENXTAL 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
2165+#define BCMA_CC_SLOWCLKCTL_XTALPU 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
2166+#define BCMA_CC_SLOWCLKCTL_CLKDIV 0xFFFF0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
2167+#define BCMA_CC_SLOWCLKCTL_CLKDIV_SHIFT 16
2168+#define BCMA_CC_SYSCLKCTL 0x00C0 /* Rev >= 3 only */
2169+#define BCMA_CC_SYSCLKCTL_IDLPEN 0x00000001 /* ILPen: Enable Idle Low Power */
2170+#define BCMA_CC_SYSCLKCTL_ALPEN 0x00000002 /* ALPen: Enable Active Low Power */
2171+#define BCMA_CC_SYSCLKCTL_PLLEN 0x00000004 /* ForcePLLOn */
2172+#define BCMA_CC_SYSCLKCTL_FORCEALP 0x00000008 /* Force ALP (or HT if ALPen is not set */
2173+#define BCMA_CC_SYSCLKCTL_FORCEHT 0x00000010 /* Force HT */
2174+#define BCMA_CC_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */
2175+#define BCMA_CC_SYSCLKCTL_CLKDIV_SHIFT 16
2176+#define BCMA_CC_CLKSTSTR 0x00C4 /* Rev >= 3 only */
2177+#define BCMA_CC_EROM 0x00FC
2178+#define BCMA_CC_PCMCIA_CFG 0x0100
2179+#define BCMA_CC_PCMCIA_MEMWAIT 0x0104
2180+#define BCMA_CC_PCMCIA_ATTRWAIT 0x0108
2181+#define BCMA_CC_PCMCIA_IOWAIT 0x010C
2182+#define BCMA_CC_IDE_CFG 0x0110
2183+#define BCMA_CC_IDE_MEMWAIT 0x0114
2184+#define BCMA_CC_IDE_ATTRWAIT 0x0118
2185+#define BCMA_CC_IDE_IOWAIT 0x011C
2186+#define BCMA_CC_PROG_CFG 0x0120
2187+#define BCMA_CC_PROG_WAITCNT 0x0124
2188+#define BCMA_CC_FLASH_CFG 0x0128
2189+#define BCMA_CC_FLASH_WAITCNT 0x012C
2190+/* 0x1E0 is defined as shared BCMA_CLKCTLST */
2191+#define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
2192+#define BCMA_CC_UART0_DATA 0x0300
2193+#define BCMA_CC_UART0_IMR 0x0304
2194+#define BCMA_CC_UART0_FCR 0x0308
2195+#define BCMA_CC_UART0_LCR 0x030C
2196+#define BCMA_CC_UART0_MCR 0x0310
2197+#define BCMA_CC_UART0_LSR 0x0314
2198+#define BCMA_CC_UART0_MSR 0x0318
2199+#define BCMA_CC_UART0_SCRATCH 0x031C
2200+#define BCMA_CC_UART1_DATA 0x0400
2201+#define BCMA_CC_UART1_IMR 0x0404
2202+#define BCMA_CC_UART1_FCR 0x0408
2203+#define BCMA_CC_UART1_LCR 0x040C
2204+#define BCMA_CC_UART1_MCR 0x0410
2205+#define BCMA_CC_UART1_LSR 0x0414
2206+#define BCMA_CC_UART1_MSR 0x0418
2207+#define BCMA_CC_UART1_SCRATCH 0x041C
2208+/* PMU registers (rev >= 20) */
2209+#define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
2210+#define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
2211+#define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
2212+#define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
2213+#define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
2214+#define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
2215+#define BCMA_CC_PMU_CTL_XTALFREQ 0x0000007C /* Crystal freq */
2216+#define BCMA_CC_PMU_CTL_XTALFREQ_SHIFT 2
2217+#define BCMA_CC_PMU_CTL_ILPDIVEN 0x00000002 /* ILP div enable */
2218+#define BCMA_CC_PMU_CTL_LPOSEL 0x00000001 /* LPO sel */
2219+#define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */
2220+#define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */
2221+#define BCMA_CC_PMU_STAT 0x0608 /* PMU status */
2222+#define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */
2223+#define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */
2224+#define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */
2225+#define BCMA_CC_PMU_STAT_HAVEHT 0x00000004 /* HT available */
2226+#define BCMA_CC_PMU_STAT_RESINIT 0x00000003 /* Res init */
2227+#define BCMA_CC_PMU_RES_STAT 0x060C /* PMU res status */
2228+#define BCMA_CC_PMU_RES_PEND 0x0610 /* PMU res pending */
2229+#define BCMA_CC_PMU_TIMER 0x0614 /* PMU timer */
2230+#define BCMA_CC_PMU_MINRES_MSK 0x0618 /* PMU min res mask */
2231+#define BCMA_CC_PMU_MAXRES_MSK 0x061C /* PMU max res mask */
2232+#define BCMA_CC_PMU_RES_TABSEL 0x0620 /* PMU res table sel */
2233+#define BCMA_CC_PMU_RES_DEPMSK 0x0624 /* PMU res dep mask */
2234+#define BCMA_CC_PMU_RES_UPDNTM 0x0628 /* PMU res updown timer */
2235+#define BCMA_CC_PMU_RES_TIMER 0x062C /* PMU res timer */
2236+#define BCMA_CC_PMU_CLKSTRETCH 0x0630 /* PMU clockstretch */
2237+#define BCMA_CC_PMU_WATCHDOG 0x0634 /* PMU watchdog */
2238+#define BCMA_CC_PMU_RES_REQTS 0x0640 /* PMU res req timer sel */
2239+#define BCMA_CC_PMU_RES_REQT 0x0644 /* PMU res req timer */
2240+#define BCMA_CC_PMU_RES_REQM 0x0648 /* PMU res req mask */
2241+#define BCMA_CC_CHIPCTL_ADDR 0x0650
2242+#define BCMA_CC_CHIPCTL_DATA 0x0654
2243+#define BCMA_CC_REGCTL_ADDR 0x0658
2244+#define BCMA_CC_REGCTL_DATA 0x065C
2245+#define BCMA_CC_PLLCTL_ADDR 0x0660
2246+#define BCMA_CC_PLLCTL_DATA 0x0664
2247+#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
2248+#define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */
2249+
2250+/* Data for the PMU, if available.
2251+ * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
2252+ */
2253+struct bcma_chipcommon_pmu {
2254+ u8 rev; /* PMU revision */
2255+ u32 crystalfreq; /* The active crystal frequency (in kHz) */
2256+};
2257+
2258+struct bcma_drv_cc {
2259+ struct bcma_device *core;
2260+ u32 status;
2261+ u32 capabilities;
2262+ u32 capabilities_ext;
2263+ /* Fast Powerup Delay constant */
2264+ u16 fast_pwrup_delay;
2265+ struct bcma_chipcommon_pmu pmu;
2266+};
2267+
2268+/* Register access */
2269+#define bcma_cc_read32(cc, offset) \
2270+ bcma_read32((cc)->core, offset)
2271+#define bcma_cc_write32(cc, offset, val) \
2272+ bcma_write32((cc)->core, offset, val)
2273+
2274+#define bcma_cc_mask32(cc, offset, mask) \
2275+ bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) & (mask))
2276+#define bcma_cc_set32(cc, offset, set) \
2277+ bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) | (set))
2278+#define bcma_cc_maskset32(cc, offset, mask, set) \
2279+ bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set))
2280+
2281+extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
2282+
2283+extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
2284+extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
2285+
2286+extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
2287+ u32 ticks);
2288+
2289+void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value);
2290+
2291+u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask);
2292+
2293+/* Chipcommon GPIO pin access. */
2294+u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask);
2295+u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value);
2296+u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value);
2297+u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value);
2298+u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value);
2299+u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value);
2300+
2301+/* PMU support */
2302+extern void bcma_pmu_init(struct bcma_drv_cc *cc);
2303+
2304+#endif /* LINUX_BCMA_DRIVER_CC_H_ */
2305--- /dev/null
2306+++ b/include/linux/bcma/bcma_driver_pci.h
2307@@ -0,0 +1,91 @@
2308+#ifndef LINUX_BCMA_DRIVER_PCI_H_
2309+#define LINUX_BCMA_DRIVER_PCI_H_
2310+
2311+#include <linux/types.h>
2312+
2313+struct pci_dev;
2314+
2315+/** PCI core registers. **/
2316+#define BCMA_CORE_PCI_CTL 0x0000 /* PCI Control */
2317+#define BCMA_CORE_PCI_CTL_RST_OE 0x00000001 /* PCI_RESET Output Enable */
2318+#define BCMA_CORE_PCI_CTL_RST 0x00000002 /* PCI_RESET driven out to pin */
2319+#define BCMA_CORE_PCI_CTL_CLK_OE 0x00000004 /* Clock gate Output Enable */
2320+#define BCMA_CORE_PCI_CTL_CLK 0x00000008 /* Gate for clock driven out to pin */
2321+#define BCMA_CORE_PCI_ARBCTL 0x0010 /* PCI Arbiter Control */
2322+#define BCMA_CORE_PCI_ARBCTL_INTERN 0x00000001 /* Use internal arbiter */
2323+#define BCMA_CORE_PCI_ARBCTL_EXTERN 0x00000002 /* Use external arbiter */
2324+#define BCMA_CORE_PCI_ARBCTL_PARKID 0x00000006 /* Mask, selects which agent is parked on an idle bus */
2325+#define BCMA_CORE_PCI_ARBCTL_PARKID_LAST 0x00000000 /* Last requestor */
2326+#define BCMA_CORE_PCI_ARBCTL_PARKID_4710 0x00000002 /* 4710 */
2327+#define BCMA_CORE_PCI_ARBCTL_PARKID_EXT0 0x00000004 /* External requestor 0 */
2328+#define BCMA_CORE_PCI_ARBCTL_PARKID_EXT1 0x00000006 /* External requestor 1 */
2329+#define BCMA_CORE_PCI_ISTAT 0x0020 /* Interrupt status */
2330+#define BCMA_CORE_PCI_ISTAT_INTA 0x00000001 /* PCI INTA# */
2331+#define BCMA_CORE_PCI_ISTAT_INTB 0x00000002 /* PCI INTB# */
2332+#define BCMA_CORE_PCI_ISTAT_SERR 0x00000004 /* PCI SERR# (write to clear) */
2333+#define BCMA_CORE_PCI_ISTAT_PERR 0x00000008 /* PCI PERR# (write to clear) */
2334+#define BCMA_CORE_PCI_ISTAT_PME 0x00000010 /* PCI PME# */
2335+#define BCMA_CORE_PCI_IMASK 0x0024 /* Interrupt mask */
2336+#define BCMA_CORE_PCI_IMASK_INTA 0x00000001 /* PCI INTA# */
2337+#define BCMA_CORE_PCI_IMASK_INTB 0x00000002 /* PCI INTB# */
2338+#define BCMA_CORE_PCI_IMASK_SERR 0x00000004 /* PCI SERR# */
2339+#define BCMA_CORE_PCI_IMASK_PERR 0x00000008 /* PCI PERR# */
2340+#define BCMA_CORE_PCI_IMASK_PME 0x00000010 /* PCI PME# */
2341+#define BCMA_CORE_PCI_MBOX 0x0028 /* Backplane to PCI Mailbox */
2342+#define BCMA_CORE_PCI_MBOX_F0_0 0x00000100 /* PCI function 0, INT 0 */
2343+#define BCMA_CORE_PCI_MBOX_F0_1 0x00000200 /* PCI function 0, INT 1 */
2344+#define BCMA_CORE_PCI_MBOX_F1_0 0x00000400 /* PCI function 1, INT 0 */
2345+#define BCMA_CORE_PCI_MBOX_F1_1 0x00000800 /* PCI function 1, INT 1 */
2346+#define BCMA_CORE_PCI_MBOX_F2_0 0x00001000 /* PCI function 2, INT 0 */
2347+#define BCMA_CORE_PCI_MBOX_F2_1 0x00002000 /* PCI function 2, INT 1 */
2348+#define BCMA_CORE_PCI_MBOX_F3_0 0x00004000 /* PCI function 3, INT 0 */
2349+#define BCMA_CORE_PCI_MBOX_F3_1 0x00008000 /* PCI function 3, INT 1 */
2350+#define BCMA_CORE_PCI_BCAST_ADDR 0x0050 /* Backplane Broadcast Address */
2351+#define BCMA_CORE_PCI_BCAST_ADDR_MASK 0x000000FF
2352+#define BCMA_CORE_PCI_BCAST_DATA 0x0054 /* Backplane Broadcast Data */
2353+#define BCMA_CORE_PCI_GPIO_IN 0x0060 /* rev >= 2 only */
2354+#define BCMA_CORE_PCI_GPIO_OUT 0x0064 /* rev >= 2 only */
2355+#define BCMA_CORE_PCI_GPIO_ENABLE 0x0068 /* rev >= 2 only */
2356+#define BCMA_CORE_PCI_GPIO_CTL 0x006C /* rev >= 2 only */
2357+#define BCMA_CORE_PCI_SBTOPCI0 0x0100 /* Backplane to PCI translation 0 (sbtopci0) */
2358+#define BCMA_CORE_PCI_SBTOPCI0_MASK 0xFC000000
2359+#define BCMA_CORE_PCI_SBTOPCI1 0x0104 /* Backplane to PCI translation 1 (sbtopci1) */
2360+#define BCMA_CORE_PCI_SBTOPCI1_MASK 0xFC000000
2361+#define BCMA_CORE_PCI_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */
2362+#define BCMA_CORE_PCI_SBTOPCI2_MASK 0xC0000000
2363+#define BCMA_CORE_PCI_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */
2364+#define BCMA_CORE_PCI_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */
2365+#define BCMA_CORE_PCI_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */
2366+#define BCMA_CORE_PCI_PCICFG3 0x0700 /* PCI config space 3 (rev >= 8) */
2367+#define BCMA_CORE_PCI_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */
2368+
2369+/* SBtoPCIx */
2370+#define BCMA_CORE_PCI_SBTOPCI_MEM 0x00000000
2371+#define BCMA_CORE_PCI_SBTOPCI_IO 0x00000001
2372+#define BCMA_CORE_PCI_SBTOPCI_CFG0 0x00000002
2373+#define BCMA_CORE_PCI_SBTOPCI_CFG1 0x00000003
2374+#define BCMA_CORE_PCI_SBTOPCI_PREF 0x00000004 /* Prefetch enable */
2375+#define BCMA_CORE_PCI_SBTOPCI_BURST 0x00000008 /* Burst enable */
2376+#define BCMA_CORE_PCI_SBTOPCI_MRM 0x00000020 /* Memory Read Multiple */
2377+#define BCMA_CORE_PCI_SBTOPCI_RC 0x00000030 /* Read Command mask (rev >= 11) */
2378+#define BCMA_CORE_PCI_SBTOPCI_RC_READ 0x00000000 /* Memory read */
2379+#define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */
2380+#define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */
2381+
2382+/* PCIcore specific boardflags */
2383+#define BCMA_CORE_PCI_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */
2384+
2385+struct bcma_drv_pci {
2386+ struct bcma_device *core;
2387+ u8 setup_done:1;
2388+};
2389+
2390+/* Register access */
2391+#define pcicore_read32(pc, offset) bcma_read32((pc)->core, offset)
2392+#define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val)
2393+
2394+extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
2395+extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
2396+ struct bcma_device *core, bool enable);
2397+
2398+#endif /* LINUX_BCMA_DRIVER_PCI_H_ */
2399--- /dev/null
2400+++ b/include/linux/bcma/bcma_regs.h
2401@@ -0,0 +1,59 @@
2402+#ifndef LINUX_BCMA_REGS_H_
2403+#define LINUX_BCMA_REGS_H_
2404+
2405+/* Some single registers are shared between many cores */
2406+/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
2407+#define BCMA_CLKCTLST 0x01E0 /* Clock control and status */
2408+#define BCMA_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
2409+#define BCMA_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
2410+#define BCMA_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
2411+#define BCMA_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
2412+#define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
2413+#define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
2414+#define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */
2415+#define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
2416+#define BCMA_CLKCTLST_HAVEHT 0x00020000 /* HT available */
2417+#define BCMA_CLKCTLST_BP_ON_ALP 0x00040000 /* RO: running on ALP clock */
2418+#define BCMA_CLKCTLST_BP_ON_HT 0x00080000 /* RO: running on HT clock */
2419+#define BCMA_CLKCTLST_EXTRESST 0x07000000 /* Mask of external resource status */
2420+/* Is there any BCM4328 on BCMA bus? */
2421+#define BCMA_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
2422+#define BCMA_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
2423+
2424+/* Agent registers (common for every core) */
2425+#define BCMA_IOCTL 0x0408 /* IO control */
2426+#define BCMA_IOCTL_CLK 0x0001
2427+#define BCMA_IOCTL_FGC 0x0002
2428+#define BCMA_IOCTL_CORE_BITS 0x3FFC
2429+#define BCMA_IOCTL_PME_EN 0x4000
2430+#define BCMA_IOCTL_BIST_EN 0x8000
2431+#define BCMA_IOST 0x0500 /* IO status */
2432+#define BCMA_IOST_CORE_BITS 0x0FFF
2433+#define BCMA_IOST_DMA64 0x1000
2434+#define BCMA_IOST_GATED_CLK 0x2000
2435+#define BCMA_IOST_BIST_ERROR 0x4000
2436+#define BCMA_IOST_BIST_DONE 0x8000
2437+#define BCMA_RESET_CTL 0x0800
2438+#define BCMA_RESET_CTL_RESET 0x0001
2439+
2440+/* BCMA PCI config space registers. */
2441+#define BCMA_PCI_PMCSR 0x44
2442+#define BCMA_PCI_PE 0x100
2443+#define BCMA_PCI_BAR0_WIN 0x80 /* Backplane address space 0 */
2444+#define BCMA_PCI_BAR1_WIN 0x84 /* Backplane address space 1 */
2445+#define BCMA_PCI_SPROMCTL 0x88 /* SPROM control */
2446+#define BCMA_PCI_SPROMCTL_WE 0x10 /* SPROM write enable */
2447+#define BCMA_PCI_BAR1_CONTROL 0x8c /* Address space 1 burst control */
2448+#define BCMA_PCI_IRQS 0x90 /* PCI interrupts */
2449+#define BCMA_PCI_IRQMASK 0x94 /* PCI IRQ control and mask (pcirev >= 6 only) */
2450+#define BCMA_PCI_BACKPLANE_IRQS 0x98 /* Backplane Interrupts */
2451+#define BCMA_PCI_BAR0_WIN2 0xAC
2452+#define BCMA_PCI_GPIO_IN 0xB0 /* GPIO Input (pcirev >= 3 only) */
2453+#define BCMA_PCI_GPIO_OUT 0xB4 /* GPIO Output (pcirev >= 3 only) */
2454+#define BCMA_PCI_GPIO_OUT_ENABLE 0xB8 /* GPIO Output Enable/Disable (pcirev >= 3 only) */
2455+#define BCMA_PCI_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
2456+#define BCMA_PCI_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
2457+#define BCMA_PCI_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
2458+#define BCMA_PCI_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
2459+
2460+#endif /* LINUX_BCMA_REGS_H_ */
2461--- a/include/linux/mod_devicetable.h
2462+++ b/include/linux/mod_devicetable.h
2463@@ -382,6 +382,23 @@ struct ssb_device_id {
2464 #define SSB_ANY_ID 0xFFFF
2465 #define SSB_ANY_REV 0xFF
2466 
2467+/* Broadcom's specific AMBA core, see drivers/bcma/ */
2468+struct bcma_device_id {
2469+ __u16 manuf;
2470+ __u16 id;
2471+ __u8 rev;
2472+ __u8 class;
2473+};
2474+#define BCMA_CORE(_manuf, _id, _rev, _class) \
2475+ { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, }
2476+#define BCMA_CORETABLE_END \
2477+ { 0, },
2478+
2479+#define BCMA_ANY_MANUF 0xFFFF
2480+#define BCMA_ANY_ID 0xFFFF
2481+#define BCMA_ANY_REV 0xFF
2482+#define BCMA_ANY_CLASS 0xFF
2483+
2484 struct virtio_device_id {
2485     __u32 device;
2486     __u32 vendor;
2487--- a/scripts/mod/file2alias.c
2488+++ b/scripts/mod/file2alias.c
2489@@ -702,6 +702,24 @@ static int do_ssb_entry(const char *file
2490     return 1;
2491 }
2492 
2493+/* Looks like: bcma:mNidNrevNclN. */
2494+static int do_bcma_entry(const char *filename,
2495+ struct bcma_device_id *id, char *alias)
2496+{
2497+ id->manuf = TO_NATIVE(id->manuf);
2498+ id->id = TO_NATIVE(id->id);
2499+ id->rev = TO_NATIVE(id->rev);
2500+ id->class = TO_NATIVE(id->class);
2501+
2502+ strcpy(alias, "bcma:");
2503+ ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf);
2504+ ADD(alias, "id", id->id != BCMA_ANY_ID, id->id);
2505+ ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev);
2506+ ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class);
2507+ add_wildcard(alias);
2508+ return 1;
2509+}
2510+
2511 /* Looks like: virtio:dNvN */
2512 static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
2513                char *alias)
2514@@ -968,6 +986,10 @@ void handle_moddevtable(struct module *m
2515         do_table(symval, sym->st_size,
2516              sizeof(struct ssb_device_id), "ssb",
2517              do_ssb_entry, mod);
2518+ else if (sym_is(symname, "__mod_bcma_device_table"))
2519+ do_table(symval, sym->st_size,
2520+ sizeof(struct bcma_device_id), "bcma",
2521+ do_bcma_entry, mod);
2522     else if (sym_is(symname, "__mod_virtio_device_table"))
2523         do_table(symval, sym->st_size,
2524              sizeof(struct virtio_device_id), "virtio",
2525--- /dev/null
2526+++ b/drivers/bcma/sprom.c
2527@@ -0,0 +1,171 @@
2528+/*
2529+ * Broadcom specific AMBA
2530+ * SPROM reading
2531+ *
2532+ * Licensed under the GNU/GPL. See COPYING for details.
2533+ */
2534+
2535+#include "bcma_private.h"
2536+
2537+#include <linux/bcma/bcma.h>
2538+#include <linux/bcma/bcma_regs.h>
2539+#include <linux/pci.h>
2540+#include <linux/io.h>
2541+#include <linux/dma-mapping.h>
2542+#include <linux/slab.h>
2543+
2544+#define SPOFF(offset) ((offset) / sizeof(u16))
2545+
2546+/**************************************************
2547+ * R/W ops.
2548+ **************************************************/
2549+
2550+static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
2551+{
2552+ int i;
2553+ for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
2554+ sprom[i] = bcma_read16(bus->drv_cc.core,
2555+ offset + (i * 2));
2556+}
2557+
2558+/**************************************************
2559+ * Validation.
2560+ **************************************************/
2561+
2562+static inline u8 bcma_crc8(u8 crc, u8 data)
2563+{
2564+ /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
2565+ static const u8 t[] = {
2566+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
2567+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
2568+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
2569+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
2570+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
2571+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
2572+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
2573+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
2574+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
2575+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
2576+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
2577+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
2578+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
2579+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
2580+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
2581+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
2582+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
2583+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
2584+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
2585+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
2586+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
2587+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
2588+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
2589+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
2590+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
2591+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
2592+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
2593+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
2594+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
2595+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
2596+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
2597+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
2598+ };
2599+ return t[crc ^ data];
2600+}
2601+
2602+static u8 bcma_sprom_crc(const u16 *sprom)
2603+{
2604+ int word;
2605+ u8 crc = 0xFF;
2606+
2607+ for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
2608+ crc = bcma_crc8(crc, sprom[word] & 0x00FF);
2609+ crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
2610+ }
2611+ crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
2612+ crc ^= 0xFF;
2613+
2614+ return crc;
2615+}
2616+
2617+static int bcma_sprom_check_crc(const u16 *sprom)
2618+{
2619+ u8 crc;
2620+ u8 expected_crc;
2621+ u16 tmp;
2622+
2623+ crc = bcma_sprom_crc(sprom);
2624+ tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
2625+ expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
2626+ if (crc != expected_crc)
2627+ return -EPROTO;
2628+
2629+ return 0;
2630+}
2631+
2632+static int bcma_sprom_valid(const u16 *sprom)
2633+{
2634+ u16 revision;
2635+ int err;
2636+
2637+ err = bcma_sprom_check_crc(sprom);
2638+ if (err)
2639+ return err;
2640+
2641+ revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
2642+ if (revision != 8 && revision != 9) {
2643+ pr_err("Unsupported SPROM revision: %d\n", revision);
2644+ return -ENOENT;
2645+ }
2646+
2647+ return 0;
2648+}
2649+
2650+/**************************************************
2651+ * SPROM extraction.
2652+ **************************************************/
2653+
2654+static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
2655+{
2656+ u16 v;
2657+ int i;
2658+
2659+ for (i = 0; i < 3; i++) {
2660+ v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
2661+ *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
2662+ }
2663+}
2664+
2665+int bcma_sprom_get(struct bcma_bus *bus)
2666+{
2667+ u16 offset;
2668+ u16 *sprom;
2669+ int err = 0;
2670+
2671+ if (!bus->drv_cc.core)
2672+ return -EOPNOTSUPP;
2673+
2674+ if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
2675+ return -ENOENT;
2676+
2677+ sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
2678+ GFP_KERNEL);
2679+ if (!sprom)
2680+ return -ENOMEM;
2681+
2682+ /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
2683+ * According to brcm80211 this applies to cards with PCIe rev >= 6
2684+ * TODO: understand this condition and use it */
2685+ offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
2686+ BCMA_CC_SPROM_PCIE6;
2687+ bcma_sprom_read(bus, offset, sprom);
2688+
2689+ err = bcma_sprom_valid(sprom);
2690+ if (err)
2691+ goto out;
2692+
2693+ bcma_sprom_extract_r8(bus, sprom);
2694+
2695+out:
2696+ kfree(sprom);
2697+ return err;
2698+}
2699--- /dev/null
2700+++ b/drivers/bcma/driver_pci_host.c
2701@@ -0,0 +1,14 @@
2702+/*
2703+ * Broadcom specific AMBA
2704+ * PCI Core in hostmode
2705+ *
2706+ * Licensed under the GNU/GPL. See COPYING for details.
2707+ */
2708+
2709+#include "bcma_private.h"
2710+#include <linux/bcma/bcma.h>
2711+
2712+void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
2713+{
2714+ pr_err("No support for PCI core in hostmode yet\n");
2715+}
2716

Archive Download this file



interactive