Bluetooth: Graceful cleanup for uninitialised timer & unregistered device.

The device de-registration when called from different process context
without regristation, doesn't complete because of synchronized timer
delete APIs. Hence timer setup state is checked before deletion to
avoid non returnable code. Also graceful cleanup is ensured.

Change-Id: I865e9d93aa9833f854b83c8718d33f13ba140df0
CRs-fixed: 326882
Signed-off-by: Royston Rodrigues <roystonr@codeaurora.org>
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 3c4aa8f..101697f 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -419,6 +419,7 @@
 	if (rc < 0) {
 		BT_ERR("Cannot open the command channel");
 		hci_free_dev(hdev);
+		hdev = NULL;
 		return -ENODEV;
 	}
 
@@ -427,6 +428,7 @@
 	if (rc < 0) {
 		BT_ERR("Failed to open the Data channel");
 		hci_free_dev(hdev);
+		hdev = NULL;
 		return -ENODEV;
 	}
 
@@ -443,6 +445,15 @@
 
 static void hci_smd_deregister_dev(struct hci_smd_data *hsmd)
 {
+	if (hsmd->hdev) {
+		if (hci_unregister_dev(hsmd->hdev) < 0)
+			BT_ERR("Can't unregister HCI device %s",
+				hsmd->hdev->name);
+
+		hci_free_dev(hsmd->hdev);
+		hsmd->hdev = NULL;
+	}
+
 	smd_close(hs.event_channel);
 	smd_close(hs.data_channel);
 
@@ -452,13 +463,14 @@
 		wake_unlock(&hs.wake_lock_tx);
 
 	/*Destroy the timer used to monitor the Rx queue for emptiness */
-	del_timer_sync(&hs.rx_q_timer);
+	if (hs.rx_q_timer.function) {
+		del_timer_sync(&hs.rx_q_timer);
+		hs.rx_q_timer.function = NULL;
+		hs.rx_q_timer.data = 0;
+	}
+
 	tasklet_kill(&hs.hci_event_task);
 	tasklet_kill(&hs.hci_data_task);
-	if (hci_unregister_dev(hsmd->hdev) < 0)
-		BT_ERR("Can't unregister HCI device %s", hsmd->hdev->name);
-
-	hci_free_dev(hsmd->hdev);
 }
 
 static int hcismd_set_enable(const char *val, struct kernel_param *kp)