Skip to content

Commit d287801

Browse files
committed
Merge series "Use raw spinlocks in the ls-extirq driver" from Vladimir Oltean <[email protected]>:
The ls-extirq irqchip driver accesses regmap inside its implementation of the struct irq_chip :: irq_set_type method, and currently regmap only knows to lock using normal spinlocks. But the method above wants raw spinlock context, so this isn't going to work and triggers a "[ BUG: Invalid wait context ]" splat. The best we can do given the arrangement of the code is to patch regmap and the syscon driver: regmap to support raw spinlocks, and syscon to request them on behalf of its ls-extirq consumer. Link: https://lore.kernel.org/lkml/20210825135438.ubcuxm5vctt6ne2q@skbuf/T/#u Vladimir Oltean (2): regmap: teach regmap to use raw spinlocks if requested in the config mfd: syscon: request a regmap with raw spinlocks for some devices drivers/base/regmap/internal.h | 4 ++++ drivers/base/regmap/regmap.c | 35 +++++++++++++++++++++++++++++----- drivers/mfd/syscon.c | 16 ++++++++++++++++ include/linux/regmap.h | 2 ++ 4 files changed, 52 insertions(+), 5 deletions(-) -- 2.25.1 base-commit: 6efb943
2 parents 29c3497 + 67021f2 commit d287801

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

drivers/base/regmap/internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ struct regmap {
5353
spinlock_t spinlock;
5454
unsigned long spinlock_flags;
5555
};
56+
struct {
57+
raw_spinlock_t raw_spinlock;
58+
unsigned long raw_spinlock_flags;
59+
};
5660
};
5761
regmap_lock lock;
5862
regmap_unlock unlock;

drivers/base/regmap/regmap.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,23 @@ __releases(&map->spinlock)
533533
spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags);
534534
}
535535

536+
static void regmap_lock_raw_spinlock(void *__map)
537+
__acquires(&map->raw_spinlock)
538+
{
539+
struct regmap *map = __map;
540+
unsigned long flags;
541+
542+
raw_spin_lock_irqsave(&map->raw_spinlock, flags);
543+
map->raw_spinlock_flags = flags;
544+
}
545+
546+
static void regmap_unlock_raw_spinlock(void *__map)
547+
__releases(&map->raw_spinlock)
548+
{
549+
struct regmap *map = __map;
550+
raw_spin_unlock_irqrestore(&map->raw_spinlock, map->raw_spinlock_flags);
551+
}
552+
536553
static void dev_get_regmap_release(struct device *dev, void *res)
537554
{
538555
/*
@@ -770,11 +787,19 @@ struct regmap *__regmap_init(struct device *dev,
770787
} else {
771788
if ((bus && bus->fast_io) ||
772789
config->fast_io) {
773-
spin_lock_init(&map->spinlock);
774-
map->lock = regmap_lock_spinlock;
775-
map->unlock = regmap_unlock_spinlock;
776-
lockdep_set_class_and_name(&map->spinlock,
777-
lock_key, lock_name);
790+
if (config->use_raw_spinlock) {
791+
raw_spin_lock_init(&map->raw_spinlock);
792+
map->lock = regmap_lock_raw_spinlock;
793+
map->unlock = regmap_unlock_raw_spinlock;
794+
lockdep_set_class_and_name(&map->raw_spinlock,
795+
lock_key, lock_name);
796+
} else {
797+
spin_lock_init(&map->spinlock);
798+
map->lock = regmap_lock_spinlock;
799+
map->unlock = regmap_unlock_spinlock;
800+
lockdep_set_class_and_name(&map->spinlock,
801+
lock_key, lock_name);
802+
}
778803
} else {
779804
mutex_init(&map->mutex);
780805
map->lock = regmap_lock_mutex;

include/linux/regmap.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ typedef void (*regmap_unlock)(void *);
344344
* @ranges: Array of configuration entries for virtual address ranges.
345345
* @num_ranges: Number of range configuration entries.
346346
* @use_hwlock: Indicate if a hardware spinlock should be used.
347+
* @use_raw_spinlock: Indicate if a raw spinlock should be used.
347348
* @hwlock_id: Specify the hardware spinlock id.
348349
* @hwlock_mode: The hardware spinlock mode, should be HWLOCK_IRQSTATE,
349350
* HWLOCK_IRQ or 0.
@@ -403,6 +404,7 @@ struct regmap_config {
403404
unsigned int num_ranges;
404405

405406
bool use_hwlock;
407+
bool use_raw_spinlock;
406408
unsigned int hwlock_id;
407409
unsigned int hwlock_mode;
408410

0 commit comments

Comments
 (0)