msm: qdsp5: Fix scheduling while atomic bug in adsp probe
-Scheduling while atomic message comes while boot up of target.
-This message comes when kernel thread to process adsp rpc
call backs is started in adsp_probe which runs in
atomic context.
-Move adsp rpc kernel thread start to bottom half using work queue.
CRs-Fixed: 342525
Change-Id: I50834b4f50fe8a7c29979808ee5fa0de6f4b0c62
Signed-off-by: Chaithanya Krishna Bacharaju <chaithan@codeaurora.org>
diff --git a/arch/arm/mach-msm/qdsp5/adsp.c b/arch/arm/mach-msm/qdsp5/adsp.c
index 71e0409..6f5ccbf 100644
--- a/arch/arm/mach-msm/qdsp5/adsp.c
+++ b/arch/arm/mach-msm/qdsp5/adsp.c
@@ -34,6 +34,7 @@
#include <linux/wait.h>
#include <linux/wakelock.h>
#include <linux/slab.h>
+#include <linux/workqueue.h>
#include <mach/debug_mm.h>
#include <linux/debugfs.h>
@@ -71,6 +72,10 @@
static uint32_t rpc_adsp_rtos_mtoa_vers_comp;
static DEFINE_MUTEX(adsp_open_lock);
+static struct workqueue_struct *msm_adsp_probe_work_queue;
+static void adsp_probe_work(struct work_struct *work);
+static DECLARE_WORK(msm_adsp_probe_work, adsp_probe_work);
+
/* protect interactions with the ADSP command/message queue */
static spinlock_t adsp_cmd_lock;
static spinlock_t adsp_write_lock;
@@ -1230,8 +1235,8 @@
goto fail_rpc_register;
}
- /* start the kernel thread to process the callbacks */
- kthread_run(adsp_rpc_thread, NULL, "kadspd");
+ /* schedule start of kernel thread later using work queue */
+ queue_work(msm_adsp_probe_work_queue, &msm_adsp_probe_work);
for (i = 0; i < count; i++) {
struct msm_adsp_module *mod = adsp_modules + i;
@@ -1271,6 +1276,13 @@
kfree(adsp_info.init_info_ptr);
return rc;
}
+
+static void adsp_probe_work(struct work_struct *work)
+{
+ /* start the kernel thread to process the callbacks */
+ kthread_run(adsp_rpc_thread, NULL, "kadspd");
+}
+
#ifdef CONFIG_DEBUG_FS
static int get_parameters(char *buf, long int *param1, int num_of_par)
{
@@ -1433,6 +1445,9 @@
rpc_adsp_rtos_mtoa_vers_comp = 0x00030001;
#endif
+ msm_adsp_probe_work_queue = create_workqueue("msm_adsp_probe");
+ if (msm_adsp_probe_work_queue == NULL)
+ return -ENOMEM;
msm_adsp_driver.driver.name = msm_adsp_driver_name;
rc = platform_driver_register(&msm_adsp_driver);
MM_INFO("%s -- %d\n", msm_adsp_driver_name, rc);