brcm80211: smac: remove firmware requests from init_module syscall
authorArend van Spriel <arend@broadcom.com>
Fri, 2 Mar 2012 21:55:50 +0000 (22:55 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 5 Mar 2012 20:54:01 +0000 (15:54 -0500)
As indicated in [1] on netdev mailing list drivers should not block
on the init_module() syscall. This patch defers the actual driver
registration to a workqueue so the init_module() syscall can complete
without delay.

[1] http://article.gmane.org/gmane.linux.network/217729/

Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c

index fec0f10..569ab8a 100644 (file)
@@ -1169,25 +1169,31 @@ static struct bcma_driver brcms_bcma_driver = {
 /**
  * This is the main entry point for the brcmsmac driver.
  *
- * This function determines if a device pointed to by pdev is a WL device,
- * and if so, performs a brcms_attach() on it.
- *
+ * This function is scheduled upon module initialization and
+ * does the driver registration, which result in brcms_bcma_probe()
+ * call resulting in the driver bringup.
  */
-static int __init brcms_module_init(void)
+static void brcms_driver_init(struct work_struct *work)
 {
-       int error = -ENODEV;
+       int error;
 
+       error = bcma_driver_register(&brcms_bcma_driver);
+       if (error)
+               pr_err("%s: register returned %d\n", __func__, error);
+}
+
+static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
+
+static int __init brcms_module_init(void)
+{
 #ifdef DEBUG
        if (msglevel != 0xdeadbeef)
                brcm_msg_level = msglevel;
-#endif                         /* DEBUG */
-
-       error = bcma_driver_register(&brcms_bcma_driver);
-       pr_err("%s: register returned %d\n", __func__, error);
-       if (!error)
-               return 0;
+#endif
+       if (!schedule_work(&brcms_driver_work))
+               return -EBUSY;
 
-       return error;
+       return 0;
 }
 
 /**
@@ -1199,6 +1205,7 @@ static int __init brcms_module_init(void)
  */
 static void __exit brcms_module_exit(void)
 {
+       cancel_work_sync(&brcms_driver_work);
        bcma_driver_unregister(&brcms_bcma_driver);
 }