aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/wm5102-tables.c
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.wolfsonmicro.com>2014-02-25 08:45:52 -0500
committerMark Brown <broonie@linaro.org>2014-02-25 18:58:42 -0500
commit1c18d2ca104c36fc2ce147cce053c62f61d2ea68 (patch)
tree42181eb461f017fbe2177c5334ddc692a102115a /drivers/mfd/wm5102-tables.c
parent6bf13103b2dbf09d32a0da2e732b6196522c1462 (diff)
mfd: arizona: Use new regmap features for manual register patch
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>
Diffstat (limited to 'drivers/mfd/wm5102-tables.c')
-rw-r--r--drivers/mfd/wm5102-tables.c21
1 files changed, 4 insertions, 17 deletions
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 1e9a4b2102f9..bffc584e4a43 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -80,8 +80,7 @@ static const struct reg_default wm5102_revb_patch[] = {
80int wm5102_patch(struct arizona *arizona) 80int wm5102_patch(struct arizona *arizona)
81{ 81{
82 const struct reg_default *wm5102_patch; 82 const struct reg_default *wm5102_patch;
83 int ret = 0; 83 int patch_size;
84 int i, patch_size;
85 84
86 switch (arizona->rev) { 85 switch (arizona->rev) {
87 case 0: 86 case 0:
@@ -92,21 +91,9 @@ int wm5102_patch(struct arizona *arizona)
92 patch_size = ARRAY_SIZE(wm5102_revb_patch); 91 patch_size = ARRAY_SIZE(wm5102_revb_patch);
93 } 92 }
94 93
95 regcache_cache_bypass(arizona->regmap, true); 94 return regmap_multi_reg_write_bypassed(arizona->regmap,
96 95 wm5102_patch,
97 for (i = 0; i < patch_size; i++) { 96 patch_size);
98 ret = regmap_write(arizona->regmap, wm5102_patch[i].reg,
99 wm5102_patch[i].def);
100 if (ret != 0) {
101 dev_err(arizona->dev, "Failed to write %x = %x: %d\n",
102 wm5102_patch[i].reg, wm5102_patch[i].def, ret);
103 goto out;
104 }
105 }
106
107out:
108 regcache_cache_bypass(arizona->regmap, false);
109 return ret;
110} 97}
111 98
112static const struct regmap_irq wm5102_aod_irqs[ARIZONA_NUM_IRQ] = { 99static const struct regmap_irq wm5102_aod_irqs[ARIZONA_NUM_IRQ] = {