Commit 2e7a9515 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull regmap updates from Mark Brown:
 "The big thing this release is a big cleanup of the interrupt code from
  Aidan MacDonald, plus a few new API updates:

   - Rework of the interrupt code, making it much simpler and easier to
     extend

   - Support for device specific update bits operations with devices
     that otherwise use bitstream interfaces

   - Support for bit operations on fields as well as whole registers"

* tag 'regmap-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
  regmap: permit to set reg_update_bits with bulk implementation
  regmap: add WARN_ONCE when invalid mask is provided to regmap_field_init()
  regmap-irq: Fix bug in regmap_irq_get_irq_reg_linear()
  regmap: cache: Add extra parameter check in regcache_init
  regmap-irq: Deprecate the not_fixed_stride flag
  regmap-irq: Add get_irq_reg() callback
  regmap-irq: Fix inverted handling of unmask registers
  regmap-irq: Deprecate type registers and virtual registers
  regmap-irq: Introduce config registers for irq types
  regmap-irq: Refactor checks for status bulk read support
  regmap-irq: Remove mask_writeonly and regmap_irq_update_bits()
  regmap-irq: Remove inappropriate uses of regmap_irq_update_bits()
  regmap-irq: Remove an unnecessary restriction on type_in_mask
  regmap-irq: Cleanup sizeof(...) use in memory allocation
  regmap-irq: Remove unused type_reg_stride field
  regmap-irq: Convert bool bitfields to unsigned int
  regmap: Don't warn about cache only mode for devices with no cache
  regmap: provide regmap_field helpers for simple bit operations
  regmap: cache: Fix syntax errors in comments
