bcm4329: Fix add_timer race conditions (b/2249878)

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/bcm4329/src/dhd/sys/dhd_linux.c b/bcm4329/src/dhd/sys/dhd_linux.c
index 135db37..54fb62f 100644
--- a/bcm4329/src/dhd/sys/dhd_linux.c
+++ b/bcm4329/src/dhd/sys/dhd_linux.c
@@ -1890,7 +1890,7 @@
 #if defined(OOB_INTR_ONLY)
 	/* Host registration for OOB interrupt */
 	if (bcmsdh_register_oob_intr(dhdp)) {
-		del_timer(&dhd->timer);
+		del_timer_sync(&dhd->timer);
 		dhd->wd_timer_valid = FALSE;
 		DHD_ERROR(("%s Host failed to resgister for OOB\n", __FUNCTION__));
 		return -ENODEV;
@@ -1902,7 +1902,7 @@
 
 	/* If bus is not ready, can't come up */
 	if (dhd->pub.busstate != DHD_BUS_DATA) {
-		del_timer(&dhd->timer);
+		del_timer_sync(&dhd->timer);
 		dhd->wd_timer_valid = FALSE;
 		DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
 		return -ENODEV;
@@ -2029,7 +2029,7 @@
 #endif /* defined(OOB_INTR_ONLY) */
 
 			/* Clear the watchdog timer */
-			del_timer(&dhd->timer);
+			del_timer_sync(&dhd->timer);
 			dhd->wd_timer_valid = FALSE;
 		}
 	}
@@ -2280,7 +2280,7 @@
 #if defined(CONTINUOUS_WATCHDOG)
 	/* Stop timer and restart at new value */
 	if (dhd->wd_timer_valid == TRUE) {
-		del_timer(&dhd->timer);
+		del_timer_sync(&dhd->timer);
 		dhd->wd_timer_valid = FALSE;
 	}
 
@@ -2292,7 +2292,7 @@
 #else
 	/* Totally stop the timer */
 	if (!wdtick && dhd->wd_timer_valid == TRUE) {
-		del_timer(&dhd->timer);
+		del_timer_sync(&dhd->timer);
 		dhd->wd_timer_valid = FALSE;
 		save_dhd_watchdog_ms = wdtick;
 		return;
@@ -2304,7 +2304,7 @@
 
 			if (dhd->wd_timer_valid == TRUE)
 				/* Stop timer and restart at new value */
-				del_timer(&dhd->timer);
+				del_timer_sync(&dhd->timer);
 
 			/* Create timer again when watchdog period is
 			   dynamically changed or in the first instance
diff --git a/bcm4329/src/wl/sys/wl_iw.c b/bcm4329/src/wl/sys/wl_iw.c
index fd5caf0..5628d89 100644
--- a/bcm4329/src/wl/sys/wl_iw.c
+++ b/bcm4329/src/wl/sys/wl_iw.c
@@ -603,7 +603,7 @@
 		
 		g_bt->bt_state = BT_DHCP_START;
 		g_bt->timer_on = 1;
-		add_timer(&g_bt->timer);
+		mod_timer(&g_bt->timer, g_bt->timer.expires);
 		WL_TRACE(("%s enable BT DHCP Timer\n", __FUNCTION__));
 
 	}
@@ -618,8 +618,8 @@
 		
 		WL_TRACE(("%s disable BT DHCP Timer\n", __FUNCTION__));
 		if (g_bt->timer_on) {
-			del_timer(&g_bt->timer);
 			g_bt->timer_on = 0;
+			del_timer_sync(&g_bt->timer);
 		}
 
 		
@@ -840,7 +840,7 @@
 
 	WL_TRACE(("%s\n", __FUNCTION__));
 
-	del_timer(wl_ctl->timer);
+	del_timer_sync(wl_ctl->timer);
 
 	up(&wl_ctl->timer_sem);
 }
@@ -1789,8 +1789,8 @@
 		net_os_wake_lock(iscan->dev);
 
 		if (iscan->timer_on) {
-			del_timer(&iscan->timer);
 			iscan->timer_on = 0;
+			del_timer_sync(&iscan->timer);
 		}
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -1853,8 +1853,8 @@
 	}
 
 	if (iscan->timer_on) {
-		del_timer(&iscan->timer);
 		iscan->timer_on = 0;
+		del_timer_sync(&iscan->timer);
 	}
 
 	complete_and_exit(&iscan->sysioc_exited, 0);
@@ -1925,7 +1925,7 @@
 	}
 	else {
 		if (*timer) {
-			del_timer(*timer);
+			del_timer_sync(*timer);
 			kfree(*timer);
 			*timer = NULL;
 		}
@@ -2196,9 +2196,7 @@
 		&iscan->scan_flag, sizeof(iscan->scan_flag));
 	wl_iw_set_event_mask(dev);
 	wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
-	del_timer(&iscan->timer);
-	iscan->timer.expires = jiffies + iscan->timer_ms*HZ/1000;
-	add_timer(&iscan->timer);
+	mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000);
 	iscan->timer_on = 1;
 
 	return 0;
@@ -3854,17 +3852,16 @@
 	net_os_wake_lock(dev);
 	
 	if (dwrq->length && extra) {
+		if (strnicmp(extra, "START", strlen("START")) == 0) {
+			wl_iw_control_wl_on(dev, info);
+			WL_TRACE(("%s, Received regular START command\n", __FUNCTION__));
+		}
+
 		if (g_onoff == G_WLAN_SET_OFF) {
-			if (strnicmp(extra, "START", strlen("START")) != 0) {
-				WL_TRACE(("%s, missing START, Fail\n", __FUNCTION__));
-				kfree(extra);
-				net_os_wake_unlock(dev);
-				return -EFAULT;
-			}
-			else {
-				wl_iw_control_wl_on(dev, info);
-				WL_TRACE(("%s, Received regular START command\n", __FUNCTION__));
-			}
+			WL_TRACE(("%s, missing START, Fail\n", __FUNCTION__));
+			kfree(extra);
+			net_os_wake_unlock(dev);
+			return -EFAULT;
 		}
 
 	    if (strnicmp(extra, "SCAN-ACTIVE", strlen("SCAN-ACTIVE")) == 0) {
@@ -4579,16 +4576,15 @@
 		net_os_wake_lock(g_bt->dev);
 
 		if (g_bt->timer_on) {
-			del_timer(&g_bt->timer);
 			g_bt->timer_on = 0;
+			del_timer_sync(&g_bt->timer);
 		}
 
 		switch (g_bt->bt_state) {
 			case BT_DHCP_START:
 				
 				g_bt->bt_state = BT_DHCP_OPPORTUNITY_WINDOW;
-				mod_timer(&g_bt->timer, jiffies + \
-				           BT_DHCP_OPPORTUNITY_WINDOW_TIEM*HZ/1000);
+				mod_timer(&g_bt->timer, jiffies + BT_DHCP_OPPORTUNITY_WINDOW_TIEM*HZ/1000);
 				g_bt->timer_on = 1;
 				break;
 			case BT_DHCP_OPPORTUNITY_WINDOW:
@@ -4622,8 +4618,8 @@
 	}
 
 	if (g_bt->timer_on) {
-		del_timer(&g_bt->timer);
 		g_bt->timer_on = 0;
+		del_timer_sync(&g_bt->timer);
 	}
 
 	complete_and_exit(&g_bt->bt_exited, 0);