Merge master.kernel.org:/home/rmk/linux-2.6-arm
[safe/jmp/linux-2.6] / drivers / ssb / main.c
index 8d16cb2..579b114 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/ssb/ssb_driver_gige.h>
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
+#include <linux/mmc/sdio_func.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -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))
 {
@@ -469,6 +489,12 @@ static int ssb_devices_register(struct ssb_bus *bus)
                        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:
                        dev->dma_mask = &dev->coherent_dma_mask;
                        break;
@@ -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)