mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 03:24:19 +02:00
regmap: Updates for v6.12
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. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmbnZjcACgkQJNaLcl1U h9CFMwf/ecsvvRV4LycfWvm3yehorg+ruV8TXFB/KswXZ957rWfxOYBrSdOoNezy nYb2LZAKWlS10Akk5CinBc/ZjRH1EQmjWCl/l2eKe1gTFQ9xPFGWNg7FlnmRRNKR 9SiBdSCjxXS55nZN7t4jeXCXUr8iaezV+K55rKdznpe/EOi19wHmNtR2+3PqtnuJ felae4Xrq3o+O20yV54KYq1iQNY2jNNFGZUGBYAzQjR8aCuY9lQATT36uTxqspWY icZwUiLCmmoRLTC+QbSnmjv26s/uURpRXR7BUhX40PaK6MuWzNHAjxUo8iYVzuVg Nmqw+5yeDF4tY9pDODrmqxK2fErObw== =TyFs -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
9179b73aa7
|
|
@ -27,7 +27,7 @@ static int regcache_flat_init(struct regmap *map)
|
|||
return -EINVAL;
|
||||
|
||||
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)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ static int regcache_maple_init(struct regmap *map)
|
|||
int ret;
|
||||
int range_start;
|
||||
|
||||
mt = kmalloc(sizeof(*mt), GFP_KERNEL);
|
||||
mt = kmalloc(sizeof(*mt), map->alloc_flags);
|
||||
if (!mt)
|
||||
return -ENOMEM;
|
||||
map->cache = mt;
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ static int regcache_rbtree_init(struct regmap *map)
|
|||
int i;
|
||||
int ret;
|
||||
|
||||
map->cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
|
||||
map->cache = kmalloc(sizeof *rbtree_ctx, map->alloc_flags);
|
||||
if (!map->cache)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -195,7 +195,9 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
|
|||
if (map->cache_ops->init) {
|
||||
dev_dbg(map->dev, "Initializing %s cache\n",
|
||||
map->cache_ops->name);
|
||||
map->lock(map->lock_arg);
|
||||
ret = map->cache_ops->init(map);
|
||||
map->unlock(map->lock_arg);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
}
|
||||
|
|
@ -223,7 +225,9 @@ void regcache_exit(struct regmap *map)
|
|||
if (map->cache_ops->exit) {
|
||||
dev_dbg(map->dev, "Destroying %s cache\n",
|
||||
map->cache_ops->name);
|
||||
map->lock(map->lock_arg);
|
||||
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,
|
|||
}
|
||||
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 = ®map_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
|
||||
*
|
||||
|
|
@ -856,18 +880,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
|
|||
}
|
||||
}
|
||||
|
||||
if (irq_base)
|
||||
d->domain = irq_domain_create_legacy(fwnode, chip->num_irqs,
|
||||
irq_base, 0,
|
||||
®map_domain_ops, d);
|
||||
else
|
||||
d->domain = irq_domain_create_linear(fwnode, chip->num_irqs,
|
||||
®map_domain_ops, d);
|
||||
if (!d->domain) {
|
||||
dev_err(map->dev, "Failed to create IRQ domain\n");
|
||||
ret = -ENOMEM;
|
||||
ret = regmap_irq_create_domain(fwnode, irq_base, chip, d);
|
||||
if (ret)
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
ret = request_threaded_irq(irq, NULL, regmap_irq_thread,
|
||||
irq_flags | IRQF_ONESHOT,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ struct regmap_test_param {
|
|||
enum regmap_endian val_endian;
|
||||
|
||||
unsigned int from_reg;
|
||||
bool fast_io;
|
||||
};
|
||||
|
||||
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)
|
|||
|
||||
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),
|
||||
regmap_endian_name(param->val_endian),
|
||||
param->fast_io ? " fast I/O" : "",
|
||||
param->from_reg);
|
||||
}
|
||||
|
||||
static const struct regmap_test_param regcache_types_list[] = {
|
||||
{ .cache = REGCACHE_NONE },
|
||||
{ .cache = REGCACHE_NONE, .fast_io = true },
|
||||
{ .cache = REGCACHE_FLAT },
|
||||
{ .cache = REGCACHE_FLAT, .fast_io = true },
|
||||
{ .cache = REGCACHE_RBTREE },
|
||||
{ .cache = REGCACHE_RBTREE, .fast_io = true },
|
||||
{ .cache = REGCACHE_MAPLE },
|
||||
{ .cache = REGCACHE_MAPLE, .fast_io = true },
|
||||
};
|
||||
|
||||
KUNIT_ARRAY_PARAM(regcache_types, regcache_types_list, param_to_desc);
|
||||
|
||||
static const struct regmap_test_param real_cache_types_only_list[] = {
|
||||
{ .cache = REGCACHE_FLAT },
|
||||
{ .cache = REGCACHE_FLAT, .fast_io = true },
|
||||
{ .cache = REGCACHE_RBTREE },
|
||||
{ .cache = REGCACHE_RBTREE, .fast_io = true },
|
||||
{ .cache = REGCACHE_MAPLE },
|
||||
{ .cache = REGCACHE_MAPLE, .fast_io = true },
|
||||
};
|
||||
|
||||
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[] = {
|
||||
{ .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 = 0x2002 },
|
||||
{ .cache = REGCACHE_FLAT, .from_reg = 0x2003 },
|
||||
{ .cache = REGCACHE_FLAT, .from_reg = 0x2004 },
|
||||
{ .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 = 0x2002 },
|
||||
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2003 },
|
||||
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2004 },
|
||||
{ .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 = 0x2002 },
|
||||
{ .cache = REGCACHE_MAPLE, .from_reg = 0x2003 },
|
||||
|
|
@ -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[] = {
|
||||
{ .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 = 0x2002 },
|
||||
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2003 },
|
||||
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2004 },
|
||||
{ .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 = 0x2002 },
|
||||
{ .cache = REGCACHE_MAPLE, .from_reg = 0x2003 },
|
||||
|
|
@ -151,8 +165,7 @@ static struct regmap *gen_regmap(struct kunit *test,
|
|||
struct reg_default *defaults;
|
||||
|
||||
config->cache_type = param->cache;
|
||||
config->disable_locking = config->cache_type == REGCACHE_RBTREE ||
|
||||
config->cache_type == REGCACHE_MAPLE;
|
||||
config->fast_io = param->fast_io;
|
||||
|
||||
if (config->max_register == 0) {
|
||||
config->max_register = param->from_reg;
|
||||
|
|
|
|||
|
|
@ -1445,6 +1445,7 @@ void regmap_exit(struct regmap *map)
|
|||
struct regmap_async *async;
|
||||
|
||||
regcache_exit(map);
|
||||
|
||||
regmap_debugfs_exit(map);
|
||||
regmap_range_exit(map);
|
||||
if (map->bus && map->bus->free_context)
|
||||
|
|
|
|||
|
|
@ -1521,6 +1521,9 @@ struct regmap_irq_chip_data;
|
|||
* struct regmap_irq_chip - Description of a generic regmap irq_chip.
|
||||
*
|
||||
* @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
|
||||
* interrupts arranged in separate sub-irq blocks with own IRQ
|
||||
|
|
@ -1606,6 +1609,7 @@ struct regmap_irq_chip_data;
|
|||
*/
|
||||
struct regmap_irq_chip {
|
||||
const char *name;
|
||||
const char *domain_suffix;
|
||||
|
||||
unsigned int main_status;
|
||||
unsigned int num_main_status_bits;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user