aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/regmap/regmap.c
diff options
context:
space:
mode:
authorDmitry Osipenko <digetx@gmail.com>2020-09-02 17:18:43 +0300
committerMark Brown <broonie@kernel.org>2020-09-02 19:53:27 +0100
commit21f8e4828c44da39b0670c5d99d5728b739542a1 (patch)
treea9343b0f35521b63cb1c37dcc7e938957af4f1f2 /drivers/base/regmap/regmap.c
parentMerge series "Introduce Embedded Controller driver for Acer A500" from Dmitry Osipenko <digetx@gmail.com>: (diff)
downloadlinux-dev-21f8e4828c44da39b0670c5d99d5728b739542a1.tar.xz
linux-dev-21f8e4828c44da39b0670c5d99d5728b739542a1.zip
regmap: Add can_sleep configuration option
Regmap can't sleep if spinlock is used for the locking protection. This patch fixes regression caused by a previous commit that switched regmap to use fsleep() and this broke Amlogic S922X platform. This patch adds new configuration option for regmap users, allowing to specify whether regmap operations can sleep and assuming that sleep is allowed if mutex is used for the regmap locking protection. Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Fixes: 2b32d2f7ce0a ("regmap: Use flexible sleep") Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Link: https://lore.kernel.org/r/20200902141843.6591-1-digetx@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to '')
-rw-r--r--drivers/base/regmap/regmap.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a417cb1a11dc..2807e544658e 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -697,11 +697,13 @@ struct regmap *__regmap_init(struct device *dev,
if (config->disable_locking) {
map->lock = map->unlock = regmap_lock_unlock_none;
+ map->can_sleep = config->can_sleep;
regmap_debugfs_disable(map);
} else if (config->lock && config->unlock) {
map->lock = config->lock;
map->unlock = config->unlock;
map->lock_arg = config->lock_arg;
+ map->can_sleep = config->can_sleep;
} else if (config->use_hwlock) {
map->hwlock = hwspin_lock_request_specific(config->hwlock_id);
if (!map->hwlock) {
@@ -737,6 +739,7 @@ struct regmap *__regmap_init(struct device *dev,
mutex_init(&map->mutex);
map->lock = regmap_lock_mutex;
map->unlock = regmap_unlock_mutex;
+ map->can_sleep = true;
lockdep_set_class_and_name(&map->mutex,
lock_key, lock_name);
}
@@ -2230,8 +2233,12 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
if (ret != 0)
return ret;
- if (regs[i].delay_us)
- fsleep(regs[i].delay_us);
+ if (regs[i].delay_us) {
+ if (map->can_sleep)
+ fsleep(regs[i].delay_us);
+ else
+ udelay(regs[i].delay_us);
+ }
base += n;
n = 0;
@@ -2267,8 +2274,12 @@ static int _regmap_multi_reg_write(struct regmap *map,
if (ret != 0)
return ret;
- if (regs[i].delay_us)
- fsleep(regs[i].delay_us);
+ if (regs[i].delay_us) {
+ if (map->can_sleep)
+ fsleep(regs[i].delay_us);
+ else
+ udelay(regs[i].delay_us);
+ }
}
return 0;
}