Commit 4aed6ee5 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull regmap updates from Mark Brown:
 "A few small fixes for regmaps this time, plus support for allowing
  drivers to select raw spinlocks for the locks in order to allow usage
  in interrutpt controllers"

* tag 'regmap-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
  regmap: teach regmap to use raw spinlocks if requested in the config
  regmap: allow const array for {devm_,}regmap_field_bulk_alloc reg_fields
  regmap: Prefer unsigned int to bare use of unsigned
  regmap: fix the offset of register error log
parents aa99f3c2 ca5537c9
...@@ -53,6 +53,10 @@ struct regmap { ...@@ -53,6 +53,10 @@ struct regmap {
spinlock_t spinlock; spinlock_t spinlock;
unsigned long spinlock_flags; unsigned long spinlock_flags;
}; };
struct {
raw_spinlock_t raw_spinlock;
unsigned long raw_spinlock_flags;
};
}; };
regmap_lock lock; regmap_lock lock;
regmap_unlock unlock; regmap_unlock unlock;
......
...@@ -368,7 +368,7 @@ static ssize_t regmap_reg_ranges_read_file(struct file *file, ...@@ -368,7 +368,7 @@ static ssize_t regmap_reg_ranges_read_file(struct file *file,
char *buf; char *buf;
char *entry; char *entry;
int ret; int ret;
unsigned entry_len; unsigned int entry_len;
if (*ppos < 0 || !count) if (*ppos < 0 || !count)
return -EINVAL; return -EINVAL;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
struct regmap_mmio_context { struct regmap_mmio_context {
void __iomem *regs; void __iomem *regs;
unsigned val_bytes; unsigned int val_bytes;
bool relaxed_mmio; bool relaxed_mmio;
bool attached_clk; bool attached_clk;
......
...@@ -533,6 +533,23 @@ __releases(&map->spinlock) ...@@ -533,6 +533,23 @@ __releases(&map->spinlock)
spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags); spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags);
} }
static void regmap_lock_raw_spinlock(void *__map)
__acquires(&map->raw_spinlock)
{
struct regmap *map = __map;
unsigned long flags;
raw_spin_lock_irqsave(&map->raw_spinlock, flags);
map->raw_spinlock_flags = flags;
}
static void regmap_unlock_raw_spinlock(void *__map)
__releases(&map->raw_spinlock)
{
struct regmap *map = __map;
raw_spin_unlock_irqrestore(&map->raw_spinlock, map->raw_spinlock_flags);
}
static void dev_get_regmap_release(struct device *dev, void *res) static void dev_get_regmap_release(struct device *dev, void *res)
{ {
/* /*
...@@ -770,11 +787,19 @@ struct regmap *__regmap_init(struct device *dev, ...@@ -770,11 +787,19 @@ struct regmap *__regmap_init(struct device *dev,
} else { } else {
if ((bus && bus->fast_io) || if ((bus && bus->fast_io) ||
config->fast_io) { config->fast_io) {
spin_lock_init(&map->spinlock); if (config->use_raw_spinlock) {
map->lock = regmap_lock_spinlock; raw_spin_lock_init(&map->raw_spinlock);
map->unlock = regmap_unlock_spinlock; map->lock = regmap_lock_raw_spinlock;
lockdep_set_class_and_name(&map->spinlock, map->unlock = regmap_unlock_raw_spinlock;
lock_key, lock_name); lockdep_set_class_and_name(&map->raw_spinlock,
lock_key, lock_name);
} else {
spin_lock_init(&map->spinlock);
map->lock = regmap_lock_spinlock;
map->unlock = regmap_unlock_spinlock;
lockdep_set_class_and_name(&map->spinlock,
lock_key, lock_name);
}
} else { } else {
mutex_init(&map->mutex); mutex_init(&map->mutex);
map->lock = regmap_lock_mutex; map->lock = regmap_lock_mutex;
...@@ -1126,10 +1151,10 @@ struct regmap *__regmap_init(struct device *dev, ...@@ -1126,10 +1151,10 @@ struct regmap *__regmap_init(struct device *dev,
/* Make sure, that this register range has no selector /* Make sure, that this register range has no selector
or data window within its boundary */ or data window within its boundary */
for (j = 0; j < config->num_ranges; j++) { for (j = 0; j < config->num_ranges; j++) {
unsigned sel_reg = config->ranges[j].selector_reg; unsigned int sel_reg = config->ranges[j].selector_reg;
unsigned win_min = config->ranges[j].window_start; unsigned int win_min = config->ranges[j].window_start;
unsigned win_max = win_min + unsigned int win_max = win_min +
config->ranges[j].window_len - 1; config->ranges[j].window_len - 1;
/* Allow data window inside its own virtual range */ /* Allow data window inside its own virtual range */
if (j == i) if (j == i)
...@@ -1298,7 +1323,7 @@ EXPORT_SYMBOL_GPL(devm_regmap_field_alloc); ...@@ -1298,7 +1323,7 @@ EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
*/ */
int regmap_field_bulk_alloc(struct regmap *regmap, int regmap_field_bulk_alloc(struct regmap *regmap,
struct regmap_field **rm_field, struct regmap_field **rm_field,
struct reg_field *reg_field, const struct reg_field *reg_field,
int num_fields) int num_fields)
{ {
struct regmap_field *rf; struct regmap_field *rf;
...@@ -1334,7 +1359,7 @@ EXPORT_SYMBOL_GPL(regmap_field_bulk_alloc); ...@@ -1334,7 +1359,7 @@ EXPORT_SYMBOL_GPL(regmap_field_bulk_alloc);
int devm_regmap_field_bulk_alloc(struct device *dev, int devm_regmap_field_bulk_alloc(struct device *dev,
struct regmap *regmap, struct regmap *regmap,
struct regmap_field **rm_field, struct regmap_field **rm_field,
struct reg_field *reg_field, const struct reg_field *reg_field,
int num_fields) int num_fields)
{ {
struct regmap_field *rf; struct regmap_field *rf;
...@@ -1667,7 +1692,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, ...@@ -1667,7 +1692,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
if (ret) { if (ret) {
dev_err(map->dev, dev_err(map->dev,
"Error in caching of register: %x ret: %d\n", "Error in caching of register: %x ret: %d\n",
reg + i, ret); reg + regmap_get_offset(map, i), ret);
return ret; return ret;
} }
} }
......
...@@ -344,6 +344,7 @@ typedef void (*regmap_unlock)(void *); ...@@ -344,6 +344,7 @@ typedef void (*regmap_unlock)(void *);
* @ranges: Array of configuration entries for virtual address ranges. * @ranges: Array of configuration entries for virtual address ranges.
* @num_ranges: Number of range configuration entries. * @num_ranges: Number of range configuration entries.
* @use_hwlock: Indicate if a hardware spinlock should be used. * @use_hwlock: Indicate if a hardware spinlock should be used.
* @use_raw_spinlock: Indicate if a raw spinlock should be used.
* @hwlock_id: Specify the hardware spinlock id. * @hwlock_id: Specify the hardware spinlock id.
* @hwlock_mode: The hardware spinlock mode, should be HWLOCK_IRQSTATE, * @hwlock_mode: The hardware spinlock mode, should be HWLOCK_IRQSTATE,
* HWLOCK_IRQ or 0. * HWLOCK_IRQ or 0.
...@@ -403,6 +404,7 @@ struct regmap_config { ...@@ -403,6 +404,7 @@ struct regmap_config {
unsigned int num_ranges; unsigned int num_ranges;
bool use_hwlock; bool use_hwlock;
bool use_raw_spinlock;
unsigned int hwlock_id; unsigned int hwlock_id;
unsigned int hwlock_mode; unsigned int hwlock_mode;
...@@ -1269,12 +1271,13 @@ void devm_regmap_field_free(struct device *dev, struct regmap_field *field); ...@@ -1269,12 +1271,13 @@ void devm_regmap_field_free(struct device *dev, struct regmap_field *field);
int regmap_field_bulk_alloc(struct regmap *regmap, int regmap_field_bulk_alloc(struct regmap *regmap,
struct regmap_field **rm_field, struct regmap_field **rm_field,
struct reg_field *reg_field, const struct reg_field *reg_field,
int num_fields); int num_fields);
void regmap_field_bulk_free(struct regmap_field *field); void regmap_field_bulk_free(struct regmap_field *field);
int devm_regmap_field_bulk_alloc(struct device *dev, struct regmap *regmap, int devm_regmap_field_bulk_alloc(struct device *dev, struct regmap *regmap,
struct regmap_field **field, struct regmap_field **field,
struct reg_field *reg_field, int num_fields); const struct reg_field *reg_field,
int num_fields);
void devm_regmap_field_bulk_free(struct device *dev, void devm_regmap_field_bulk_free(struct device *dev,
struct regmap_field *field); struct regmap_field *field);
......
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