1 --- a/arch/mips/bcm47xx/Kconfig
2 +++ b/arch/mips/bcm47xx/Kconfig
3 @@ -4,6 +4,7 @@ config BCM47XX_SSB
4 bool "SSB Support for Broadcom BCM47XX"
5 select SYS_HAS_CPU_BMIPS32_3300
9 select SSB_DRIVER_EXTIF
11 --- a/drivers/ssb/Kconfig
12 +++ b/drivers/ssb/Kconfig
13 @@ -80,6 +80,15 @@ config SSB_SDIOHOST
18 + bool "Support for SSB bus on SoC"
21 + Host interface for a SSB directly mapped into memory. This is
22 + for some Broadcom SoCs from the BCM47xx and BCM53xx lines.
27 bool "No SSB kernel messages"
28 depends on SSB && EXPERT
29 --- a/drivers/ssb/Makefile
30 +++ b/drivers/ssb/Makefile
31 @@ -5,8 +5,9 @@ ssb-$(CONFIG_SSB_SPROM) += sprom.o
34 ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o
35 -ssb-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o
36 +ssb-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o bridge_pcmcia_80211.o
37 ssb-$(CONFIG_SSB_SDIOHOST) += sdio.o
38 +ssb-$(CONFIG_SSB_HOST_SOC) += host_soc.o
41 ssb-y += driver_chipcommon.o
43 +++ b/drivers/ssb/bridge_pcmcia_80211.c
46 + * Broadcom 43xx PCMCIA-SSB bridge module
48 + * Copyright (c) 2007 Michael Buesch <m@bues.ch>
50 + * Licensed under the GNU/GPL. See COPYING for details.
53 +#include <linux/ssb/ssb.h>
54 +#include <linux/slab.h>
55 +#include <linux/module.h>
57 +#include <pcmcia/cistpl.h>
58 +#include <pcmcia/ciscode.h>
59 +#include <pcmcia/ds.h>
60 +#include <pcmcia/cisreg.h>
62 +#include "ssb_private.h"
64 +static const struct pcmcia_device_id ssb_host_pcmcia_tbl[] = {
65 + PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448),
66 + PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476),
70 +MODULE_DEVICE_TABLE(pcmcia, ssb_host_pcmcia_tbl);
72 +static int ssb_host_pcmcia_probe(struct pcmcia_device *dev)
74 + struct ssb_bus *ssb;
78 + ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
84 + dev->config_flags |= CONF_ENABLE_IRQ;
86 + dev->resource[2]->flags |= WIN_ENABLE | WIN_DATA_WIDTH_16 |
88 + dev->resource[2]->start = 0;
89 + dev->resource[2]->end = SSB_CORE_SIZE;
90 + res = pcmcia_request_window(dev, dev->resource[2], 250);
94 + res = pcmcia_map_mem_page(dev, dev->resource[2], 0);
101 + res = pcmcia_enable_device(dev);
105 + err = ssb_bus_pcmciabus_register(ssb, dev, dev->resource[2]->start);
113 + pcmcia_disable_device(dev);
117 + ssb_err("Initialization failed (%d, %d)\n", res, err);
121 +static void ssb_host_pcmcia_remove(struct pcmcia_device *dev)
123 + struct ssb_bus *ssb = dev->priv;
125 + ssb_bus_unregister(ssb);
126 + pcmcia_disable_device(dev);
132 +static int ssb_host_pcmcia_suspend(struct pcmcia_device *dev)
134 + struct ssb_bus *ssb = dev->priv;
136 + return ssb_bus_suspend(ssb);
139 +static int ssb_host_pcmcia_resume(struct pcmcia_device *dev)
141 + struct ssb_bus *ssb = dev->priv;
143 + return ssb_bus_resume(ssb);
145 +#else /* CONFIG_PM */
146 +# define ssb_host_pcmcia_suspend NULL
147 +# define ssb_host_pcmcia_resume NULL
148 +#endif /* CONFIG_PM */
150 +static struct pcmcia_driver ssb_host_pcmcia_driver = {
151 + .owner = THIS_MODULE,
152 + .name = "ssb-pcmcia",
153 + .id_table = ssb_host_pcmcia_tbl,
154 + .probe = ssb_host_pcmcia_probe,
155 + .remove = ssb_host_pcmcia_remove,
156 + .suspend = ssb_host_pcmcia_suspend,
157 + .resume = ssb_host_pcmcia_resume,
161 + * These are not module init/exit functions!
162 + * The module_pcmcia_driver() helper cannot be used here.
164 +int ssb_host_pcmcia_init(void)
166 + return pcmcia_register_driver(&ssb_host_pcmcia_driver);
169 +void ssb_host_pcmcia_exit(void)
171 + pcmcia_unregister_driver(&ssb_host_pcmcia_driver);
174 +++ b/drivers/ssb/host_soc.c
177 + * Sonics Silicon Backplane SoC host related functions.
180 + * Copyright 2005, Broadcom Corporation
181 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
183 + * Licensed under the GNU/GPL. See COPYING for details.
186 +#include <linux/ssb/ssb.h>
188 +#include "ssb_private.h"
190 +static u8 ssb_host_soc_read8(struct ssb_device *dev, u16 offset)
192 + struct ssb_bus *bus = dev->bus;
194 + offset += dev->core_index * SSB_CORE_SIZE;
195 + return readb(bus->mmio + offset);
198 +static u16 ssb_host_soc_read16(struct ssb_device *dev, u16 offset)
200 + struct ssb_bus *bus = dev->bus;
202 + offset += dev->core_index * SSB_CORE_SIZE;
203 + return readw(bus->mmio + offset);
206 +static u32 ssb_host_soc_read32(struct ssb_device *dev, u16 offset)
208 + struct ssb_bus *bus = dev->bus;
210 + offset += dev->core_index * SSB_CORE_SIZE;
211 + return readl(bus->mmio + offset);
214 +#ifdef CONFIG_SSB_BLOCKIO
215 +static void ssb_host_soc_block_read(struct ssb_device *dev, void *buffer,
216 + size_t count, u16 offset, u8 reg_width)
218 + struct ssb_bus *bus = dev->bus;
219 + void __iomem *addr;
221 + offset += dev->core_index * SSB_CORE_SIZE;
222 + addr = bus->mmio + offset;
224 + switch (reg_width) {
229 + *buf = __raw_readb(addr);
235 + case sizeof(u16): {
236 + __le16 *buf = buffer;
238 + SSB_WARN_ON(count & 1);
240 + *buf = (__force __le16)__raw_readw(addr);
246 + case sizeof(u32): {
247 + __le32 *buf = buffer;
249 + SSB_WARN_ON(count & 3);
251 + *buf = (__force __le32)__raw_readl(addr);
261 +#endif /* CONFIG_SSB_BLOCKIO */
263 +static void ssb_host_soc_write8(struct ssb_device *dev, u16 offset, u8 value)
265 + struct ssb_bus *bus = dev->bus;
267 + offset += dev->core_index * SSB_CORE_SIZE;
268 + writeb(value, bus->mmio + offset);
271 +static void ssb_host_soc_write16(struct ssb_device *dev, u16 offset, u16 value)
273 + struct ssb_bus *bus = dev->bus;
275 + offset += dev->core_index * SSB_CORE_SIZE;
276 + writew(value, bus->mmio + offset);
279 +static void ssb_host_soc_write32(struct ssb_device *dev, u16 offset, u32 value)
281 + struct ssb_bus *bus = dev->bus;
283 + offset += dev->core_index * SSB_CORE_SIZE;
284 + writel(value, bus->mmio + offset);
287 +#ifdef CONFIG_SSB_BLOCKIO
288 +static void ssb_host_soc_block_write(struct ssb_device *dev, const void *buffer,
289 + size_t count, u16 offset, u8 reg_width)
291 + struct ssb_bus *bus = dev->bus;
292 + void __iomem *addr;
294 + offset += dev->core_index * SSB_CORE_SIZE;
295 + addr = bus->mmio + offset;
297 + switch (reg_width) {
299 + const u8 *buf = buffer;
302 + __raw_writeb(*buf, addr);
308 + case sizeof(u16): {
309 + const __le16 *buf = buffer;
311 + SSB_WARN_ON(count & 1);
313 + __raw_writew((__force u16)(*buf), addr);
319 + case sizeof(u32): {
320 + const __le32 *buf = buffer;
322 + SSB_WARN_ON(count & 3);
324 + __raw_writel((__force u32)(*buf), addr);
334 +#endif /* CONFIG_SSB_BLOCKIO */
336 +/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
337 +const struct ssb_bus_ops ssb_host_soc_ops = {
338 + .read8 = ssb_host_soc_read8,
339 + .read16 = ssb_host_soc_read16,
340 + .read32 = ssb_host_soc_read32,
341 + .write8 = ssb_host_soc_write8,
342 + .write16 = ssb_host_soc_write16,
343 + .write32 = ssb_host_soc_write32,
344 +#ifdef CONFIG_SSB_BLOCKIO
345 + .block_read = ssb_host_soc_block_read,
346 + .block_write = ssb_host_soc_block_write,
349 --- a/drivers/ssb/main.c
350 +++ b/drivers/ssb/main.c
351 @@ -596,166 +596,6 @@ error:
355 -static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset)
357 - struct ssb_bus *bus = dev->bus;
359 - offset += dev->core_index * SSB_CORE_SIZE;
360 - return readb(bus->mmio + offset);
363 -static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
365 - struct ssb_bus *bus = dev->bus;
367 - offset += dev->core_index * SSB_CORE_SIZE;
368 - return readw(bus->mmio + offset);
371 -static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset)
373 - struct ssb_bus *bus = dev->bus;
375 - offset += dev->core_index * SSB_CORE_SIZE;
376 - return readl(bus->mmio + offset);
379 -#ifdef CONFIG_SSB_BLOCKIO
380 -static void ssb_ssb_block_read(struct ssb_device *dev, void *buffer,
381 - size_t count, u16 offset, u8 reg_width)
383 - struct ssb_bus *bus = dev->bus;
384 - void __iomem *addr;
386 - offset += dev->core_index * SSB_CORE_SIZE;
387 - addr = bus->mmio + offset;
389 - switch (reg_width) {
394 - *buf = __raw_readb(addr);
400 - case sizeof(u16): {
401 - __le16 *buf = buffer;
403 - SSB_WARN_ON(count & 1);
405 - *buf = (__force __le16)__raw_readw(addr);
411 - case sizeof(u32): {
412 - __le32 *buf = buffer;
414 - SSB_WARN_ON(count & 3);
416 - *buf = (__force __le32)__raw_readl(addr);
426 -#endif /* CONFIG_SSB_BLOCKIO */
428 -static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value)
430 - struct ssb_bus *bus = dev->bus;
432 - offset += dev->core_index * SSB_CORE_SIZE;
433 - writeb(value, bus->mmio + offset);
436 -static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
438 - struct ssb_bus *bus = dev->bus;
440 - offset += dev->core_index * SSB_CORE_SIZE;
441 - writew(value, bus->mmio + offset);
444 -static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
446 - struct ssb_bus *bus = dev->bus;
448 - offset += dev->core_index * SSB_CORE_SIZE;
449 - writel(value, bus->mmio + offset);
452 -#ifdef CONFIG_SSB_BLOCKIO
453 -static void ssb_ssb_block_write(struct ssb_device *dev, const void *buffer,
454 - size_t count, u16 offset, u8 reg_width)
456 - struct ssb_bus *bus = dev->bus;
457 - void __iomem *addr;
459 - offset += dev->core_index * SSB_CORE_SIZE;
460 - addr = bus->mmio + offset;
462 - switch (reg_width) {
464 - const u8 *buf = buffer;
467 - __raw_writeb(*buf, addr);
473 - case sizeof(u16): {
474 - const __le16 *buf = buffer;
476 - SSB_WARN_ON(count & 1);
478 - __raw_writew((__force u16)(*buf), addr);
484 - case sizeof(u32): {
485 - const __le32 *buf = buffer;
487 - SSB_WARN_ON(count & 3);
489 - __raw_writel((__force u32)(*buf), addr);
499 -#endif /* CONFIG_SSB_BLOCKIO */
501 -/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
502 -static const struct ssb_bus_ops ssb_ssb_ops = {
503 - .read8 = ssb_ssb_read8,
504 - .read16 = ssb_ssb_read16,
505 - .read32 = ssb_ssb_read32,
506 - .write8 = ssb_ssb_write8,
507 - .write16 = ssb_ssb_write16,
508 - .write32 = ssb_ssb_write32,
509 -#ifdef CONFIG_SSB_BLOCKIO
510 - .block_read = ssb_ssb_block_read,
511 - .block_write = ssb_ssb_block_write,
515 static int ssb_fetch_invariants(struct ssb_bus *bus,
516 ssb_invariants_func_t get_invariants)
518 @@ -876,7 +716,6 @@ int ssb_bus_pcibus_register(struct ssb_b
522 -EXPORT_SYMBOL(ssb_bus_pcibus_register);
523 #endif /* CONFIG_SSB_PCIHOST */
525 #ifdef CONFIG_SSB_PCMCIAHOST
526 @@ -898,7 +737,6 @@ int ssb_bus_pcmciabus_register(struct ss
530 -EXPORT_SYMBOL(ssb_bus_pcmciabus_register);
531 #endif /* CONFIG_SSB_PCMCIAHOST */
533 #ifdef CONFIG_SSB_SDIOHOST
534 @@ -923,13 +761,14 @@ int ssb_bus_sdiobus_register(struct ssb_
535 EXPORT_SYMBOL(ssb_bus_sdiobus_register);
536 #endif /* CONFIG_SSB_PCMCIAHOST */
538 +#ifdef CONFIG_SSB_HOST_SOC
539 int ssb_bus_ssbbus_register(struct ssb_bus *bus, unsigned long baseaddr,
540 ssb_invariants_func_t get_invariants)
544 bus->bustype = SSB_BUSTYPE_SSB;
545 - bus->ops = &ssb_ssb_ops;
546 + bus->ops = &ssb_host_soc_ops;
548 err = ssb_bus_register(bus, get_invariants, baseaddr);
550 @@ -939,6 +778,7 @@ int ssb_bus_ssbbus_register(struct ssb_b
556 int __ssb_driver_register(struct ssb_driver *drv, struct module *owner)
558 @@ -1465,6 +1305,12 @@ static int __init ssb_modinit(void)
559 /* don't fail SSB init because of this */
562 + err = ssb_host_pcmcia_init();
564 + ssb_err("PCMCIA host initialization failed\n");
565 + /* don't fail SSB init because of this */
568 err = ssb_gige_init();
570 ssb_err("SSB Broadcom Gigabit Ethernet driver initialization failed\n");
571 @@ -1482,6 +1328,7 @@ fs_initcall(ssb_modinit);
572 static void __exit ssb_modexit(void)
575 + ssb_host_pcmcia_exit();
576 b43_pci_ssb_bridge_exit();
577 bus_unregister(&ssb_bustype);
579 --- a/drivers/ssb/pcmcia.c
580 +++ b/drivers/ssb/pcmcia.c
581 @@ -147,8 +147,7 @@ error:
585 -int ssb_pcmcia_switch_core(struct ssb_bus *bus,
586 - struct ssb_device *dev)
587 +static int ssb_pcmcia_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
591 --- a/drivers/ssb/sdio.c
592 +++ b/drivers/ssb/sdio.c
593 @@ -200,7 +200,7 @@ out:
596 /* host must be already claimed */
597 -int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
598 +static int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
600 u8 coreidx = dev->core_index;
602 --- a/drivers/ssb/ssb_private.h
603 +++ b/drivers/ssb/ssb_private.h
604 @@ -85,8 +85,6 @@ static inline int ssb_pci_init(struct ss
607 #ifdef CONFIG_SSB_PCMCIAHOST
608 -extern int ssb_pcmcia_switch_core(struct ssb_bus *bus,
609 - struct ssb_device *dev);
610 extern int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
612 extern int ssb_pcmcia_switch_segment(struct ssb_bus *bus,
613 @@ -96,13 +94,10 @@ extern int ssb_pcmcia_get_invariants(str
614 extern int ssb_pcmcia_hardware_setup(struct ssb_bus *bus);
615 extern void ssb_pcmcia_exit(struct ssb_bus *bus);
616 extern int ssb_pcmcia_init(struct ssb_bus *bus);
617 +extern int ssb_host_pcmcia_init(void);
618 +extern void ssb_host_pcmcia_exit(void);
619 extern const struct ssb_bus_ops ssb_pcmcia_ops;
620 #else /* CONFIG_SSB_PCMCIAHOST */
621 -static inline int ssb_pcmcia_switch_core(struct ssb_bus *bus,
622 - struct ssb_device *dev)
626 static inline int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
629 @@ -124,6 +119,13 @@ static inline int ssb_pcmcia_init(struct
633 +static inline int ssb_host_pcmcia_init(void)
637 +static inline void ssb_host_pcmcia_exit(void)
640 #endif /* CONFIG_SSB_PCMCIAHOST */
643 @@ -132,9 +134,7 @@ extern int ssb_sdio_get_invariants(struc
644 struct ssb_init_invariants *iv);
646 extern u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset);
647 -extern int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev);
648 extern int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx);
649 -extern int ssb_sdio_hardware_setup(struct ssb_bus *bus);
650 extern void ssb_sdio_exit(struct ssb_bus *bus);
651 extern int ssb_sdio_init(struct ssb_bus *bus);
653 @@ -144,19 +144,10 @@ static inline u32 ssb_sdio_scan_read32(s
657 -static inline int ssb_sdio_switch_core(struct ssb_bus *bus,
658 - struct ssb_device *dev)
662 static inline int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
666 -static inline int ssb_sdio_hardware_setup(struct ssb_bus *bus)
670 static inline void ssb_sdio_exit(struct ssb_bus *bus)
673 @@ -166,6 +157,13 @@ static inline int ssb_sdio_init(struct s
675 #endif /* CONFIG_SSB_SDIOHOST */
677 +/**************************************************
679 + **************************************************/
681 +#ifdef CONFIG_SSB_HOST_SOC
682 +extern const struct ssb_bus_ops ssb_host_soc_ops;
686 extern const char *ssb_core_name(u16 coreid);