ASoC: Intel: Add helper to poll register for DSP status
authorSubhransu S. Prusty <subhransu.s.prusty@intel.com>
Thu, 9 Jul 2015 16:08:52 +0000 (21:38 +0530)
committerMark Brown <broonie@kernel.org>
Thu, 9 Jul 2015 17:33:23 +0000 (18:33 +0100)
This patch adds helper to poll register for DSP status.

Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
Signed-off-by: Kp, Jeeja <jeeja.kp@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/common/sst-dsp.c
sound/soc/intel/common/sst-dsp.h

index 64e9421..cc25f4c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 
 #include "sst-dsp.h"
 #include "sst-dsp-priv.h"
@@ -222,6 +223,48 @@ int sst_dsp_shim_update_bits64(struct sst_dsp *sst, u32 offset,
 }
 EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits64);
 
+int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask,
+                        u32 target, u32 timeout, char *operation)
+{
+       int time, ret;
+       u32 reg;
+       bool done = false;
+
+       /*
+        * we will poll for couple of ms using mdelay, if not successful
+        * then go to longer sleep using usleep_range
+        */
+
+       /* check if set state successful */
+       for (time = 0; time < 5; time++) {
+               if ((sst_dsp_shim_read_unlocked(ctx, offset) & mask) == target) {
+                       done = true;
+                       break;
+               }
+               mdelay(1);
+       }
+
+       if (done ==  false) {
+               /* sleeping in 10ms steps so adjust timeout value */
+               timeout /= 10;
+
+               for (time = 0; time < timeout; time++) {
+                       if ((sst_dsp_shim_read_unlocked(ctx, offset) & mask) == target)
+                               break;
+
+                       usleep_range(5000, 10000);
+               }
+       }
+
+       reg = sst_dsp_shim_read_unlocked(ctx, offset);
+       dev_info(ctx->dev, "FW Poll Status: reg=%#x %s %s\n", reg, operation,
+                       (time < timeout) ? "successful" : "timedout");
+       ret = time < timeout ? 0 : -ETIME;
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(sst_dsp_register_poll);
+
 void sst_dsp_dump(struct sst_dsp *sst)
 {
        if (sst->ops->dump)
index 96aeb25..cc3197b 100644 (file)
@@ -278,6 +278,8 @@ void sst_dsp_inbox_read(struct sst_dsp *dsp, void *message, size_t bytes);
 void sst_dsp_outbox_write(struct sst_dsp *dsp, void *message, size_t bytes);
 void sst_dsp_outbox_read(struct sst_dsp *dsp, void *message, size_t bytes);
 void sst_dsp_mailbox_dump(struct sst_dsp *dsp, size_t bytes);
+int sst_dsp_register_poll(struct sst_dsp  *dsp, u32 offset, u32 mask,
+                u32 expected_value, u32 timeout, char *operation);
 
 /* Debug */
 void sst_dsp_dump(struct sst_dsp *sst);