From 544dff7ea4d8b1bd44eb2d21a6b33f0b521a3b6e Mon Sep 17 00:00:00 2001 From: Satya Durga Srinivasu Prabhala Date: Fri, 17 Feb 2017 19:17:45 -0800 Subject: [PATCH] soc: qcom: pil-loaders: move pil loading of ADSP, SLPI & CDSP to workqueue When pil loading done through user space helper, there is a possibility that signal could be pending on thread that initiated the pil, which would lead to pil failure. To avoid this issue, move pil loading for ADSP, SLPI and CDSP to separate workqueue in respective loader drivers. Change-Id: Ie60a7eba7c52ac1565ce166d0e367379cce0b03e Signed-off-by: Satya Durga Srinivasu Prabhala --- drivers/sensors/sensors_ssc.c | 17 ++++++++++++++--- drivers/soc/qcom/qdsp6v2/adsp-loader.c | 16 +++++++++++++--- drivers/soc/qcom/qdsp6v2/cdsp-loader.c | 22 ++++++++++++++++------ 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/drivers/sensors/sensors_ssc.c b/drivers/sensors/sensors_ssc.c index 0910ef34e777..0e299efece94 100644 --- a/drivers/sensors/sensors_ssc.c +++ b/drivers/sensors/sensors_ssc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -26,6 +26,8 @@ #include #include #include +#include + #include #define IMAGE_LOAD_CMD 1 @@ -64,10 +66,11 @@ static struct attribute *attrs[] = { }; static struct platform_device *slpi_private; +static struct work_struct slpi_ldr_work; -static void slpi_loader_do(struct platform_device *pdev) +static void slpi_load_fw(struct work_struct *slpi_ldr_work) { - + struct platform_device *pdev = slpi_private; struct slpi_loader_private *priv = NULL; int ret; const char *firmware_name = NULL; @@ -111,6 +114,12 @@ fail: dev_err(&pdev->dev, "%s: SLPI image loading failed\n", __func__); } +static void slpi_loader_do(struct platform_device *pdev) +{ + dev_info(&pdev->dev, "%s: scheduling work to load SLPI fw\n", __func__); + schedule_work(&slpi_ldr_work); +} + static void slpi_loader_unload(struct platform_device *pdev) { struct slpi_loader_private *priv = NULL; @@ -336,6 +345,8 @@ static int sensors_ssc_probe(struct platform_device *pdev) goto cdev_add_err; } + INIT_WORK(&slpi_ldr_work, slpi_load_fw); + return 0; cdev_add_err: diff --git a/drivers/soc/qcom/qdsp6v2/adsp-loader.c b/drivers/soc/qcom/qdsp6v2/adsp-loader.c index 51539a36a74f..b45eac88ed12 100644 --- a/drivers/soc/qcom/qdsp6v2/adsp-loader.c +++ b/drivers/soc/qcom/qdsp6v2/adsp-loader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -20,6 +20,8 @@ #include #include #include +#include + #include #define Q6_PIL_GET_DELAY_MS 100 @@ -44,12 +46,13 @@ static struct attribute *attrs[] = { NULL, }; +static struct work_struct adsp_ldr_work; static struct platform_device *adsp_private; static void adsp_loader_unload(struct platform_device *pdev); -static void adsp_loader_do(struct platform_device *pdev) +static void adsp_load_fw(struct work_struct *adsp_ldr_work) { - + struct platform_device *pdev = adsp_private; struct adsp_loader_private *priv = NULL; const char *adsp_dt = "qcom,adsp-state"; @@ -146,6 +149,11 @@ fail: return; } +static void adsp_loader_do(struct platform_device *pdev) +{ + dev_info(&pdev->dev, "%s: scheduling work to load ADSP fw\n", __func__); + schedule_work(&adsp_ldr_work); +} static ssize_t adsp_boot_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -270,6 +278,8 @@ static int adsp_loader_probe(struct platform_device *pdev) return ret; } + INIT_WORK(&adsp_ldr_work, adsp_load_fw); + return 0; } diff --git a/drivers/soc/qcom/qdsp6v2/cdsp-loader.c b/drivers/soc/qcom/qdsp6v2/cdsp-loader.c index 0b801c5cd7dd..cae26e3913d6 100644 --- a/drivers/soc/qcom/qdsp6v2/cdsp-loader.c +++ b/drivers/soc/qcom/qdsp6v2/cdsp-loader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014,2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,6 +19,8 @@ #include #include #include +#include + #include #define BOOT_CMD 1 @@ -47,11 +49,12 @@ static struct attribute *attrs[] = { static u32 cdsp_state = CDSP_SUBSYS_DOWN; static struct platform_device *cdsp_private; +static struct work_struct cdsp_ldr_work; static void cdsp_loader_unload(struct platform_device *pdev); -static int cdsp_loader_do(struct platform_device *pdev) +static void cdsp_load_fw(struct work_struct *cdsp_ldr_work) { - + struct platform_device *pdev = cdsp_private; struct cdsp_loader_private *priv = NULL; int rc = 0; @@ -101,14 +104,19 @@ static int cdsp_loader_do(struct platform_device *pdev) } dev_dbg(&pdev->dev, "%s: CDSP image is loaded\n", __func__); - return rc; + return; } fail: dev_err(&pdev->dev, "%s: CDSP image loading failed\n", __func__); - return rc; + return; } +static void cdsp_loader_do(struct platform_device *pdev) +{ + dev_info(&pdev->dev, "%s: scheduling work to load CDSP fw\n", __func__); + schedule_work(&cdsp_ldr_work); +} static ssize_t cdsp_boot_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -126,7 +134,7 @@ static ssize_t cdsp_boot_store(struct kobject *kobj, pr_debug("%s: going to call cdsp_loader_do\n", __func__); cdsp_loader_do(cdsp_private); } else if (boot == IMAGE_UNLOAD_CMD) { - pr_debug("%s: going to call adsp_unloader\n", __func__); + pr_debug("%s: going to call cdsp_unloader\n", __func__); cdsp_loader_unload(cdsp_private); } return count; @@ -238,6 +246,8 @@ static int cdsp_loader_probe(struct platform_device *pdev) return ret; } + INIT_WORK(&cdsp_ldr_work, cdsp_load_fw); + return 0; }