qseecom: Fix kernel panic

When qseecom_unload_app() is invoked, wait_event_freezable() is called
in an atomic context (within a spinlock).  wait_event_freezable() allows
sleep and should not  be called in an atomic context where sleep is not
allowed.

Change-Id: I8c9c6d28f9e492fbbf2ac74a5ee3d1067c7733ad
Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 8354aa8..696f16d 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -522,7 +522,6 @@
 	return 0;
 }
 
-
 static int __qseecom_listener_has_sent_rsp(struct qseecom_dev_handle *data)
 {
 	int ret;
@@ -771,21 +770,20 @@
 	int ret = 0;
 	struct qseecom_command_scm_resp resp;
 	struct qseecom_registered_app_list *ptr_app;
-	uint32_t unload = 0;
+	bool unload = false;
+	bool found_app = false;
 
 	if (qseecom.qseos_version == QSEOS_VERSION_14) {
 		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
 		list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
 								list) {
 			if (ptr_app->app_id == data->client.app_id) {
+				found_app = true;
 				if (ptr_app->ref_cnt == 1) {
-					unload = __qseecom_cleanup_app(data);
-					list_del(&ptr_app->list);
-					kzfree(ptr_app);
+					unload = true;
 					break;
 				} else {
 					ptr_app->ref_cnt--;
-					data->released = true;
 					pr_warn("Can't unload app with id %d (it is inuse)\n",
 							ptr_app->app_id);
 					break;
@@ -795,14 +793,20 @@
 		spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
 								flags);
 	}
-	if (!IS_ERR_OR_NULL(data->client.ihandle)) {
-		ion_unmap_kernel(qseecom.ion_clnt, data->client.ihandle);
-		ion_free(qseecom.ion_clnt, data->client.ihandle);
+	if (found_app == false)  {
+		pr_err("Cannot find app with id = %d\n", data->client.app_id);
+		return -EINVAL;
 	}
 
 	if ((unload) && (qseecom.qseos_version == QSEOS_VERSION_14)) {
 		struct qseecom_unload_app_ireq req;
 
+		__qseecom_cleanup_app(data);
+		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
+		list_del(&ptr_app->list);
+		kzfree(ptr_app);
+		spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
+								flags);
 		/* Populate the structure for sending scm call to load image */
 		req.qsee_cmd_id = QSEOS_APP_SHUTDOWN_COMMAND;
 		req.app_id = data->client.app_id;
@@ -840,6 +844,11 @@
 			}
 		}
 	}
+	if (!IS_ERR_OR_NULL(data->client.ihandle)) {
+		ion_unmap_kernel(qseecom.ion_clnt, data->client.ihandle);
+		ion_free(qseecom.ion_clnt, data->client.ihandle);
+		data->client.ihandle = NULL;
+	}
 	data->released = true;
 	return ret;
 }