parents 7d0d3fa7 739f872e
......@@ -133,6 +133,12 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
return -EINVAL;
}
if (config->num_reg_defaults && !config->reg_defaults) {
dev_err(map->dev,
"Register defaults number are set without the reg!\n");
return -EINVAL;
}
for (i = 0; i < config->num_reg_defaults; i++)
if (config->reg_defaults[i].reg % map->reg_stride)
return -EINVAL;
......@@ -495,7 +501,8 @@ EXPORT_SYMBOL_GPL(regcache_drop_region);
void regcache_cache_only(struct regmap *map, bool enable)
{
map->lock(map->lock_arg);
WARN_ON(map->cache_bypass && enable);
WARN_ON(map->cache_type != REGCACHE_NONE &&
map->cache_bypass && enable);
map->cache_only = enable;
trace_regmap_cache_only(map, enable);
map->unlock(map->lock_arg);
......@@ -531,7 +538,7 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty);
* @enable: flag if changes should not be written to the cache
*
* When a register map is marked with the cache bypass option, writes
* to the register map API will only update the hardware and not the
* to the register map API will only update the hardware and not
* the cache directly. This is useful when syncing the cache back to
* the hardware.
*/
......
This diff is collapsed.
......@@ -882,6 +882,8 @@ struct regmap *__regmap_init(struct device *dev,
if (config && config->read && config->write) {
map->reg_read = _regmap_bus_read;
if (config->reg_update_bits)
map->reg_update_bits = config->reg_update_bits;
/* Bulk read/write */
map->read = config->read;
......@@ -1298,6 +1300,9 @@ static void regmap_field_init(struct regmap_field *rm_field,
rm_field->reg = reg_field.reg;
rm_field->shift = reg_field.lsb;
rm_field->mask = GENMASK(reg_field.msb, reg_field.lsb);
WARN_ONCE(rm_field->mask == 0, "invalid empty mask defined\n");
rm_field->id_size = reg_field.id_size;
rm_field->id_offset = reg_field.id_offset;
}
......@@ -2218,6 +2223,28 @@ int regmap_field_update_bits_base(struct regmap_field *field,
}
EXPORT_SYMBOL_GPL(regmap_field_update_bits_base);
/**
* regmap_field_test_bits() - Check if all specified bits are set in a
* register field.
*
* @field: Register field to operate on
* @bits: Bits to test
*
* Returns -1 if the underlying regmap_field_read() fails, 0 if at least one of the
* tested bits is not set and 1 if all tested bits are set.
*/
int regmap_field_test_bits(struct regmap_field *field, unsigned int bits)
{
unsigned int val, ret;
ret = regmap_field_read(field, &val);
if (ret)
return ret;
return (val & bits) == bits;
}
EXPORT_SYMBOL_GPL(regmap_field_test_bits);
/**
* regmap_fields_update_bits_base() - Perform a read/modify/write cycle a
* register field with port ID
......
......@@ -1336,6 +1336,22 @@ static inline int regmap_field_update_bits(struct regmap_field *field,
NULL, false, false);
}
static inline int regmap_field_set_bits(struct regmap_field *field,
unsigned int bits)
{
return regmap_field_update_bits_base(field, bits, bits, NULL, false,
false);
}
static inline int regmap_field_clear_bits(struct regmap_field *field,
unsigned int bits)
{
return regmap_field_update_bits_base(field, bits, 0, NULL, false,
false);
}
int regmap_field_test_bits(struct regmap_field *field, unsigned int bits);
static inline int
regmap_field_force_update_bits(struct regmap_field *field,
unsigned int mask, unsigned int val)
......@@ -1424,6 +1440,8 @@ struct regmap_irq_sub_irq_map {
unsigned int *offset;
};
struct regmap_irq_chip_data;
/**
* struct regmap_irq_chip - Description of a generic regmap irq_chip.
*
......@@ -1451,32 +1469,50 @@ struct regmap_irq_sub_irq_map {
* main_status set.
*
* @status_base: Base status register address.
* @mask_base: Base mask register address.
* @mask_writeonly: Base mask register is write only.
* @unmask_base: Base unmask register address. for chips who have
* separate mask and unmask registers
* @mask_base: Base mask register address. Mask bits are set to 1 when an
* interrupt is masked, 0 when unmasked.
* @unmask_base: Base unmask register address. Unmask bits are set to 1 when
* an interrupt is unmasked and 0 when masked.
* @ack_base: Base ack address. If zero then the chip is clear on read.
* Using zero value is possible with @use_ack bit.
* @wake_base: Base address for wake enables. If zero unsupported.
* @type_base: Base address for irq type. If zero unsupported.
* @virt_reg_base: Base addresses for extra config regs.
* @type_base: Base address for irq type. If zero unsupported. Deprecated,
* use @config_base instead.
* @virt_reg_base: Base addresses for extra config regs. Deprecated, use
* @config_base instead.
* @config_base: Base address for IRQ type config regs. If null unsupported.
* @irq_reg_stride: Stride to use for chips where registers are not contiguous.
* @init_ack_masked: Ack all masked interrupts once during initalization.
* @mask_invert: Inverted mask register: cleared bits are masked out.
* Deprecated; prefer describing an inverted mask register as
* an unmask register.
* @mask_unmask_non_inverted: Controls mask bit inversion for chips that set
* both @mask_base and @unmask_base. If false, mask and unmask bits are
* inverted (which is deprecated behavior); if true, bits will not be
* inverted and the registers keep their normal behavior. Note that if
* you use only one of @mask_base or @unmask_base, this flag has no
* effect and is unnecessary. Any new drivers that set both @mask_base
* and @unmask_base should set this to true to avoid relying on the
* deprecated behavior.
* @use_ack: Use @ack register even if it is zero.
* @ack_invert: Inverted ack register: cleared bits for ack.
* @clear_ack: Use this to set 1 and 0 or vice-versa to clear interrupts.
* @wake_invert: Inverted wake register: cleared bits are wake enabled.
* @type_invert: Invert the type flags.
* @type_in_mask: Use the mask registers for controlling irq type. For
* interrupts defining type_rising/falling_mask use mask_base
* for edge configuration and never update bits in type_base.
* @type_invert: Invert the type flags. Deprecated, use config registers
* instead.
* @type_in_mask: Use the mask registers for controlling irq type. Use this if
* the hardware provides separate bits for rising/falling edge
* or low/high level interrupts and they should be combined into
* a single logical interrupt. Use &struct regmap_irq_type data
* to define the mask bit for each irq type.
* @clear_on_unmask: For chips with interrupts cleared on read: read the status
* registers before unmasking interrupts to clear any bits
* set when they were masked.
* @not_fixed_stride: Used when chip peripherals are not laid out with fixed
* stride. Must be used with sub_reg_offsets containing the
* offsets to each peripheral.
* stride. Must be used with sub_reg_offsets containing the
* offsets to each peripheral. Deprecated; the same thing
* can be accomplished with a @get_irq_reg callback, without
* the need for a @sub_reg_offsets table.
* @status_invert: Inverted status register: cleared bits are active interrupts.
* @runtime_pm: Hold a runtime PM lock on the device when accessing it.
*
......@@ -1484,17 +1520,28 @@ struct regmap_irq_sub_irq_map {
* @irqs: Descriptors for individual IRQs. Interrupt numbers are
* assigned based on the index in the array of the interrupt.
* @num_irqs: Number of descriptors.
* @num_type_reg: Number of type registers.
* @num_type_reg: Number of type registers. Deprecated, use config registers
* instead.
* @num_virt_regs: Number of non-standard irq configuration registers.
* If zero unsupported.
* @type_reg_stride: Stride to use for chips where type registers are not
* contiguous.
* If zero unsupported. Deprecated, use config registers
* instead.
* @num_config_bases: Number of config base registers.
* @num_config_regs: Number of config registers for each config base register.
* @handle_pre_irq: Driver specific callback to handle interrupt from device
* before regmap_irq_handler process the interrupts.
* @handle_post_irq: Driver specific callback to handle interrupt from device
* after handling the interrupts in regmap_irq_handler().
* @set_type_virt: Driver specific callback to extend regmap_irq_set_type()
* and configure virt regs.
* and configure virt regs. Deprecated, use @set_type_config
* callback and config registers instead.
* @set_type_config: Callback used for configuring irq types.
* @get_irq_reg: Callback for mapping (base register, index) pairs to register
* addresses. The base register will be one of @status_base,
* @mask_base, etc., @main_status, or any of @config_base.
* The index will be in the range [0, num_main_regs[ for the
* main status base, [0, num_type_settings[ for any config
* register base, and [0, num_regs[ for any other base.
* If unspecified then regmap_irq_get_irq_reg_linear() is used.
* @irq_drv_data: Driver specific IRQ data which is passed as parameter when
* driver specific pre/post interrupt handler is called.
*
......@@ -1517,20 +1564,21 @@ struct regmap_irq_chip {
unsigned int wake_base;
unsigned int type_base;
unsigned int *virt_reg_base;
const unsigned int *config_base;
unsigned int irq_reg_stride;
bool mask_writeonly:1;
bool init_ack_masked:1;
bool mask_invert:1;
bool use_ack:1;
bool ack_invert:1;
bool clear_ack:1;
bool wake_invert:1;
bool runtime_pm:1;
bool type_invert:1;
bool type_in_mask:1;
bool clear_on_unmask:1;
bool not_fixed_stride:1;
bool status_invert:1;
unsigned int init_ack_masked:1;
unsigned int mask_invert:1;
unsigned int mask_unmask_non_inverted:1;
unsigned int use_ack:1;
unsigned int ack_invert:1;
unsigned int clear_ack:1;
unsigned int wake_invert:1;
unsigned int runtime_pm:1;
unsigned int type_invert:1;
unsigned int type_in_mask:1;
unsigned int clear_on_unmask:1;
unsigned int not_fixed_stride:1;
unsigned int status_invert:1;
int num_regs;
......@@ -1539,16 +1587,24 @@ struct regmap_irq_chip {
int num_type_reg;
int num_virt_regs;
unsigned int type_reg_stride;
int num_config_bases;
int num_config_regs;
int (*handle_pre_irq)(void *irq_drv_data);
int (*handle_post_irq)(void *irq_drv_data);
int (*set_type_virt)(unsigned int **buf, unsigned int type,
unsigned long hwirq, int reg);
int (*set_type_config)(unsigned int **buf, unsigned int type,
const struct regmap_irq *irq_data, int idx);
unsigned int (*get_irq_reg)(struct regmap_irq_chip_data *data,
unsigned int base, int index);
void *irq_drv_data;
};
struct regmap_irq_chip_data;
unsigned int regmap_irq_get_irq_reg_linear(struct regmap_irq_chip_data *data,
unsigned int base, int index);
int regmap_irq_set_type_config_simple(unsigned int **buf, unsigned int type,
const struct regmap_irq *irq_data, int idx);
int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
int irq_base, const struct regmap_irq_chip *chip,
......@@ -1769,6 +1825,27 @@ regmap_field_force_update_bits(struct regmap_field *field,
return -EINVAL;
}
static inline int regmap_field_set_bits(struct regmap_field *field,
unsigned int bits)
{
WARN_ONCE(1, "regmap API is disabled");
return -EINVAL;
}
static inline int regmap_field_clear_bits(struct regmap_field *field,
unsigned int bits)
{
WARN_ONCE(1, "regmap API is disabled");
return -EINVAL;
}
static inline int regmap_field_test_bits(struct regmap_field *field,
unsigned int bits)
{
WARN_ONCE(1, "regmap API is disabled");
return -EINVAL;
}
static inline int regmap_fields_write(struct regmap_field *field,
unsigned int id, unsigned int val)
{
......
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