mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-25 16:31:13 +00:00
687 lines
16 KiB
Diff
687 lines
16 KiB
Diff
|
--- a/arch/mips/bcm47xx/Kconfig
|
||
|
+++ b/arch/mips/bcm47xx/Kconfig
|
||
|
@@ -4,6 +4,7 @@ config BCM47XX_SSB
|
||
|
bool "SSB Support for Broadcom BCM47XX"
|
||
|
select SYS_HAS_CPU_BMIPS32_3300
|
||
|
select SSB
|
||
|
+ select SSB_HOST_SOC
|
||
|
select SSB_DRIVER_MIPS
|
||
|
select SSB_DRIVER_EXTIF
|
||
|
select SSB_EMBEDDED
|
||
|
--- a/drivers/ssb/Kconfig
|
||
|
+++ b/drivers/ssb/Kconfig
|
||
|
@@ -80,6 +80,15 @@ config SSB_SDIOHOST
|
||
|
|
||
|
If unsure, say N
|
||
|
|
||
|
+config SSB_HOST_SOC
|
||
|
+ bool "Support for SSB bus on SoC"
|
||
|
+ depends on SSB
|
||
|
+ help
|
||
|
+ Host interface for a SSB directly mapped into memory. This is
|
||
|
+ for some Broadcom SoCs from the BCM47xx and BCM53xx lines.
|
||
|
+
|
||
|
+ If unsure, say N
|
||
|
+
|
||
|
config SSB_SILENT
|
||
|
bool "No SSB kernel messages"
|
||
|
depends on SSB && EXPERT
|
||
|
--- a/drivers/ssb/Makefile
|
||
|
+++ b/drivers/ssb/Makefile
|
||
|
@@ -5,8 +5,9 @@ ssb-$(CONFIG_SSB_SPROM) += sprom.o
|
||
|
|
||
|
# host support
|
||
|
ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o
|
||
|
-ssb-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o
|
||
|
+ssb-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o bridge_pcmcia_80211.o
|
||
|
ssb-$(CONFIG_SSB_SDIOHOST) += sdio.o
|
||
|
+ssb-$(CONFIG_SSB_HOST_SOC) += host_soc.o
|
||
|
|
||
|
# built-in drivers
|
||
|
ssb-y += driver_chipcommon.o
|
||
|
--- /dev/null
|
||
|
+++ b/drivers/ssb/bridge_pcmcia_80211.c
|
||
|
@@ -0,0 +1,128 @@
|
||
|
+/*
|
||
|
+ * Broadcom 43xx PCMCIA-SSB bridge module
|
||
|
+ *
|
||
|
+ * Copyright (c) 2007 Michael Buesch <m@bues.ch>
|
||
|
+ *
|
||
|
+ * Licensed under the GNU/GPL. See COPYING for details.
|
||
|
+ */
|
||
|
+
|
||
|
+#include <linux/ssb/ssb.h>
|
||
|
+#include <linux/slab.h>
|
||
|
+#include <linux/module.h>
|
||
|
+
|
||
|
+#include <pcmcia/cistpl.h>
|
||
|
+#include <pcmcia/ciscode.h>
|
||
|
+#include <pcmcia/ds.h>
|
||
|
+#include <pcmcia/cisreg.h>
|
||
|
+
|
||
|
+#include "ssb_private.h"
|
||
|
+
|
||
|
+static const struct pcmcia_device_id ssb_host_pcmcia_tbl[] = {
|
||
|
+ PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448),
|
||
|
+ PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476),
|
||
|
+ PCMCIA_DEVICE_NULL,
|
||
|
+};
|
||
|
+
|
||
|
+MODULE_DEVICE_TABLE(pcmcia, ssb_host_pcmcia_tbl);
|
||
|
+
|
||
|
+static int ssb_host_pcmcia_probe(struct pcmcia_device *dev)
|
||
|
+{
|
||
|
+ struct ssb_bus *ssb;
|
||
|
+ int err = -ENOMEM;
|
||
|
+ int res = 0;
|
||
|
+
|
||
|
+ ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
|
||
|
+ if (!ssb)
|
||
|
+ goto out_error;
|
||
|
+
|
||
|
+ err = -ENODEV;
|
||
|
+
|
||
|
+ dev->config_flags |= CONF_ENABLE_IRQ;
|
||
|
+
|
||
|
+ dev->resource[2]->flags |= WIN_ENABLE | WIN_DATA_WIDTH_16 |
|
||
|
+ WIN_USE_WAIT;
|
||
|
+ dev->resource[2]->start = 0;
|
||
|
+ dev->resource[2]->end = SSB_CORE_SIZE;
|
||
|
+ res = pcmcia_request_window(dev, dev->resource[2], 250);
|
||
|
+ if (res != 0)
|
||
|
+ goto err_kfree_ssb;
|
||
|
+
|
||
|
+ res = pcmcia_map_mem_page(dev, dev->resource[2], 0);
|
||
|
+ if (res != 0)
|
||
|
+ goto err_disable;
|
||
|
+
|
||
|
+ if (!dev->irq)
|
||
|
+ goto err_disable;
|
||
|
+
|
||
|
+ res = pcmcia_enable_device(dev);
|
||
|
+ if (res != 0)
|
||
|
+ goto err_disable;
|
||
|
+
|
||
|
+ err = ssb_bus_pcmciabus_register(ssb, dev, dev->resource[2]->start);
|
||
|
+ if (err)
|
||
|
+ goto err_disable;
|
||
|
+ dev->priv = ssb;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+
|
||
|
+err_disable:
|
||
|
+ pcmcia_disable_device(dev);
|
||
|
+err_kfree_ssb:
|
||
|
+ kfree(ssb);
|
||
|
+out_error:
|
||
|
+ ssb_err("Initialization failed (%d, %d)\n", res, err);
|
||
|
+ return err;
|
||
|
+}
|
||
|
+
|
||
|
+static void ssb_host_pcmcia_remove(struct pcmcia_device *dev)
|
||
|
+{
|
||
|
+ struct ssb_bus *ssb = dev->priv;
|
||
|
+
|
||
|
+ ssb_bus_unregister(ssb);
|
||
|
+ pcmcia_disable_device(dev);
|
||
|
+ kfree(ssb);
|
||
|
+ dev->priv = NULL;
|
||
|
+}
|
||
|
+
|
||
|
+#ifdef CONFIG_PM
|
||
|
+static int ssb_host_pcmcia_suspend(struct pcmcia_device *dev)
|
||
|
+{
|
||
|
+ struct ssb_bus *ssb = dev->priv;
|
||
|
+
|
||
|
+ return ssb_bus_suspend(ssb);
|
||
|
+}
|
||
|
+
|
||
|
+static int ssb_host_pcmcia_resume(struct pcmcia_device *dev)
|
||
|
+{
|
||
|
+ struct ssb_bus *ssb = dev->priv;
|
||
|
+
|
||
|
+ return ssb_bus_resume(ssb);
|
||
|
+}
|
||
|
+#else /* CONFIG_PM */
|
||
|
+# define ssb_host_pcmcia_suspend NULL
|
||
|
+# define ssb_host_pcmcia_resume NULL
|
||
|
+#endif /* CONFIG_PM */
|
||
|
+
|
||
|
+static struct pcmcia_driver ssb_host_pcmcia_driver = {
|
||
|
+ .owner = THIS_MODULE,
|
||
|
+ .name = "ssb-pcmcia",
|
||
|
+ .id_table = ssb_host_pcmcia_tbl,
|
||
|
+ .probe = ssb_host_pcmcia_probe,
|
||
|
+ .remove = ssb_host_pcmcia_remove,
|
||
|
+ .suspend = ssb_host_pcmcia_suspend,
|
||
|
+ .resume = ssb_host_pcmcia_resume,
|
||
|
+};
|
||
|
+
|
||
|
+/*
|
||
|
+ * These are not module init/exit functions!
|
||
|
+ * The module_pcmcia_driver() helper cannot be used here.
|
||
|
+ */
|
||
|
+int ssb_host_pcmcia_init(void)
|
||
|
+{
|
||
|
+ return pcmcia_register_driver(&ssb_host_pcmcia_driver);
|
||
|
+}
|
||
|
+
|
||
|
+void ssb_host_pcmcia_exit(void)
|
||
|
+{
|
||
|
+ pcmcia_unregister_driver(&ssb_host_pcmcia_driver);
|
||
|
+}
|
||
|
--- /dev/null
|
||
|
+++ b/drivers/ssb/host_soc.c
|
||
|
@@ -0,0 +1,173 @@
|
||
|
+/*
|
||
|
+ * Sonics Silicon Backplane SoC host related functions.
|
||
|
+ * Subsystem core
|
||
|
+ *
|
||
|
+ * Copyright 2005, Broadcom Corporation
|
||
|
+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
|
||
|
+ *
|
||
|
+ * Licensed under the GNU/GPL. See COPYING for details.
|
||
|
+ */
|
||
|
+
|
||
|
+#include <linux/ssb/ssb.h>
|
||
|
+
|
||
|
+#include "ssb_private.h"
|
||
|
+
|
||
|
+static u8 ssb_host_soc_read8(struct ssb_device *dev, u16 offset)
|
||
|
+{
|
||
|
+ struct ssb_bus *bus = dev->bus;
|
||
|
+
|
||
|
+ offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
+ return readb(bus->mmio + offset);
|
||
|
+}
|
||
|
+
|
||
|
+static u16 ssb_host_soc_read16(struct ssb_device *dev, u16 offset)
|
||
|
+{
|
||
|
+ struct ssb_bus *bus = dev->bus;
|
||
|
+
|
||
|
+ offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
+ return readw(bus->mmio + offset);
|
||
|
+}
|
||
|
+
|
||
|
+static u32 ssb_host_soc_read32(struct ssb_device *dev, u16 offset)
|
||
|
+{
|
||
|
+ struct ssb_bus *bus = dev->bus;
|
||
|
+
|
||
|
+ offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
+ return readl(bus->mmio + offset);
|
||
|
+}
|
||
|
+
|
||
|
+#ifdef CONFIG_SSB_BLOCKIO
|
||
|
+static void ssb_host_soc_block_read(struct ssb_device *dev, void *buffer,
|
||
|
+ size_t count, u16 offset, u8 reg_width)
|
||
|
+{
|
||
|
+ struct ssb_bus *bus = dev->bus;
|
||
|
+ void __iomem *addr;
|
||
|
+
|
||
|
+ offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
+ addr = bus->mmio + offset;
|
||
|
+
|
||
|
+ switch (reg_width) {
|
||
|
+ case sizeof(u8): {
|
||
|
+ u8 *buf = buffer;
|
||
|
+
|
||
|
+ while (count) {
|
||
|
+ *buf = __raw_readb(addr);
|
||
|
+ buf++;
|
||
|
+ count--;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ case sizeof(u16): {
|
||
|
+ __le16 *buf = buffer;
|
||
|
+
|
||
|
+ SSB_WARN_ON(count & 1);
|
||
|
+ while (count) {
|
||
|
+ *buf = (__force __le16)__raw_readw(addr);
|
||
|
+ buf++;
|
||
|
+ count -= 2;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ case sizeof(u32): {
|
||
|
+ __le32 *buf = buffer;
|
||
|
+
|
||
|
+ SSB_WARN_ON(count & 3);
|
||
|
+ while (count) {
|
||
|
+ *buf = (__force __le32)__raw_readl(addr);
|
||
|
+ buf++;
|
||
|
+ count -= 4;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ default:
|
||
|
+ SSB_WARN_ON(1);
|
||
|
+ }
|
||
|
+}
|
||
|
+#endif /* CONFIG_SSB_BLOCKIO */
|
||
|
+
|
||
|
+static void ssb_host_soc_write8(struct ssb_device *dev, u16 offset, u8 value)
|
||
|
+{
|
||
|
+ struct ssb_bus *bus = dev->bus;
|
||
|
+
|
||
|
+ offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
+ writeb(value, bus->mmio + offset);
|
||
|
+}
|
||
|
+
|
||
|
+static void ssb_host_soc_write16(struct ssb_device *dev, u16 offset, u16 value)
|
||
|
+{
|
||
|
+ struct ssb_bus *bus = dev->bus;
|
||
|
+
|
||
|
+ offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
+ writew(value, bus->mmio + offset);
|
||
|
+}
|
||
|
+
|
||
|
+static void ssb_host_soc_write32(struct ssb_device *dev, u16 offset, u32 value)
|
||
|
+{
|
||
|
+ struct ssb_bus *bus = dev->bus;
|
||
|
+
|
||
|
+ offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
+ writel(value, bus->mmio + offset);
|
||
|
+}
|
||
|
+
|
||
|
+#ifdef CONFIG_SSB_BLOCKIO
|
||
|
+static void ssb_host_soc_block_write(struct ssb_device *dev, const void *buffer,
|
||
|
+ size_t count, u16 offset, u8 reg_width)
|
||
|
+{
|
||
|
+ struct ssb_bus *bus = dev->bus;
|
||
|
+ void __iomem *addr;
|
||
|
+
|
||
|
+ offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
+ addr = bus->mmio + offset;
|
||
|
+
|
||
|
+ switch (reg_width) {
|
||
|
+ case sizeof(u8): {
|
||
|
+ const u8 *buf = buffer;
|
||
|
+
|
||
|
+ while (count) {
|
||
|
+ __raw_writeb(*buf, addr);
|
||
|
+ buf++;
|
||
|
+ count--;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ case sizeof(u16): {
|
||
|
+ const __le16 *buf = buffer;
|
||
|
+
|
||
|
+ SSB_WARN_ON(count & 1);
|
||
|
+ while (count) {
|
||
|
+ __raw_writew((__force u16)(*buf), addr);
|
||
|
+ buf++;
|
||
|
+ count -= 2;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ case sizeof(u32): {
|
||
|
+ const __le32 *buf = buffer;
|
||
|
+
|
||
|
+ SSB_WARN_ON(count & 3);
|
||
|
+ while (count) {
|
||
|
+ __raw_writel((__force u32)(*buf), addr);
|
||
|
+ buf++;
|
||
|
+ count -= 4;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ default:
|
||
|
+ SSB_WARN_ON(1);
|
||
|
+ }
|
||
|
+}
|
||
|
+#endif /* CONFIG_SSB_BLOCKIO */
|
||
|
+
|
||
|
+/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
|
||
|
+const struct ssb_bus_ops ssb_host_soc_ops = {
|
||
|
+ .read8 = ssb_host_soc_read8,
|
||
|
+ .read16 = ssb_host_soc_read16,
|
||
|
+ .read32 = ssb_host_soc_read32,
|
||
|
+ .write8 = ssb_host_soc_write8,
|
||
|
+ .write16 = ssb_host_soc_write16,
|
||
|
+ .write32 = ssb_host_soc_write32,
|
||
|
+#ifdef CONFIG_SSB_BLOCKIO
|
||
|
+ .block_read = ssb_host_soc_block_read,
|
||
|
+ .block_write = ssb_host_soc_block_write,
|
||
|
+#endif
|
||
|
+};
|
||
|
--- a/drivers/ssb/main.c
|
||
|
+++ b/drivers/ssb/main.c
|
||
|
@@ -596,166 +596,6 @@ error:
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
-static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset)
|
||
|
-{
|
||
|
- struct ssb_bus *bus = dev->bus;
|
||
|
-
|
||
|
- offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
- return readb(bus->mmio + offset);
|
||
|
-}
|
||
|
-
|
||
|
-static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
|
||
|
-{
|
||
|
- struct ssb_bus *bus = dev->bus;
|
||
|
-
|
||
|
- offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
- return readw(bus->mmio + offset);
|
||
|
-}
|
||
|
-
|
||
|
-static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset)
|
||
|
-{
|
||
|
- struct ssb_bus *bus = dev->bus;
|
||
|
-
|
||
|
- offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
- return readl(bus->mmio + offset);
|
||
|
-}
|
||
|
-
|
||
|
-#ifdef CONFIG_SSB_BLOCKIO
|
||
|
-static void ssb_ssb_block_read(struct ssb_device *dev, void *buffer,
|
||
|
- size_t count, u16 offset, u8 reg_width)
|
||
|
-{
|
||
|
- struct ssb_bus *bus = dev->bus;
|
||
|
- void __iomem *addr;
|
||
|
-
|
||
|
- offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
- addr = bus->mmio + offset;
|
||
|
-
|
||
|
- switch (reg_width) {
|
||
|
- case sizeof(u8): {
|
||
|
- u8 *buf = buffer;
|
||
|
-
|
||
|
- while (count) {
|
||
|
- *buf = __raw_readb(addr);
|
||
|
- buf++;
|
||
|
- count--;
|
||
|
- }
|
||
|
- break;
|
||
|
- }
|
||
|
- case sizeof(u16): {
|
||
|
- __le16 *buf = buffer;
|
||
|
-
|
||
|
- SSB_WARN_ON(count & 1);
|
||
|
- while (count) {
|
||
|
- *buf = (__force __le16)__raw_readw(addr);
|
||
|
- buf++;
|
||
|
- count -= 2;
|
||
|
- }
|
||
|
- break;
|
||
|
- }
|
||
|
- case sizeof(u32): {
|
||
|
- __le32 *buf = buffer;
|
||
|
-
|
||
|
- SSB_WARN_ON(count & 3);
|
||
|
- while (count) {
|
||
|
- *buf = (__force __le32)__raw_readl(addr);
|
||
|
- buf++;
|
||
|
- count -= 4;
|
||
|
- }
|
||
|
- break;
|
||
|
- }
|
||
|
- default:
|
||
|
- SSB_WARN_ON(1);
|
||
|
- }
|
||
|
-}
|
||
|
-#endif /* CONFIG_SSB_BLOCKIO */
|
||
|
-
|
||
|
-static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value)
|
||
|
-{
|
||
|
- struct ssb_bus *bus = dev->bus;
|
||
|
-
|
||
|
- offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
- writeb(value, bus->mmio + offset);
|
||
|
-}
|
||
|
-
|
||
|
-static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
|
||
|
-{
|
||
|
- struct ssb_bus *bus = dev->bus;
|
||
|
-
|
||
|
- offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
- writew(value, bus->mmio + offset);
|
||
|
-}
|
||
|
-
|
||
|
-static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
|
||
|
-{
|
||
|
- struct ssb_bus *bus = dev->bus;
|
||
|
-
|
||
|
- offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
- writel(value, bus->mmio + offset);
|
||
|
-}
|
||
|
-
|
||
|
-#ifdef CONFIG_SSB_BLOCKIO
|
||
|
-static void ssb_ssb_block_write(struct ssb_device *dev, const void *buffer,
|
||
|
- size_t count, u16 offset, u8 reg_width)
|
||
|
-{
|
||
|
- struct ssb_bus *bus = dev->bus;
|
||
|
- void __iomem *addr;
|
||
|
-
|
||
|
- offset += dev->core_index * SSB_CORE_SIZE;
|
||
|
- addr = bus->mmio + offset;
|
||
|
-
|
||
|
- switch (reg_width) {
|
||
|
- case sizeof(u8): {
|
||
|
- const u8 *buf = buffer;
|
||
|
-
|
||
|
- while (count) {
|
||
|
- __raw_writeb(*buf, addr);
|
||
|
- buf++;
|
||
|
- count--;
|
||
|
- }
|
||
|
- break;
|
||
|
- }
|
||
|
- case sizeof(u16): {
|
||
|
- const __le16 *buf = buffer;
|
||
|
-
|
||
|
- SSB_WARN_ON(count & 1);
|
||
|
- while (count) {
|
||
|
- __raw_writew((__force u16)(*buf), addr);
|
||
|
- buf++;
|
||
|
- count -= 2;
|
||
|
- }
|
||
|
- break;
|
||
|
- }
|
||
|
- case sizeof(u32): {
|
||
|
- const __le32 *buf = buffer;
|
||
|
-
|
||
|
- SSB_WARN_ON(count & 3);
|
||
|
- while (count) {
|
||
|
- __raw_writel((__force u32)(*buf), addr);
|
||
|
- buf++;
|
||
|
- count -= 4;
|
||
|
- }
|
||
|
- break;
|
||
|
- }
|
||
|
- default:
|
||
|
- SSB_WARN_ON(1);
|
||
|
- }
|
||
|
-}
|
||
|
-#endif /* CONFIG_SSB_BLOCKIO */
|
||
|
-
|
||
|
-/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
|
||
|
-static const struct ssb_bus_ops ssb_ssb_ops = {
|
||
|
- .read8 = ssb_ssb_read8,
|
||
|
- .read16 = ssb_ssb_read16,
|
||
|
- .read32 = ssb_ssb_read32,
|
||
|
- .write8 = ssb_ssb_write8,
|
||
|
- .write16 = ssb_ssb_write16,
|
||
|
- .write32 = ssb_ssb_write32,
|
||
|
-#ifdef CONFIG_SSB_BLOCKIO
|
||
|
- .block_read = ssb_ssb_block_read,
|
||
|
- .block_write = ssb_ssb_block_write,
|
||
|
-#endif
|
||
|
-};
|
||
|
-
|
||
|
static int ssb_fetch_invariants(struct ssb_bus *bus,
|
||
|
ssb_invariants_func_t get_invariants)
|
||
|
{
|
||
|
@@ -876,7 +716,6 @@ int ssb_bus_pcibus_register(struct ssb_b
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
-EXPORT_SYMBOL(ssb_bus_pcibus_register);
|
||
|
#endif /* CONFIG_SSB_PCIHOST */
|
||
|
|
||
|
#ifdef CONFIG_SSB_PCMCIAHOST
|
||
|
@@ -898,7 +737,6 @@ int ssb_bus_pcmciabus_register(struct ss
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
-EXPORT_SYMBOL(ssb_bus_pcmciabus_register);
|
||
|
#endif /* CONFIG_SSB_PCMCIAHOST */
|
||
|
|
||
|
#ifdef CONFIG_SSB_SDIOHOST
|
||
|
@@ -923,13 +761,14 @@ int ssb_bus_sdiobus_register(struct ssb_
|
||
|
EXPORT_SYMBOL(ssb_bus_sdiobus_register);
|
||
|
#endif /* CONFIG_SSB_PCMCIAHOST */
|
||
|
|
||
|
+#ifdef CONFIG_SSB_HOST_SOC
|
||
|
int ssb_bus_ssbbus_register(struct ssb_bus *bus, unsigned long baseaddr,
|
||
|
ssb_invariants_func_t get_invariants)
|
||
|
{
|
||
|
int err;
|
||
|
|
||
|
bus->bustype = SSB_BUSTYPE_SSB;
|
||
|
- bus->ops = &ssb_ssb_ops;
|
||
|
+ bus->ops = &ssb_host_soc_ops;
|
||
|
|
||
|
err = ssb_bus_register(bus, get_invariants, baseaddr);
|
||
|
if (!err) {
|
||
|
@@ -939,6 +778,7 @@ int ssb_bus_ssbbus_register(struct ssb_b
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
+#endif
|
||
|
|
||
|
int __ssb_driver_register(struct ssb_driver *drv, struct module *owner)
|
||
|
{
|
||
|
@@ -1465,6 +1305,12 @@ static int __init ssb_modinit(void)
|
||
|
/* don't fail SSB init because of this */
|
||
|
err = 0;
|
||
|
}
|
||
|
+ err = ssb_host_pcmcia_init();
|
||
|
+ if (err) {
|
||
|
+ ssb_err("PCMCIA host initialization failed\n");
|
||
|
+ /* don't fail SSB init because of this */
|
||
|
+ err = 0;
|
||
|
+ }
|
||
|
err = ssb_gige_init();
|
||
|
if (err) {
|
||
|
ssb_err("SSB Broadcom Gigabit Ethernet driver initialization failed\n");
|
||
|
@@ -1482,6 +1328,7 @@ fs_initcall(ssb_modinit);
|
||
|
static void __exit ssb_modexit(void)
|
||
|
{
|
||
|
ssb_gige_exit();
|
||
|
+ ssb_host_pcmcia_exit();
|
||
|
b43_pci_ssb_bridge_exit();
|
||
|
bus_unregister(&ssb_bustype);
|
||
|
}
|
||
|
--- a/drivers/ssb/pcmcia.c
|
||
|
+++ b/drivers/ssb/pcmcia.c
|
||
|
@@ -147,8 +147,7 @@ error:
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
-int ssb_pcmcia_switch_core(struct ssb_bus *bus,
|
||
|
- struct ssb_device *dev)
|
||
|
+static int ssb_pcmcia_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
|
||
|
{
|
||
|
int err;
|
||
|
|
||
|
--- a/drivers/ssb/sdio.c
|
||
|
+++ b/drivers/ssb/sdio.c
|
||
|
@@ -200,7 +200,7 @@ out:
|
||
|
}
|
||
|
|
||
|
/* host must be already claimed */
|
||
|
-int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
|
||
|
+static int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
|
||
|
{
|
||
|
u8 coreidx = dev->core_index;
|
||
|
u32 sbaddr;
|
||
|
--- a/drivers/ssb/ssb_private.h
|
||
|
+++ b/drivers/ssb/ssb_private.h
|
||
|
@@ -85,8 +85,6 @@ static inline int ssb_pci_init(struct ss
|
||
|
|
||
|
/* pcmcia.c */
|
||
|
#ifdef CONFIG_SSB_PCMCIAHOST
|
||
|
-extern int ssb_pcmcia_switch_core(struct ssb_bus *bus,
|
||
|
- struct ssb_device *dev);
|
||
|
extern int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
|
||
|
u8 coreidx);
|
||
|
extern int ssb_pcmcia_switch_segment(struct ssb_bus *bus,
|
||
|
@@ -96,13 +94,10 @@ extern int ssb_pcmcia_get_invariants(str
|
||
|
extern int ssb_pcmcia_hardware_setup(struct ssb_bus *bus);
|
||
|
extern void ssb_pcmcia_exit(struct ssb_bus *bus);
|
||
|
extern int ssb_pcmcia_init(struct ssb_bus *bus);
|
||
|
+extern int ssb_host_pcmcia_init(void);
|
||
|
+extern void ssb_host_pcmcia_exit(void);
|
||
|
extern const struct ssb_bus_ops ssb_pcmcia_ops;
|
||
|
#else /* CONFIG_SSB_PCMCIAHOST */
|
||
|
-static inline int ssb_pcmcia_switch_core(struct ssb_bus *bus,
|
||
|
- struct ssb_device *dev)
|
||
|
-{
|
||
|
- return 0;
|
||
|
-}
|
||
|
static inline int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
|
||
|
u8 coreidx)
|
||
|
{
|
||
|
@@ -124,6 +119,13 @@ static inline int ssb_pcmcia_init(struct
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
+static inline int ssb_host_pcmcia_init(void)
|
||
|
+{
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+static inline void ssb_host_pcmcia_exit(void)
|
||
|
+{
|
||
|
+}
|
||
|
#endif /* CONFIG_SSB_PCMCIAHOST */
|
||
|
|
||
|
/* sdio.c */
|
||
|
@@ -132,9 +134,7 @@ extern int ssb_sdio_get_invariants(struc
|
||
|
struct ssb_init_invariants *iv);
|
||
|
|
||
|
extern u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset);
|
||
|
-extern int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev);
|
||
|
extern int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx);
|
||
|
-extern int ssb_sdio_hardware_setup(struct ssb_bus *bus);
|
||
|
extern void ssb_sdio_exit(struct ssb_bus *bus);
|
||
|
extern int ssb_sdio_init(struct ssb_bus *bus);
|
||
|
|
||
|
@@ -144,19 +144,10 @@ static inline u32 ssb_sdio_scan_read32(s
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
-static inline int ssb_sdio_switch_core(struct ssb_bus *bus,
|
||
|
- struct ssb_device *dev)
|
||
|
-{
|
||
|
- return 0;
|
||
|
-}
|
||
|
static inline int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
-static inline int ssb_sdio_hardware_setup(struct ssb_bus *bus)
|
||
|
-{
|
||
|
- return 0;
|
||
|
-}
|
||
|
static inline void ssb_sdio_exit(struct ssb_bus *bus)
|
||
|
{
|
||
|
}
|
||
|
@@ -166,6 +157,13 @@ static inline int ssb_sdio_init(struct s
|
||
|
}
|
||
|
#endif /* CONFIG_SSB_SDIOHOST */
|
||
|
|
||
|
+/**************************************************
|
||
|
+ * host_soc.c
|
||
|
+ **************************************************/
|
||
|
+
|
||
|
+#ifdef CONFIG_SSB_HOST_SOC
|
||
|
+extern const struct ssb_bus_ops ssb_host_soc_ops;
|
||
|
+#endif
|
||
|
|
||
|
/* scan.c */
|
||
|
extern const char *ssb_core_name(u16 coreid);
|