mfd: arizona: Use new regmap features for manual register patch
authorCharles Keepax <ckeepax@opensource.wolfsonmicro.com>
Tue, 25 Feb 2014 13:45:52 +0000 (13:45 +0000)
committerMark Brown <broonie@linaro.org>
Tue, 25 Feb 2014 23:58:42 +0000 (08:58 +0900)
On the wm5102 the register patches are applied manually, rather than by
the regmap core. This application is wrapped in calls to
regcache_cache_bypass. However, this is dangerous as other threads may
be accessing the hardware at the same time as the pm_runtime operations
and if they do so during the period whilst cache_bypass is enabled those
writes will miss the cache when they shouldn't.

Apply the register patch using the new regmap_multi_reg_write_bypassed
function to avoid this problem. Also remove the call to
regcache_cache_bypass from the hardware patch application as it is
unneeded there and creates a similar window for writes to miss the
cache.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
drivers/mfd/arizona-core.c
drivers/mfd/wm5102-tables.c

index a45aab9f6bb135e64c0f0a420f75ed2508e17e92..1c3ae57082ed7bc1a2dcd8583a507875f3b7d92b 100644 (file)
@@ -251,8 +251,6 @@ static int arizona_apply_hardware_patch(struct arizona* arizona)
        unsigned int fll, sysclk;
        int ret, err;
 
-       regcache_cache_bypass(arizona->regmap, true);
-
        /* Cache existing FLL and SYSCLK settings */
        ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &fll);
        if (ret != 0) {
@@ -322,8 +320,6 @@ err_fll:
                        err);
        }
 
-       regcache_cache_bypass(arizona->regmap, false);
-
        if (ret != 0)
                return ret;
        else
index 1e9a4b2102f9d89c9549e3d226cf7ef0c91866ef..bffc584e4a4355f25f565ae6d0aa77244e556238 100644 (file)
@@ -80,8 +80,7 @@ static const struct reg_default wm5102_revb_patch[] = {
 int wm5102_patch(struct arizona *arizona)
 {
        const struct reg_default *wm5102_patch;
-       int ret = 0;
-       int i, patch_size;
+       int patch_size;
 
        switch (arizona->rev) {
        case 0:
@@ -92,21 +91,9 @@ int wm5102_patch(struct arizona *arizona)
                patch_size = ARRAY_SIZE(wm5102_revb_patch);
        }
 
-       regcache_cache_bypass(arizona->regmap, true);
-
-       for (i = 0; i < patch_size; i++) {
-               ret = regmap_write(arizona->regmap, wm5102_patch[i].reg,
-                                  wm5102_patch[i].def);
-               if (ret != 0) {
-                       dev_err(arizona->dev, "Failed to write %x = %x: %d\n",
-                               wm5102_patch[i].reg, wm5102_patch[i].def, ret);
-                       goto out;
-               }
-       }
-
-out:
-       regcache_cache_bypass(arizona->regmap, false);
-       return ret;
+       return regmap_multi_reg_write_bypassed(arizona->regmap,
+                                              wm5102_patch,
+                                              patch_size);
 }
 
 static const struct regmap_irq wm5102_aod_irqs[ARIZONA_NUM_IRQ] = {
This page took 0.027002 seconds and 5 git commands to generate.