Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[linux-2.6.git] / drivers / bcma / main.c
index 10f92b3..b8379b9 100644 (file)
 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
 MODULE_LICENSE("GPL");
 
+/* contains the number the next bus should get. */
+static unsigned int bcma_bus_next_num = 0;
+
+/* bcma_buses_mutex locks the bcma_bus_next_num */
+static DEFINE_MUTEX(bcma_buses_mutex);
+
 static int bcma_bus_match(struct device *dev, struct device_driver *drv);
 static int bcma_device_probe(struct device *dev);
 static int bcma_device_remove(struct device *dev);
@@ -93,7 +99,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
 
                core->dev.release = bcma_release_core_dev;
                core->dev.bus = &bcma_bus_type;
-               dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
+               dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
 
                switch (bus->hosttype) {
                case BCMA_HOSTTYPE_PCI:
@@ -132,11 +138,15 @@ static void bcma_unregister_cores(struct bcma_bus *bus)
        }
 }
 
-int bcma_bus_register(struct bcma_bus *bus)
+int __devinit bcma_bus_register(struct bcma_bus *bus)
 {
        int err;
        struct bcma_device *core;
 
+       mutex_lock(&bcma_buses_mutex);
+       bus->num = bcma_bus_next_num++;
+       mutex_unlock(&bcma_buses_mutex);
+
        /* Scan for devices (cores) */
        err = bcma_bus_scan(bus);
        if (err) {
@@ -169,10 +179,8 @@ int bcma_bus_register(struct bcma_bus *bus)
        err = bcma_sprom_get(bus);
        if (err == -ENOENT) {
                pr_err("No SPROM available\n");
-       } else if (err) {
+       } else if (err)
                pr_err("Failed to get SPROM: %d\n", err);
-               return -ENOENT;
-       }
 
        /* Register found cores */
        bcma_register_cores(bus);
@@ -241,6 +249,21 @@ int __init bcma_bus_early_register(struct bcma_bus *bus,
 }
 
 #ifdef CONFIG_PM
+int bcma_bus_suspend(struct bcma_bus *bus)
+{
+       struct bcma_device *core;
+
+       list_for_each_entry(core, &bus->cores, list) {
+               struct device_driver *drv = core->dev.driver;
+               if (drv) {
+                       struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
+                       if (adrv->suspend)
+                               adrv->suspend(core);
+               }
+       }
+       return 0;
+}
+
 int bcma_bus_resume(struct bcma_bus *bus)
 {
        struct bcma_device *core;
@@ -252,6 +275,15 @@ int bcma_bus_resume(struct bcma_bus *bus)
                bcma_core_chipcommon_init(&bus->drv_cc);
        }
 
+       list_for_each_entry(core, &bus->cores, list) {
+               struct device_driver *drv = core->dev.driver;
+               if (drv) {
+                       struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
+                       if (adrv->resume)
+                               adrv->resume(core);
+               }
+       }
+
        return 0;
 }
 #endif