mirror of https://github.com/torvalds/linux.git
regmap: Updates for v6.19
Another small update for regmap, we have one new feature plus a little
bit of cleanup:
- Support for sparseness information in the flat cache, allowing users
that really need the performance properties it provides to benefit
from the interface and startup time improvements that sparsness provides
without needing to go all the way to a more fancy data structure.
- Cleanup work from Andy Shevchenko, refactoring the cache interface
in preparation for some future stuff he's working on.
-----BEGIN PGP SIGNATURE-----
iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmkt6/0ACgkQJNaLcl1U
h9A33gf/QC/O/zxVtpq31+CtC1k3ola0rWrLxOnQKywoUcBjJqX+FiFqL+MDS6Mw
RfXzX7SmzJup71/sg7GNQjRSL3jH3UmsAy4acbNhoCXwi0VaFibHfTqVKNQGK5um
uzsDP8Ue4zUyqym3jMKxs36iVYtt9/QcUjrubumisnB51csQKQ0tn7+2khUbN7D5
PEjUfR7WiGAGDf2AmCLueCYaV16uuzoxnlV9U4Mp5LYvzi5KKxZZAid9ppUCUcAt
uab8Y5Qo8uxBKJEue1vp4shfbxj69GoOdzOP8bYWNP2z6xcHXgK2ma/5y3eqK7L0
uA1SHqKW3QXY1VckI83QWrifR6r8mQ==
=TTeH
-----END PGP SIGNATURE-----
Merge tag 'regmap-v6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown:
"Another small update for regmap, we have one new feature plus a little
bit of cleanup:
- Support for sparseness information in the flat cache, allowing
users that really need the performance properties it provides to
benefit from the interface and startup time improvements that
sparsness provides without needing to go all the way to a more
fancy data structure
- Cleanup work from Andy Shevchenko, refactoring the cache interface
in preparation for some future stuff he's working on"
* tag 'regmap-v6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
regmap: sdw-mbq: Reorder regmap_mbq_context struct for better packing
regmap: i3c: Use ARRAY_SIZE()
regcache: maple: Split ->populate() from ->init()
regcache: flat: Split ->populate() from ->init()
regcache: flat: Remove unneeded check and error message for -ENOMEM
regcache: rbtree: Split ->populate() from ->init()
regcache: Add ->populate() callback to separate from ->init()
regmap: warn users about uninitialized flat cache
regmap: add flat cache with sparse validity
This commit is contained in:
commit
ba1401f9cc
|
|
@ -186,6 +186,7 @@ struct regcache_ops {
|
||||||
enum regcache_type type;
|
enum regcache_type type;
|
||||||
int (*init)(struct regmap *map);
|
int (*init)(struct regmap *map);
|
||||||
int (*exit)(struct regmap *map);
|
int (*exit)(struct regmap *map);
|
||||||
|
int (*populate)(struct regmap *map);
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
void (*debugfs_init)(struct regmap *map);
|
void (*debugfs_init)(struct regmap *map);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -288,6 +289,7 @@ enum regmap_endian regmap_get_val_endian(struct device *dev,
|
||||||
const struct regmap_bus *bus,
|
const struct regmap_bus *bus,
|
||||||
const struct regmap_config *config);
|
const struct regmap_config *config);
|
||||||
|
|
||||||
|
extern struct regcache_ops regcache_flat_sparse_ops;
|
||||||
extern struct regcache_ops regcache_rbtree_ops;
|
extern struct regcache_ops regcache_rbtree_ops;
|
||||||
extern struct regcache_ops regcache_maple_ops;
|
extern struct regcache_ops regcache_maple_ops;
|
||||||
extern struct regcache_ops regcache_flat_ops;
|
extern struct regcache_ops regcache_flat_ops;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,11 @@
|
||||||
//
|
//
|
||||||
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
// Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||||
|
|
||||||
|
#include <linux/bitmap.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#include <linux/overflow.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
|
@ -18,46 +22,92 @@ static inline unsigned int regcache_flat_get_index(const struct regmap *map,
|
||||||
return regcache_get_index_by_order(map, reg);
|
return regcache_get_index_by_order(map, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct regcache_flat_data {
|
||||||
|
unsigned long *valid;
|
||||||
|
unsigned int data[];
|
||||||
|
};
|
||||||
|
|
||||||
static int regcache_flat_init(struct regmap *map)
|
static int regcache_flat_init(struct regmap *map)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int cache_size;
|
||||||
unsigned int *cache;
|
struct regcache_flat_data *cache;
|
||||||
|
|
||||||
if (!map || map->reg_stride_order < 0 || !map->max_register_is_set)
|
if (!map || map->reg_stride_order < 0 || !map->max_register_is_set)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
map->cache = kcalloc(regcache_flat_get_index(map, map->max_register)
|
cache_size = regcache_flat_get_index(map, map->max_register) + 1;
|
||||||
+ 1, sizeof(unsigned int), map->alloc_flags);
|
cache = kzalloc(struct_size(cache, data, cache_size), map->alloc_flags);
|
||||||
if (!map->cache)
|
if (!cache)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
cache = map->cache;
|
cache->valid = bitmap_zalloc(cache_size, map->alloc_flags);
|
||||||
|
if (!cache->valid)
|
||||||
|
goto err_free;
|
||||||
|
|
||||||
|
map->cache = cache;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_free:
|
||||||
|
kfree(cache);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regcache_flat_exit(struct regmap *map)
|
||||||
|
{
|
||||||
|
struct regcache_flat_data *cache = map->cache;
|
||||||
|
|
||||||
|
if (cache)
|
||||||
|
bitmap_free(cache->valid);
|
||||||
|
|
||||||
|
kfree(cache);
|
||||||
|
map->cache = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regcache_flat_populate(struct regmap *map)
|
||||||
|
{
|
||||||
|
struct regcache_flat_data *cache = map->cache;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < map->num_reg_defaults; i++) {
|
for (i = 0; i < map->num_reg_defaults; i++) {
|
||||||
unsigned int reg = map->reg_defaults[i].reg;
|
unsigned int reg = map->reg_defaults[i].reg;
|
||||||
unsigned int index = regcache_flat_get_index(map, reg);
|
unsigned int index = regcache_flat_get_index(map, reg);
|
||||||
|
|
||||||
cache[index] = map->reg_defaults[i].def;
|
cache->data[index] = map->reg_defaults[i].def;
|
||||||
|
__set_bit(index, cache->valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regcache_flat_exit(struct regmap *map)
|
|
||||||
{
|
|
||||||
kfree(map->cache);
|
|
||||||
map->cache = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int regcache_flat_read(struct regmap *map,
|
static int regcache_flat_read(struct regmap *map,
|
||||||
unsigned int reg, unsigned int *value)
|
unsigned int reg, unsigned int *value)
|
||||||
{
|
{
|
||||||
unsigned int *cache = map->cache;
|
struct regcache_flat_data *cache = map->cache;
|
||||||
unsigned int index = regcache_flat_get_index(map, reg);
|
unsigned int index = regcache_flat_get_index(map, reg);
|
||||||
|
|
||||||
*value = cache[index];
|
/* legacy behavior: ignore validity, but warn the user */
|
||||||
|
if (unlikely(!test_bit(index, cache->valid)))
|
||||||
|
dev_warn_once(map->dev,
|
||||||
|
"using zero-initialized flat cache, this may cause unexpected behavior");
|
||||||
|
|
||||||
|
*value = cache->data[index];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regcache_flat_sparse_read(struct regmap *map,
|
||||||
|
unsigned int reg, unsigned int *value)
|
||||||
|
{
|
||||||
|
struct regcache_flat_data *cache = map->cache;
|
||||||
|
unsigned int index = regcache_flat_get_index(map, reg);
|
||||||
|
|
||||||
|
if (unlikely(!test_bit(index, cache->valid)))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
*value = cache->data[index];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -65,10 +115,23 @@ static int regcache_flat_read(struct regmap *map,
|
||||||
static int regcache_flat_write(struct regmap *map, unsigned int reg,
|
static int regcache_flat_write(struct regmap *map, unsigned int reg,
|
||||||
unsigned int value)
|
unsigned int value)
|
||||||
{
|
{
|
||||||
unsigned int *cache = map->cache;
|
struct regcache_flat_data *cache = map->cache;
|
||||||
unsigned int index = regcache_flat_get_index(map, reg);
|
unsigned int index = regcache_flat_get_index(map, reg);
|
||||||
|
|
||||||
cache[index] = value;
|
cache->data[index] = value;
|
||||||
|
__set_bit(index, cache->valid);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regcache_flat_drop(struct regmap *map, unsigned int min,
|
||||||
|
unsigned int max)
|
||||||
|
{
|
||||||
|
struct regcache_flat_data *cache = map->cache;
|
||||||
|
unsigned int bitmap_min = regcache_flat_get_index(map, min);
|
||||||
|
unsigned int bitmap_max = regcache_flat_get_index(map, max);
|
||||||
|
|
||||||
|
bitmap_clear(cache->valid, bitmap_min, bitmap_max + 1 - bitmap_min);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +141,18 @@ struct regcache_ops regcache_flat_ops = {
|
||||||
.name = "flat",
|
.name = "flat",
|
||||||
.init = regcache_flat_init,
|
.init = regcache_flat_init,
|
||||||
.exit = regcache_flat_exit,
|
.exit = regcache_flat_exit,
|
||||||
|
.populate = regcache_flat_populate,
|
||||||
.read = regcache_flat_read,
|
.read = regcache_flat_read,
|
||||||
.write = regcache_flat_write,
|
.write = regcache_flat_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct regcache_ops regcache_flat_sparse_ops = {
|
||||||
|
.type = REGCACHE_FLAT_S,
|
||||||
|
.name = "flat-sparse",
|
||||||
|
.init = regcache_flat_init,
|
||||||
|
.exit = regcache_flat_exit,
|
||||||
|
.populate = regcache_flat_populate,
|
||||||
|
.read = regcache_flat_sparse_read,
|
||||||
|
.write = regcache_flat_write,
|
||||||
|
.drop = regcache_flat_drop,
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,23 @@ static int regcache_maple_sync(struct regmap *map, unsigned int min,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int regcache_maple_init(struct regmap *map)
|
||||||
|
{
|
||||||
|
struct maple_tree *mt;
|
||||||
|
|
||||||
|
mt = kmalloc(sizeof(*mt), map->alloc_flags);
|
||||||
|
if (!mt)
|
||||||
|
return -ENOMEM;
|
||||||
|
map->cache = mt;
|
||||||
|
|
||||||
|
mt_init(mt);
|
||||||
|
|
||||||
|
if (!mt_external_lock(mt) && map->lock_key)
|
||||||
|
lockdep_set_class_and_subclass(&mt->ma_lock, map->lock_key, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int regcache_maple_exit(struct regmap *map)
|
static int regcache_maple_exit(struct regmap *map)
|
||||||
{
|
{
|
||||||
struct maple_tree *mt = map->cache;
|
struct maple_tree *mt = map->cache;
|
||||||
|
|
@ -340,26 +357,12 @@ static int regcache_maple_insert_block(struct regmap *map, int first,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regcache_maple_init(struct regmap *map)
|
static int regcache_maple_populate(struct regmap *map)
|
||||||
{
|
{
|
||||||
struct maple_tree *mt;
|
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
int range_start;
|
int range_start;
|
||||||
|
|
||||||
mt = kmalloc(sizeof(*mt), map->alloc_flags);
|
|
||||||
if (!mt)
|
|
||||||
return -ENOMEM;
|
|
||||||
map->cache = mt;
|
|
||||||
|
|
||||||
mt_init(mt);
|
|
||||||
|
|
||||||
if (!mt_external_lock(mt) && map->lock_key)
|
|
||||||
lockdep_set_class_and_subclass(&mt->ma_lock, map->lock_key, 1);
|
|
||||||
|
|
||||||
if (!map->num_reg_defaults)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
range_start = 0;
|
range_start = 0;
|
||||||
|
|
||||||
/* Scan for ranges of contiguous registers */
|
/* Scan for ranges of contiguous registers */
|
||||||
|
|
@ -369,23 +372,14 @@ static int regcache_maple_init(struct regmap *map)
|
||||||
ret = regcache_maple_insert_block(map, range_start,
|
ret = regcache_maple_insert_block(map, range_start,
|
||||||
i - 1);
|
i - 1);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto err;
|
return ret;
|
||||||
|
|
||||||
range_start = i;
|
range_start = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the last block */
|
/* Add the last block */
|
||||||
ret = regcache_maple_insert_block(map, range_start,
|
return regcache_maple_insert_block(map, range_start, map->num_reg_defaults - 1);
|
||||||
map->num_reg_defaults - 1);
|
|
||||||
if (ret != 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
regcache_maple_exit(map);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct regcache_ops regcache_maple_ops = {
|
struct regcache_ops regcache_maple_ops = {
|
||||||
|
|
@ -393,6 +387,7 @@ struct regcache_ops regcache_maple_ops = {
|
||||||
.name = "maple",
|
.name = "maple",
|
||||||
.init = regcache_maple_init,
|
.init = regcache_maple_init,
|
||||||
.exit = regcache_maple_exit,
|
.exit = regcache_maple_exit,
|
||||||
|
.populate = regcache_maple_populate,
|
||||||
.read = regcache_maple_read,
|
.read = regcache_maple_read,
|
||||||
.write = regcache_maple_write,
|
.write = regcache_maple_write,
|
||||||
.drop = regcache_maple_drop,
|
.drop = regcache_maple_drop,
|
||||||
|
|
|
||||||
|
|
@ -184,8 +184,6 @@ static void rbtree_debugfs_init(struct regmap *map)
|
||||||
static int regcache_rbtree_init(struct regmap *map)
|
static int regcache_rbtree_init(struct regmap *map)
|
||||||
{
|
{
|
||||||
struct regcache_rbtree_ctx *rbtree_ctx;
|
struct regcache_rbtree_ctx *rbtree_ctx;
|
||||||
int i;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
map->cache = kmalloc(sizeof *rbtree_ctx, map->alloc_flags);
|
map->cache = kmalloc(sizeof *rbtree_ctx, map->alloc_flags);
|
||||||
if (!map->cache)
|
if (!map->cache)
|
||||||
|
|
@ -195,19 +193,7 @@ static int regcache_rbtree_init(struct regmap *map)
|
||||||
rbtree_ctx->root = RB_ROOT;
|
rbtree_ctx->root = RB_ROOT;
|
||||||
rbtree_ctx->cached_rbnode = NULL;
|
rbtree_ctx->cached_rbnode = NULL;
|
||||||
|
|
||||||
for (i = 0; i < map->num_reg_defaults; i++) {
|
|
||||||
ret = regcache_rbtree_write(map,
|
|
||||||
map->reg_defaults[i].reg,
|
|
||||||
map->reg_defaults[i].def);
|
|
||||||
if (ret)
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
|
||||||
regcache_rbtree_exit(map);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regcache_rbtree_exit(struct regmap *map)
|
static int regcache_rbtree_exit(struct regmap *map)
|
||||||
|
|
@ -239,6 +225,22 @@ static int regcache_rbtree_exit(struct regmap *map)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int regcache_rbtree_populate(struct regmap *map)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for (i = 0; i < map->num_reg_defaults; i++) {
|
||||||
|
ret = regcache_rbtree_write(map,
|
||||||
|
map->reg_defaults[i].reg,
|
||||||
|
map->reg_defaults[i].def);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int regcache_rbtree_read(struct regmap *map,
|
static int regcache_rbtree_read(struct regmap *map,
|
||||||
unsigned int reg, unsigned int *value)
|
unsigned int reg, unsigned int *value)
|
||||||
{
|
{
|
||||||
|
|
@ -546,6 +548,7 @@ struct regcache_ops regcache_rbtree_ops = {
|
||||||
.name = "rbtree",
|
.name = "rbtree",
|
||||||
.init = regcache_rbtree_init,
|
.init = regcache_rbtree_init,
|
||||||
.exit = regcache_rbtree_exit,
|
.exit = regcache_rbtree_exit,
|
||||||
|
.populate = regcache_rbtree_populate,
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
.debugfs_init = rbtree_debugfs_init,
|
.debugfs_init = rbtree_debugfs_init,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
static const struct regcache_ops *cache_types[] = {
|
static const struct regcache_ops *cache_types[] = {
|
||||||
|
®cache_flat_sparse_ops,
|
||||||
®cache_rbtree_ops,
|
®cache_rbtree_ops,
|
||||||
®cache_maple_ops,
|
®cache_maple_ops,
|
||||||
®cache_flat_ops,
|
®cache_flat_ops,
|
||||||
|
|
@ -221,8 +222,24 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (map->num_reg_defaults && map->cache_ops->populate) {
|
||||||
|
dev_dbg(map->dev, "Populating %s cache\n", map->cache_ops->name);
|
||||||
|
map->lock(map->lock_arg);
|
||||||
|
ret = map->cache_ops->populate(map);
|
||||||
|
map->unlock(map->lock_arg);
|
||||||
|
if (ret)
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_exit:
|
||||||
|
if (map->cache_ops->exit) {
|
||||||
|
dev_dbg(map->dev, "Destroying %s cache\n", map->cache_ops->name);
|
||||||
|
map->lock(map->lock_arg);
|
||||||
|
ret = map->cache_ops->exit(map);
|
||||||
|
map->unlock(map->lock_arg);
|
||||||
|
}
|
||||||
err_free:
|
err_free:
|
||||||
kfree(map->reg_defaults);
|
kfree(map->reg_defaults);
|
||||||
if (map->cache_free)
|
if (map->cache_free)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
// Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
|
// Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
|
||||||
|
|
||||||
|
#include <linux/array_size.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/i3c/device.h>
|
#include <linux/i3c/device.h>
|
||||||
#include <linux/i3c/master.h>
|
#include <linux/i3c/master.h>
|
||||||
|
|
@ -18,7 +19,7 @@ static int regmap_i3c_write(void *context, const void *data, size_t count)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return i3c_device_do_priv_xfers(i3c, xfers, 1);
|
return i3c_device_do_priv_xfers(i3c, xfers, ARRAY_SIZE(xfers));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regmap_i3c_read(void *context,
|
static int regmap_i3c_read(void *context,
|
||||||
|
|
@ -37,7 +38,7 @@ static int regmap_i3c_read(void *context,
|
||||||
xfers[1].len = val_size;
|
xfers[1].len = val_size;
|
||||||
xfers[1].data.in = val;
|
xfers[1].data.in = val;
|
||||||
|
|
||||||
return i3c_device_do_priv_xfers(i3c, xfers, 2);
|
return i3c_device_do_priv_xfers(i3c, xfers, ARRAY_SIZE(xfers));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct regmap_bus regmap_i3c = {
|
static const struct regmap_bus regmap_i3c = {
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ static const char *regcache_type_name(enum regcache_type type)
|
||||||
return "none";
|
return "none";
|
||||||
case REGCACHE_FLAT:
|
case REGCACHE_FLAT:
|
||||||
return "flat";
|
return "flat";
|
||||||
|
case REGCACHE_FLAT_S:
|
||||||
|
return "flat-sparse";
|
||||||
case REGCACHE_RBTREE:
|
case REGCACHE_RBTREE:
|
||||||
return "rbtree";
|
return "rbtree";
|
||||||
case REGCACHE_MAPLE:
|
case REGCACHE_MAPLE:
|
||||||
|
|
@ -93,6 +95,8 @@ static const struct regmap_test_param regcache_types_list[] = {
|
||||||
{ .cache = REGCACHE_NONE, .fast_io = true },
|
{ .cache = REGCACHE_NONE, .fast_io = true },
|
||||||
{ .cache = REGCACHE_FLAT },
|
{ .cache = REGCACHE_FLAT },
|
||||||
{ .cache = REGCACHE_FLAT, .fast_io = true },
|
{ .cache = REGCACHE_FLAT, .fast_io = true },
|
||||||
|
{ .cache = REGCACHE_FLAT_S },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .fast_io = true },
|
||||||
{ .cache = REGCACHE_RBTREE },
|
{ .cache = REGCACHE_RBTREE },
|
||||||
{ .cache = REGCACHE_RBTREE, .fast_io = true },
|
{ .cache = REGCACHE_RBTREE, .fast_io = true },
|
||||||
{ .cache = REGCACHE_MAPLE },
|
{ .cache = REGCACHE_MAPLE },
|
||||||
|
|
@ -104,6 +108,8 @@ 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_FLAT, .fast_io = true },
|
||||||
|
{ .cache = REGCACHE_FLAT_S },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .fast_io = true },
|
||||||
{ .cache = REGCACHE_RBTREE },
|
{ .cache = REGCACHE_RBTREE },
|
||||||
{ .cache = REGCACHE_RBTREE, .fast_io = true },
|
{ .cache = REGCACHE_RBTREE, .fast_io = true },
|
||||||
{ .cache = REGCACHE_MAPLE },
|
{ .cache = REGCACHE_MAPLE },
|
||||||
|
|
@ -119,6 +125,12 @@ static const struct regmap_test_param real_cache_types_list[] = {
|
||||||
{ .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_FLAT_S, .from_reg = 0 },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .from_reg = 0, .fast_io = true },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .from_reg = 0x2001 },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .from_reg = 0x2002 },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .from_reg = 0x2003 },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .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 = 0, .fast_io = true },
|
||||||
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2001 },
|
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2001 },
|
||||||
|
|
@ -136,6 +148,12 @@ static const struct regmap_test_param real_cache_types_list[] = {
|
||||||
KUNIT_ARRAY_PARAM(real_cache_types, real_cache_types_list, param_to_desc);
|
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_FLAT_S, .from_reg = 0 },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .from_reg = 0, .fast_io = true },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .from_reg = 0x2001 },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .from_reg = 0x2002 },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .from_reg = 0x2003 },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .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 = 0, .fast_io = true },
|
||||||
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2001 },
|
{ .cache = REGCACHE_RBTREE, .from_reg = 0x2001 },
|
||||||
|
|
@ -1597,6 +1615,8 @@ static const struct regmap_test_param raw_types_list[] = {
|
||||||
{ .cache = REGCACHE_NONE, .val_endian = REGMAP_ENDIAN_BIG },
|
{ .cache = REGCACHE_NONE, .val_endian = REGMAP_ENDIAN_BIG },
|
||||||
{ .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_LITTLE },
|
{ .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_LITTLE },
|
||||||
{ .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_BIG },
|
{ .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_BIG },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .val_endian = REGMAP_ENDIAN_LITTLE },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .val_endian = REGMAP_ENDIAN_BIG },
|
||||||
{ .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_LITTLE },
|
{ .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_LITTLE },
|
||||||
{ .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_BIG },
|
{ .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_BIG },
|
||||||
{ .cache = REGCACHE_MAPLE, .val_endian = REGMAP_ENDIAN_LITTLE },
|
{ .cache = REGCACHE_MAPLE, .val_endian = REGMAP_ENDIAN_LITTLE },
|
||||||
|
|
@ -1608,6 +1628,8 @@ KUNIT_ARRAY_PARAM(raw_test_types, raw_types_list, param_to_desc);
|
||||||
static const struct regmap_test_param raw_cache_types_list[] = {
|
static const struct regmap_test_param raw_cache_types_list[] = {
|
||||||
{ .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_LITTLE },
|
{ .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_LITTLE },
|
||||||
{ .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_BIG },
|
{ .cache = REGCACHE_FLAT, .val_endian = REGMAP_ENDIAN_BIG },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .val_endian = REGMAP_ENDIAN_LITTLE },
|
||||||
|
{ .cache = REGCACHE_FLAT_S, .val_endian = REGMAP_ENDIAN_BIG },
|
||||||
{ .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_LITTLE },
|
{ .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_LITTLE },
|
||||||
{ .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_BIG },
|
{ .cache = REGCACHE_RBTREE, .val_endian = REGMAP_ENDIAN_BIG },
|
||||||
{ .cache = REGCACHE_MAPLE, .val_endian = REGMAP_ENDIAN_LITTLE },
|
{ .cache = REGCACHE_MAPLE, .val_endian = REGMAP_ENDIAN_LITTLE },
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,11 @@ struct regmap_mbq_context {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct sdw_slave *sdw;
|
struct sdw_slave *sdw;
|
||||||
|
|
||||||
|
bool (*readable_reg)(struct device *dev, unsigned int reg);
|
||||||
|
|
||||||
struct regmap_sdw_mbq_cfg cfg;
|
struct regmap_sdw_mbq_cfg cfg;
|
||||||
|
|
||||||
int val_size;
|
int val_size;
|
||||||
bool (*readable_reg)(struct device *dev, unsigned int reg);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int regmap_sdw_mbq_size(struct regmap_mbq_context *ctx, unsigned int reg)
|
static int regmap_sdw_mbq_size(struct regmap_mbq_context *ctx, unsigned int reg)
|
||||||
|
|
|
||||||
|
|
@ -55,18 +55,23 @@ struct sdw_slave;
|
||||||
#define REGMAP_DOWNSHIFT(s) (s)
|
#define REGMAP_DOWNSHIFT(s) (s)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The supported cache types, the default is no cache. Any new caches
|
* The supported cache types, the default is no cache. Any new caches should
|
||||||
* should usually use the maple tree cache unless they specifically
|
* usually use the maple tree cache unless they specifically require that there
|
||||||
* require that there are never any allocations at runtime and can't
|
* are never any allocations at runtime in which case they should use the sparse
|
||||||
* provide defaults in which case they should use the flat cache. The
|
* flat cache. The rbtree cache *may* have some performance advantage for very
|
||||||
* rbtree cache *may* have some performance advantage for very low end
|
* low end systems that make heavy use of cache syncs but is mainly legacy.
|
||||||
* systems that make heavy use of cache syncs but is mainly legacy.
|
* These caches are sparse and entries will be initialized from hardware if no
|
||||||
|
* default has been provided.
|
||||||
|
* The non-sparse flat cache is provided for compatibility with existing users
|
||||||
|
* and will zero-initialize cache entries for which no defaults are provided.
|
||||||
|
* New users should use the sparse flat cache.
|
||||||
*/
|
*/
|
||||||
enum regcache_type {
|
enum regcache_type {
|
||||||
REGCACHE_NONE,
|
REGCACHE_NONE,
|
||||||
REGCACHE_RBTREE,
|
REGCACHE_RBTREE,
|
||||||
REGCACHE_FLAT,
|
REGCACHE_FLAT,
|
||||||
REGCACHE_MAPLE,
|
REGCACHE_MAPLE,
|
||||||
|
REGCACHE_FLAT_S,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue