Merge "msm: adsp-loader: Add support for adsp state in adsp loader"
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 1e647a7..213da90 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -474,3 +474,22 @@
"MIC BIAS4 External", "Digital Mic6";
qcom,taiko-mclk-clk-freq = <12288000>;
};
+
+* msm-adsp-loader
+
+Required properties:
+ - compatible : "msm-adsp-loader"
+ - qcom,adsp-state:
+ It is possible that some MSM use PIL to load the ADSP image. While
+ other MSM may use SBL to load the ADSP image at boot. Audio APR needs
+ state of ADSP to register and enable APR to be used for sending commands
+ to ADSP. so adsp-state represents the state of ADSP to ADSP loader. Value
+ of 0 indicates ADSP loader needs to use PIL and value of 2 means ADSP
+ image is already loaded by SBL.
+
+Example:
+
+qcom,msm-adsp-loader {
+ compatible = "qcom,adsp-loader";
+ qcom,adsp-state = <2>;
+};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 4618ca2..1bad657 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -809,6 +809,7 @@
qcom,msm-adsp-loader {
compatible = "qcom,adsp-loader";
+ qcom,adsp-state = <0>;
};
qcom,msm-pcm {
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 6e4d9e6..09c388f 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -393,6 +393,7 @@
qcom,msm-adsp-loader {
compatible = "qcom,adsp-loader";
+ qcom,adsp-state = <2>;
};
qcom,msm-pcm {
diff --git a/arch/arm/mach-msm/qdsp6v2/adsp-loader.c b/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
index c28e403..02dbece 100644
--- a/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
+++ b/arch/arm/mach-msm/qdsp6v2/adsp-loader.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <mach/subsystem_restart.h>
#include <mach/qdsp6v2/apr.h>
+#include <linux/of_device.h>
#define Q6_PIL_GET_DELAY_MS 100
@@ -30,25 +31,41 @@
{
struct adsp_loader_private *priv;
int rc = 0;
+ const char *adsp_dt = "qcom,adsp-state";
+ u32 adsp_state;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, priv);
-
- priv->pil_h = subsystem_get("adsp");
- if (IS_ERR(priv->pil_h)) {
- pr_err("%s: pil get adsp failed, error:%d\n", __func__, rc);
- devm_kfree(&pdev->dev, priv);
- goto fail;
+ rc = of_property_read_u32(pdev->dev.of_node, adsp_dt, &adsp_state);
+ if (rc) {
+ dev_err(&pdev->dev,
+ "%s: ADSP state = %x\n", __func__, adsp_state);
+ return rc;
}
- /* Query the DSP to check if resources are available */
- msleep(Q6_PIL_GET_DELAY_MS);
+ if (adsp_state == APR_SUBSYS_DOWN) {
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
- /* Set the state of the ADSP in APR driver */
- apr_set_q6_state(APR_SUBSYS_LOADED);
+ platform_set_drvdata(pdev, priv);
+
+ priv->pil_h = subsystem_get("adsp");
+ if (IS_ERR(priv->pil_h)) {
+ pr_err("%s: pil get adsp failed, error:%d\n",
+ __func__, rc);
+ devm_kfree(&pdev->dev, priv);
+ goto fail;
+ }
+
+ /* Query the DSP to check if resources are available */
+ msleep(Q6_PIL_GET_DELAY_MS);
+
+ /* Set the state of the ADSP in APR driver */
+ apr_set_q6_state(APR_SUBSYS_LOADED);
+ } else if (adsp_state == APR_SUBSYS_LOADED) {
+ dev_dbg(&pdev->dev,
+ "%s:MDM9x25 ADSP state = %x\n", __func__, adsp_state);
+ apr_set_q6_state(APR_SUBSYS_LOADED);
+ }
/* Query for MMPM API */
@@ -62,7 +79,8 @@
struct adsp_loader_private *priv;
priv = platform_get_drvdata(pdev);
- subsystem_put(priv->pil_h);
+ if (priv != NULL)
+ subsystem_put(priv->pil_h);
pr_info("%s: Q6/ADSP image is unloaded\n", __func__);
return 0;