summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Krummenacher <max.krummenacher@toradex.com>2020-01-06 21:17:41 +0100
committerMax Krummenacher <max.krummenacher@toradex.com>2020-01-09 18:13:16 +0100
commitae8e1117ab0c6d78436d553552c243e56b73a805 (patch)
tree0da897cf2bbf71ceca928973e81f93e158178d23
parentfff496c2a1bd08bb4987232c9f3f4b6704bd3146 (diff)
fsl_dsp.c: test for dsp existence before installing driver
The DSP is an optional silicon feature of i.MX8, i.MX8X SoCs. This prevents the following message which is often followed by a kernel oops. | Failed power operation on resource 512 sc_err 3, power_on 1 Test the DSP disable fuse in the drivers init call and don't install the driver if the SoC we are running on has no DSP. Fuse code taken from vpu_encoder_b0.c. Related-to: ELB-1380 Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com>
-rw-r--r--sound/soc/fsl/fsl_dsp.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/sound/soc/fsl/fsl_dsp.c b/sound/soc/fsl/fsl_dsp.c
index 3573384..4bd5505 100644
--- a/sound/soc/fsl/fsl_dsp.c
+++ b/sound/soc/fsl/fsl_dsp.c
@@ -71,6 +71,46 @@
#include "fsl_dsp_pool.h"
#include "fsl_dsp_xaf_api.h"
+#define DSP_DISABLE_FUSE 0x8
+#define DSP_DISABLE_MASK 0x1
+
+static int check_dsp_is_available(void)
+{
+ sc_ipc_t mu_ipc;
+ sc_ipc_id_t mu_id;
+ uint32_t fuse = 0xffff;
+ int ret;
+
+ ret = sc_ipc_getMuID(&mu_id);
+ if (ret) {
+ pr_err("sc_ipc_getMuID() can't obtain mu id SCI! %d\n",
+ ret);
+ return -EINVAL;
+ }
+
+ ret = sc_ipc_open(&mu_ipc, mu_id);
+ if (ret) {
+ pr_err("sc_ipc_getMuID() can't open MU channel to SCU! %d\n",
+ ret);
+ return -EINVAL;
+ }
+
+ ret = sc_misc_otp_fuse_read(mu_ipc, DSP_DISABLE_FUSE, &fuse);
+ sc_ipc_close(mu_ipc);
+ if (ret) {
+ pr_err("sc_misc_otp_fuse_read fail! %d\n", ret);
+ return -EINVAL;
+ }
+
+ pr_debug("mu_id = %d, fuse[%i] = 0x%x\n", mu_id, DSP_DISABLE_FUSE, fuse);
+ if (fuse & DSP_DISABLE_MASK) {
+ pr_info("%s: HiFi4 DSP not available on this silicon\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/* ...allocate new client */
struct xf_client *xf_client_alloc(struct fsl_dsp *dsp_priv)
{
@@ -1159,7 +1199,22 @@ static struct platform_driver fsl_dsp_driver = {
.pm = &fsl_dsp_pm,
},
};
-module_platform_driver(fsl_dsp_driver);
+
+static int __init fsl_dsp_driver_init(void)
+{
+ /* do not install the driver if no DSP is found */
+ if (check_dsp_is_available())
+ return -EINVAL;
+
+ return platform_driver_register(&fsl_dsp_driver);
+}
+module_init(fsl_dsp_driver_init);
+
+static void __exit fsl_dsp_driver_exit(void)
+{
+ platform_driver_unregister(&fsl_dsp_driver);
+}
+module_exit(fsl_dsp_driver_exit);
MODULE_DESCRIPTION("Freescale DSP driver");
MODULE_ALIAS("platform:fsl-dsp");