diff options
author | Albert Herranz <albert_herranz@yahoo.es> | 2009-09-08 13:30:12 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-09-09 11:19:00 -0400 |
commit | 24ea602e183ca20a7577ebe253323d0e5d0f9847 (patch) | |
tree | 9cd9c0b3832cac2f155e633fbed1ce2bf3331f9a /drivers/ssb/main.c | |
parent | f020979d5d7c9816c071d0aedf60a889fa4fae40 (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.c | 58 |
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 | ||
93 | struct 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; | ||
104 | found: | ||
105 | ssb_buses_unlock(); | ||
106 | |||
107 | return bus; | ||
108 | } | ||
109 | #endif /* CONFIG_SSB_SDIOHOST */ | ||
110 | |||
91 | int ssb_for_each_bus_call(unsigned long data, | 111 | int 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); |
777 | err_unmap: | 809 | err_unmap: |
778 | ssb_iounmap(bus); | 810 | ssb_iounmap(bus); |
811 | err_sdio_exit: | ||
812 | ssb_sdio_exit(bus); | ||
779 | err_disable_xtal: | 813 | err_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, | |||
825 | EXPORT_SYMBOL(ssb_bus_pcmciabus_register); | 859 | EXPORT_SYMBOL(ssb_bus_pcmciabus_register); |
826 | #endif /* CONFIG_SSB_PCMCIAHOST */ | 860 | #endif /* CONFIG_SSB_PCMCIAHOST */ |
827 | 861 | ||
862 | #ifdef CONFIG_SSB_SDIOHOST | ||
863 | int 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 | } | ||
881 | EXPORT_SYMBOL(ssb_bus_sdiobus_register); | ||
882 | #endif /* CONFIG_SSB_PCMCIAHOST */ | ||
883 | |||
828 | int ssb_bus_ssbbus_register(struct ssb_bus *bus, | 884 | int 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) |