aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/main.c
diff options
context:
space:
mode:
authorAlbert Herranz <albert_herranz@yahoo.es>2009-09-08 13:30:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-09-09 11:19:00 -0400
commit24ea602e183ca20a7577ebe253323d0e5d0f9847 (patch)
tree9cd9c0b3832cac2f155e633fbed1ce2bf3331f9a /drivers/ssb/main.c
parentf020979d5d7c9816c071d0aedf60a889fa4fae40 (diff)
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 <albert_herranz@yahoo.es> Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/ssb/main.c')
-rw-r--r--drivers/ssb/main.c58
1 files changed, 57 insertions, 1 deletions
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 @@
17#include <linux/ssb/ssb_driver_gige.h> 17#include <linux/ssb/ssb_driver_gige.h>
18#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/mmc/sdio_func.h>
20 21
21#include <pcmcia/cs_types.h> 22#include <pcmcia/cs_types.h>
22#include <pcmcia/cs.h> 23#include <pcmcia/cs.h>
@@ -88,6 +89,25 @@ found:
88} 89}
89#endif /* CONFIG_SSB_PCMCIAHOST */ 90#endif /* CONFIG_SSB_PCMCIAHOST */
90 91
92#ifdef CONFIG_SSB_SDIOHOST
93struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func)
94{
95 struct ssb_bus *bus;
96
97 ssb_buses_lock();
98 list_for_each_entry(bus, &buses, list) {
99 if (bus->bustype == SSB_BUSTYPE_SDIO &&
100 bus->host_sdio == func)
101 goto found;
102 }
103 bus = NULL;
104found:
105 ssb_buses_unlock();
106
107 return bus;
108}
109#endif /* CONFIG_SSB_SDIOHOST */
110
91int ssb_for_each_bus_call(unsigned long data, 111int ssb_for_each_bus_call(unsigned long data,
92 int (*func)(struct ssb_bus *bus, unsigned long data)) 112 int (*func)(struct ssb_bus *bus, unsigned long data))
93{ 113{
@@ -469,6 +489,12 @@ static int ssb_devices_register(struct ssb_bus *bus)
469 dev->parent = &bus->host_pcmcia->dev; 489 dev->parent = &bus->host_pcmcia->dev;
470#endif 490#endif
471 break; 491 break;
492 case SSB_BUSTYPE_SDIO:
493#ifdef CONFIG_SSB_SDIO
494 sdev->irq = bus->host_sdio->dev.irq;
495 dev->parent = &bus->host_sdio->dev;
496#endif
497 break;
472 case SSB_BUSTYPE_SSB: 498 case SSB_BUSTYPE_SSB:
473 dev->dma_mask = &dev->coherent_dma_mask; 499 dev->dma_mask = &dev->coherent_dma_mask;
474 break; 500 break;
@@ -724,12 +750,18 @@ static int ssb_bus_register(struct ssb_bus *bus,
724 err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); 750 err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
725 if (err) 751 if (err)
726 goto out; 752 goto out;
753
754 /* Init SDIO-host device (if any), before the scan */
755 err = ssb_sdio_init(bus);
756 if (err)
757 goto err_disable_xtal;
758
727 ssb_buses_lock(); 759 ssb_buses_lock();
728 bus->busnumber = next_busnumber; 760 bus->busnumber = next_busnumber;
729 /* Scan for devices (cores) */ 761 /* Scan for devices (cores) */
730 err = ssb_bus_scan(bus, baseaddr); 762 err = ssb_bus_scan(bus, baseaddr);
731 if (err) 763 if (err)
732 goto err_disable_xtal; 764 goto err_sdio_exit;
733 765
734 /* Init PCI-host device (if any) */ 766 /* Init PCI-host device (if any) */
735 err = ssb_pci_init(bus); 767 err = ssb_pci_init(bus);
@@ -776,6 +808,8 @@ err_pci_exit:
776 ssb_pci_exit(bus); 808 ssb_pci_exit(bus);
777err_unmap: 809err_unmap:
778 ssb_iounmap(bus); 810 ssb_iounmap(bus);
811err_sdio_exit:
812 ssb_sdio_exit(bus);
779err_disable_xtal: 813err_disable_xtal:
780 ssb_buses_unlock(); 814 ssb_buses_unlock();
781 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0); 815 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
@@ -825,6 +859,28 @@ int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
825EXPORT_SYMBOL(ssb_bus_pcmciabus_register); 859EXPORT_SYMBOL(ssb_bus_pcmciabus_register);
826#endif /* CONFIG_SSB_PCMCIAHOST */ 860#endif /* CONFIG_SSB_PCMCIAHOST */
827 861
862#ifdef CONFIG_SSB_SDIOHOST
863int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func,
864 unsigned int quirks)
865{
866 int err;
867
868 bus->bustype = SSB_BUSTYPE_SDIO;
869 bus->host_sdio = func;
870 bus->ops = &ssb_sdio_ops;
871 bus->quirks = quirks;
872
873 err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0);
874 if (!err) {
875 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
876 "SDIO device %s\n", sdio_func_id(func));
877 }
878
879 return err;
880}
881EXPORT_SYMBOL(ssb_bus_sdiobus_register);
882#endif /* CONFIG_SSB_PCMCIAHOST */
883
828int ssb_bus_ssbbus_register(struct ssb_bus *bus, 884int ssb_bus_ssbbus_register(struct ssb_bus *bus,
829 unsigned long baseaddr, 885 unsigned long baseaddr,
830 ssb_invariants_func_t get_invariants) 886 ssb_invariants_func_t get_invariants)