Commit 9179b73a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'regmap-v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap

Pull regmap updates from Mark Brown:
 "The main update here is Matti's work allowing regmap irqdomains to be
  given custom names (allowing multiple interrupt controllers associatd
  with a single struct device), this pulls in some commits from Thomas'
  tree which it depends on.

  Otherwise there's a bit of work on improving handling of regmaps
  protected with spinlocks when used with complex cache types, fixing
  some valid but harmless lockdep reports seen with some new driver
  work"

* tag 'regmap-v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
  regmap: kunit: Add coverage of spinlocked regmaps
  regcache: use map->alloc_flags also for allocating cache
  regmap: Use locking during kunit tests
  regmap: Hold the regmap lock when allocating and freeing the cache
  regmap: Allow setting IRQ domain name suffix
parents c903327d c7edb7ac
...@@ -27,7 +27,7 @@ static int regcache_flat_init(struct regmap *map) ...@@ -27,7 +27,7 @@ static int regcache_flat_init(struct regmap *map)
return -EINVAL; return -EINVAL;
map->cache = kcalloc(regcache_flat_get_index(map, map->max_register) map->cache = kcalloc(regcache_flat_get_index(map, map->max_register)
+ 1, sizeof(unsigned int), GFP_KERNEL); + 1, sizeof(unsigned int), map->alloc_flags);
if (!map->cache) if (!map->cache)
return -ENOMEM; return -ENOMEM;
......
...@@ -348,7 +348,7 @@ static int regcache_maple_init(struct regmap *map) ...@@ -348,7 +348,7 @@ static int regcache_maple_init(struct regmap *map)
int ret; int ret;
int range_start; int range_start;
mt = kmalloc(sizeof(*mt), GFP_KERNEL); mt = kmalloc(sizeof(*mt), map->alloc_flags);
if (!mt) if (!mt)
return -ENOMEM; return -ENOMEM;
map->cache = mt; map->cache = mt;
......
...@@ -187,7 +187,7 @@ static int regcache_rbtree_init(struct regmap *map) ...@@ -187,7 +187,7 @@ static int regcache_rbtree_init(struct regmap *map)
int i; int i;
int ret; int ret;
map->cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL); map->cache = kmalloc(sizeof *rbtree_ctx, map->alloc_flags);
if (!map->cache) if (!map->cache)
return -ENOMEM; return -ENOMEM;
......
...@@ -195,7 +195,9 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) ...@@ -195,7 +195,9 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
if (map->cache_ops->init) { if (map->cache_ops->init) {
dev_dbg(map->dev, "Initializing %s cache\n", dev_dbg(map->dev, "Initializing %s cache\n",
map->cache_ops->name); map->cache_ops->name);
map->lock(map->lock_arg);
ret = map->cache_ops->init(map); ret = map->cache_ops->init(map);
map->unlock(map->lock_arg);
if (ret) if (ret)
goto err_free; goto err_free;
} }
...@@ -223,7 +225,9 @@ void regcache_exit(struct regmap *map) ...@@ -223,7 +225,9 @@ void regcache_exit(struct regmap *map)
if (map->cache_ops->exit) { if (map->cache_ops->exit) {
dev_dbg(map->dev, "Destroying %s cache\n", dev_dbg(map->dev, "Destroying %s cache\n",
map->cache_ops->name); map->cache_ops->name);
map->lock(map->lock_arg);
map->cache_ops->exit(map); map->cache_ops->exit(map);
map->unlock(map->lock_arg);
} }
} }
......
...@@ -608,6 +608,30 @@ int regmap_irq_set_type_config_simple(unsigned int **buf, unsigned int type, ...@@ -608,6 +608,30 @@ int regmap_irq_set_type_config_simple(unsigned int **buf, unsigned int type,
} }
EXPORT_SYMBOL_GPL(regmap_irq_set_type_config_simple); EXPORT_SYMBOL_GPL(regmap_irq_set_type_config_simple);
static int regmap_irq_create_domain(struct fwnode_handle *fwnode, int irq_base,
const struct regmap_irq_chip *chip,
struct regmap_irq_chip_data *d)
{
struct irq_domain_info info = {
.fwnode = fwnode,
.size = chip->num_irqs,
.hwirq_max = chip->num_irqs,
.virq_base = irq_base,
.ops = &regmap_domain_ops,
.host_data = d,
.name_suffix = chip->domain_suffix,
};
d->domain = irq_domain_instantiate(&info);
if (IS_ERR(d->domain)) {
dev_err(d->map->dev, "Failed to create IRQ domain\n");
return PTR_ERR(d->domain);
}
return 0;
}
/** /**
* regmap_add_irq_chip_fwnode() - Use standard regmap IRQ controller handling * regmap_add_irq_chip_fwnode() - Use standard regmap IRQ controller handling
* *
...@@ -856,18 +880,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, ...@@ -856,18 +880,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
} }
} }
if (irq_base) ret = regmap_irq_create_domain(fwnode, irq_base, chip, d);
d->domain = irq_domain_create_legacy(fwnode, chip->num_irqs, if (ret)
irq_base, 0,
&regmap_domain_ops, d);
else
d->domain = irq_domain_create_linear(fwnode, chip->num_irqs,
&regmap_domain_ops, d);
if (!d->domain) {
dev_err(map->dev, "Failed to create IRQ domain\n");
ret = -ENOMEM;
goto err_alloc; goto err_alloc;
}
ret = request_threaded_irq(irq, NULL, regmap_irq_thread, ret = request_threaded_irq(irq, NULL, regmap_irq_thread,
irq_flags | IRQF_ONESHOT, irq_flags | IRQF_ONESHOT,
......
...@@ -22,6 +22,7 @@ struct regmap_test_param { ...@@ -22,6 +22,7 @@ struct regmap_test_param {
enum regmap_endian val_endian; enum regmap_endian val_endian;
unsigned int from_reg; unsigned int from_reg;
bool fast_io;
}; };
static void get_changed_bytes(void *orig, void *new, size_t size) static void get_changed_bytes(void *orig, void *new, size_t size)
...@@ -80,41 +81,52 @@ static const char *regmap_endian_name(enum regmap_endian endian) ...@@ -80,41 +81,52 @@ static const char *regmap_endian_name(enum regmap_endian endian)
static void param_to_desc(const struct regmap_test_param *param, char *desc) static void param_to_desc(const struct regmap_test_param *param, char *desc)
{ {
snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s-%s @%#x", snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s-%s%s @%#x",
regcache_type_name(param->cache), regcache_type_name(param->cache),
regmap_endian_name(param->val_endian), regmap_endian_name(param->val_endian),
param->fast_io ? " fast I/O" : "",
param->from_reg); param->from_reg);
} }
static const struct regmap_test_param regcache_types_list[] = { static const struct regmap_test_param regcache_types_list[] = {
{ .cache = REGCACHE_NONE }, { .cache = REGCACHE_NONE },
{ .cache = REGCACHE_NONE, .fast_io = true },
{ .cache = REGCACHE_FLAT }, { .cache = REGCACHE_FLAT },
{ .cache = REGCACHE_FLAT, .fast_io = true },
{ .cache = REGCACHE_RBTREE }, { .cache = REGCACHE_RBTREE },
{ .cache = REGCACHE_RBTREE, .fast_io = true },
{ .cache = REGCACHE_MAPLE }, { .cache = REGCACHE_MAPLE },
{ .cache = REGCACHE_MAPLE, .fast_io = true },
}; };
KUNIT_ARRAY_PARAM(regcache_types, regcache_types_list, param_to_desc); KUNIT_ARRAY_PARAM(regcache_types, regcache_types_list, param_to_desc);
static const struct regmap_test_param real_cache_types_only_list[] = { static const struct regmap_test_param real_cache_types_only_list[] = {
{ .cache = REGCACHE_FLAT }, { .cache = REGCACHE_FLAT },
{ .cache = REGCACHE_FLAT, .fast_io = true },
{ .cache = REGCACHE_RBTREE }, { .cache = REGCACHE_RBTREE },
{ .cache = REGCACHE_RBTREE, .fast_io = true },
{ .cache = REGCACHE_MAPLE }, { .cache = REGCACHE_MAPLE },
{ .cache = REGCACHE_MAPLE, .fast_io = true },
}; };
KUNIT_ARRAY_PARAM(real_cache_types_only, real_cache_types_only_list, param_to_desc); KUNIT_ARRAY_PARAM(real_cache_types_only, real_cache_types_only_list, param_to_desc);
static const struct regmap_test_param real_cache_types_list[] = { static const struct regmap_test_param real_cache_types_list[] = {
{ .cache = REGCACHE_FLAT, .from_reg = 0 }, { .cache = REGCACHE_FLAT, .from_reg = 0 },
{ .cache = REGCACHE_FLAT, .from_reg = 0, .fast_io = true },
{ .cache = REGCACHE_FLAT, .from_reg = 0x2001 }, { .cache = REGCACHE_FLAT, .from_reg = 0x2001 },
{ .cache = REGCACHE_FLAT, .from_reg = 0x2002 }, { .cache = REGCACHE_FLAT, .from_reg = 0x2002 },
{ .cache = REGCACHE_FLAT, .from_reg = 0x2003 }, { .cache = REGCACHE_FLAT, .from_reg = 0x2003 },
{ .cache = REGCACHE_FLAT, .from_reg = 0x2004 }, { .cache = REGCACHE_FLAT, .from_reg = 0x2004 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0 }, { .cache = REGCACHE_RBTREE, .from_reg = 0 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0, .fast_io = true },
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2001 }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2001 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2002 }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2002 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2003 }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2003 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2004 }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2004 },
{ .cache = REGCACHE_MAPLE, .from_reg = 0 }, { .cache = REGCACHE_MAPLE, .from_reg = 0 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0, .fast_io = true },
{ .cache = REGCACHE_MAPLE, .from_reg = 0x2001 }, { .cache = REGCACHE_MAPLE, .from_reg = 0x2001 },
{ .cache = REGCACHE_MAPLE, .from_reg = 0x2002 }, { .cache = REGCACHE_MAPLE, .from_reg = 0x2002 },
{ .cache = REGCACHE_MAPLE, .from_reg = 0x2003 }, { .cache = REGCACHE_MAPLE, .from_reg = 0x2003 },
...@@ -125,11 +137,13 @@ KUNIT_ARRAY_PARAM(real_cache_types, real_cache_types_list, param_to_desc); ...@@ -125,11 +137,13 @@ KUNIT_ARRAY_PARAM(real_cache_types, real_cache_types_list, param_to_desc);
static const struct regmap_test_param sparse_cache_types_list[] = { static const struct regmap_test_param sparse_cache_types_list[] = {
{ .cache = REGCACHE_RBTREE, .from_reg = 0 }, { .cache = REGCACHE_RBTREE, .from_reg = 0 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0, .fast_io = true },
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2001 }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2001 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2002 }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2002 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2003 }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2003 },
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2004 }, { .cache = REGCACHE_RBTREE, .from_reg = 0x2004 },
{ .cache = REGCACHE_MAPLE, .from_reg = 0 }, { .cache = REGCACHE_MAPLE, .from_reg = 0 },
{ .cache = REGCACHE_MAPLE, .from_reg = 0, .fast_io = true },
{ .cache = REGCACHE_MAPLE, .from_reg = 0x2001 }, { .cache = REGCACHE_MAPLE, .from_reg = 0x2001 },
{ .cache = REGCACHE_MAPLE, .from_reg = 0x2002 }, { .cache = REGCACHE_MAPLE, .from_reg = 0x2002 },
{ .cache = REGCACHE_MAPLE, .from_reg = 0x2003 }, { .cache = REGCACHE_MAPLE, .from_reg = 0x2003 },
...@@ -151,8 +165,7 @@ static struct regmap *gen_regmap(struct kunit *test, ...@@ -151,8 +165,7 @@ static struct regmap *gen_regmap(struct kunit *test,
struct reg_default *defaults; struct reg_default *defaults;
config->cache_type = param->cache; config->cache_type = param->cache;
config->disable_locking = config->cache_type == REGCACHE_RBTREE || config->fast_io = param->fast_io;
config->cache_type == REGCACHE_MAPLE;
if (config->max_register == 0) { if (config->max_register == 0) {
config->max_register = param->from_reg; config->max_register = param->from_reg;
......
...@@ -1445,6 +1445,7 @@ void regmap_exit(struct regmap *map) ...@@ -1445,6 +1445,7 @@ void regmap_exit(struct regmap *map)
struct regmap_async *async; struct regmap_async *async;
regcache_exit(map); regcache_exit(map);
regmap_debugfs_exit(map); regmap_debugfs_exit(map);
regmap_range_exit(map); regmap_range_exit(map);
if (map->bus && map->bus->free_context) if (map->bus && map->bus->free_context)
......
...@@ -1521,6 +1521,9 @@ struct regmap_irq_chip_data; ...@@ -1521,6 +1521,9 @@ struct regmap_irq_chip_data;
* struct regmap_irq_chip - Description of a generic regmap irq_chip. * struct regmap_irq_chip - Description of a generic regmap irq_chip.
* *
* @name: Descriptive name for IRQ controller. * @name: Descriptive name for IRQ controller.
* @domain_suffix: Name suffix to be appended to end of IRQ domain name. Needed
* when multiple regmap-IRQ controllers are created from same
* device.
* *
* @main_status: Base main status register address. For chips which have * @main_status: Base main status register address. For chips which have
* interrupts arranged in separate sub-irq blocks with own IRQ * interrupts arranged in separate sub-irq blocks with own IRQ
...@@ -1606,6 +1609,7 @@ struct regmap_irq_chip_data; ...@@ -1606,6 +1609,7 @@ struct regmap_irq_chip_data;
*/ */
struct regmap_irq_chip { struct regmap_irq_chip {
const char *name; const char *name;
const char *domain_suffix;
unsigned int main_status; unsigned int main_status;
unsigned int num_main_status_bits; unsigned int num_main_status_bits;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment