From 24ea602e183ca20a7577ebe253323d0e5d0f9847 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Tue, 8 Sep 2009 19:30:12 +0200 Subject: ssb: Implement SDIO host bus support Add support for communicating with a Sonics Silicon Backplane through a SDIO interface, as found in the Nintendo Wii WLAN daughter card. The Nintendo Wii WLAN card includes a custom Broadcom 4318 chip with a SDIO host interface. Signed-off-by: Albert Herranz Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/main.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'drivers/ssb/main.c') diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 8d16cb258ccf..579b114be412 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -88,6 +89,25 @@ found: } #endif /* CONFIG_SSB_PCMCIAHOST */ +#ifdef CONFIG_SSB_SDIOHOST +struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func) +{ + struct ssb_bus *bus; + + ssb_buses_lock(); + list_for_each_entry(bus, &buses, list) { + if (bus->bustype == SSB_BUSTYPE_SDIO && + bus->host_sdio == func) + goto found; + } + bus = NULL; +found: + ssb_buses_unlock(); + + return bus; +} +#endif /* CONFIG_SSB_SDIOHOST */ + int ssb_for_each_bus_call(unsigned long data, int (*func)(struct ssb_bus *bus, unsigned long data)) { @@ -467,6 +487,12 @@ static int ssb_devices_register(struct ssb_bus *bus) #ifdef CONFIG_SSB_PCMCIAHOST sdev->irq = bus->host_pcmcia->irq.AssignedIRQ; dev->parent = &bus->host_pcmcia->dev; +#endif + break; + case SSB_BUSTYPE_SDIO: +#ifdef CONFIG_SSB_SDIO + sdev->irq = bus->host_sdio->dev.irq; + dev->parent = &bus->host_sdio->dev; #endif break; case SSB_BUSTYPE_SSB: @@ -724,12 +750,18 @@ static int ssb_bus_register(struct ssb_bus *bus, err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); if (err) goto out; + + /* Init SDIO-host device (if any), before the scan */ + err = ssb_sdio_init(bus); + if (err) + goto err_disable_xtal; + ssb_buses_lock(); bus->busnumber = next_busnumber; /* Scan for devices (cores) */ err = ssb_bus_scan(bus, baseaddr); if (err) - goto err_disable_xtal; + goto err_sdio_exit; /* Init PCI-host device (if any) */ err = ssb_pci_init(bus); @@ -776,6 +808,8 @@ err_pci_exit: ssb_pci_exit(bus); err_unmap: ssb_iounmap(bus); +err_sdio_exit: + ssb_sdio_exit(bus); err_disable_xtal: ssb_buses_unlock(); ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0); @@ -825,6 +859,28 @@ int ssb_bus_pcmciabus_register(struct ssb_bus *bus, EXPORT_SYMBOL(ssb_bus_pcmciabus_register); #endif /* CONFIG_SSB_PCMCIAHOST */ +#ifdef CONFIG_SSB_SDIOHOST +int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func, + unsigned int quirks) +{ + int err; + + bus->bustype = SSB_BUSTYPE_SDIO; + bus->host_sdio = func; + bus->ops = &ssb_sdio_ops; + bus->quirks = quirks; + + err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0); + if (!err) { + ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " + "SDIO device %s\n", sdio_func_id(func)); + } + + return err; +} +EXPORT_SYMBOL(ssb_bus_sdiobus_register); +#endif /* CONFIG_SSB_PCMCIAHOST */ + int ssb_bus_ssbbus_register(struct ssb_bus *bus, unsigned long baseaddr, ssb_invariants_func_t get_invariants) -- cgit v1.2.3