summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel
diff options
context:
space:
mode:
authorJeeja KP <jeeja.kp@intel.com>2017-01-02 09:50:02 +0530
committerMark Brown <broonie@kernel.org>2017-01-06 18:14:45 +0000
commit9cc8f9fe0f9e84771f2872f8939d37414ef9d58d (patch)
tree7c95de171e383b36954737f39cb79a43c8962624 /sound/soc/intel
parenteee0e16f8c3cf31fbbae4a88e51d25abebbaf147 (diff)
downloadop-kernel-dev-9cc8f9fe0f9e84771f2872f8939d37414ef9d58d.zip
op-kernel-dev-9cc8f9fe0f9e84771f2872f8939d37414ef9d58d.tar.gz
ASoC: Intel: Common: Update dsp register poll implementation
Poll implementation is not quite accurate, especially for smaller values of timeout or timeout values close to the actual timeout needed Use jiffies to set the timeout value and time_before() to get the accurate time. So update the dsp register poll implementation to provide accurate timeout using jiffies. Signed-off-by: Jayachandran B <jayachandran.b@intel.com> Signed-off-by: Jeeja KP <jeeja.kp@intel.com> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel')
-rw-r--r--sound/soc/intel/common/sst-dsp.c52
1 files changed, 26 insertions, 26 deletions
diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
index c00ede4..11c0805 100644
--- a/sound/soc/intel/common/sst-dsp.c
+++ b/sound/soc/intel/common/sst-dsp.c
@@ -252,44 +252,44 @@ void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset,
EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_forced);
int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask,
- u32 target, u32 timeout, char *operation)
+ u32 target, u32 time, char *operation)
{
- int time, ret;
u32 reg;
- bool done = false;
+ unsigned long timeout;
+ int k = 0, s = 500;
/*
- * we will poll for couple of ms using mdelay, if not successful
- * then go to longer sleep using usleep_range
+ * split the loop into sleeps of varying resolution. more accurately,
+ * the range of wakeups are:
+ * Phase 1(first 5ms): min sleep 0.5ms; max sleep 1ms.
+ * Phase 2:( 5ms to 10ms) : min sleep 0.5ms; max sleep 10ms
+ * (usleep_range (500, 1000) and usleep_range(5000, 10000) are
+ * both possible in this phase depending on whether k > 10 or not).
+ * Phase 3: (beyond 10 ms) min sleep 5ms; max sleep 10ms.
*/
- /* 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);
+ timeout = jiffies + msecs_to_jiffies(time);
+ while (((sst_dsp_shim_read_unlocked(ctx, offset) & mask) != target)
+ && time_before(jiffies, timeout)) {
+ k++;
+ if (k > 10)
+ s = 5000;
+
+ usleep_range(s, 2*s);
}
- if (done == false) {
- /* sleeping in 10ms steps so adjust timeout value */
- timeout /= 10;
+ reg = sst_dsp_shim_read_unlocked(ctx, offset);
- for (time = 0; time < timeout; time++) {
- if ((sst_dsp_shim_read_unlocked(ctx, offset) & mask) == target)
- break;
+ if ((reg & mask) == target) {
+ dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s successful\n",
+ reg, operation);
- usleep_range(5000, 10000);
- }
+ return 0;
}
- reg = sst_dsp_shim_read_unlocked(ctx, offset);
- dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s %s\n", reg, operation,
- (time < timeout) ? "successful" : "timedout");
- ret = time < timeout ? 0 : -ETIME;
-
- return ret;
+ dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s timedout\n",
+ reg, operation);
+ return -ETIME;
}
EXPORT_SYMBOL_GPL(sst_dsp_register_poll);
OpenPOWER on IntegriCloud