Merge tag 'regmap-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown:
"Quite a few enhancements this time around, helpers and diagnostics for
the most part which is good to see:
- Addition of table based lookups for the register access checks from
Davide Ciminaghi, making life easier for drivers with big blocks of
similar registers.
- Allow drivers to get the irqdomain for regmap irq_chips, allowing
the domain to be used with other APIs.
- Debug improvements for paged register maps.
- Performance improvments for some of the diagnostic infrastructure,
very helpful for devices with large register maps."
* tag 'regmap-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
regmap: debugfs: Cache offsets of valid regions for dump
regmap: debugfs: Factor out initial seek
regmap: debugfs: Avoid overflows for very small reads
regmap: Cache register and value sizes for debugfs
regmap: introduce tables for readable/writeable/volatile/precious checks
regmap: core: Report registers in hex when we can't cache
regmap: Fix printing of size_t variable
regmap: make lock/unlock functions customizable
regmap: silence GCC warning
regmap: Split raw writes that cross window boundaries
regmap: Make return code checks consistent
regmap: Factor range lookup out of page selection
regmap: Provide debugfs read of register ranges
regmap: Factor out debugfs register read
regmap: Allow ranges to be named
regmap: When we sanity check during range adds say what errors we find
regmap: Rename n_ranges to num_ranges
regmap: irq: Allow users to retrieve the irq_domain
This commit is contained in:
+88
-7
@@ -19,6 +19,7 @@
|
||||
struct module;
|
||||
struct device;
|
||||
struct i2c_client;
|
||||
struct irq_domain;
|
||||
struct spi_device;
|
||||
struct regmap;
|
||||
struct regmap_range_cfg;
|
||||
@@ -53,6 +54,39 @@ enum regmap_endian {
|
||||
REGMAP_ENDIAN_NATIVE,
|
||||
};
|
||||
|
||||
/**
|
||||
* A register range, used for access related checks
|
||||
* (readable/writeable/volatile/precious checks)
|
||||
*
|
||||
* @range_min: address of first register
|
||||
* @range_max: address of last register
|
||||
*/
|
||||
struct regmap_range {
|
||||
unsigned int range_min;
|
||||
unsigned int range_max;
|
||||
};
|
||||
|
||||
/*
|
||||
* A table of ranges including some yes ranges and some no ranges.
|
||||
* If a register belongs to a no_range, the corresponding check function
|
||||
* will return false. If a register belongs to a yes range, the corresponding
|
||||
* check function will return true. "no_ranges" are searched first.
|
||||
*
|
||||
* @yes_ranges : pointer to an array of regmap ranges used as "yes ranges"
|
||||
* @n_yes_ranges: size of the above array
|
||||
* @no_ranges: pointer to an array of regmap ranges used as "no ranges"
|
||||
* @n_no_ranges: size of the above array
|
||||
*/
|
||||
struct regmap_access_table {
|
||||
const struct regmap_range *yes_ranges;
|
||||
unsigned int n_yes_ranges;
|
||||
const struct regmap_range *no_ranges;
|
||||
unsigned int n_no_ranges;
|
||||
};
|
||||
|
||||
typedef void (*regmap_lock)(void *);
|
||||
typedef void (*regmap_unlock)(void *);
|
||||
|
||||
/**
|
||||
* Configuration for the register map of a device.
|
||||
*
|
||||
@@ -67,16 +101,39 @@ enum regmap_endian {
|
||||
* @val_bits: Number of bits in a register value, mandatory.
|
||||
*
|
||||
* @writeable_reg: Optional callback returning true if the register
|
||||
* can be written to.
|
||||
* can be written to. If this field is NULL but wr_table
|
||||
* (see below) is not, the check is performed on such table
|
||||
* (a register is writeable if it belongs to one of the ranges
|
||||
* specified by wr_table).
|
||||
* @readable_reg: Optional callback returning true if the register
|
||||
* can be read from.
|
||||
* can be read from. If this field is NULL but rd_table
|
||||
* (see below) is not, the check is performed on such table
|
||||
* (a register is readable if it belongs to one of the ranges
|
||||
* specified by rd_table).
|
||||
* @volatile_reg: Optional callback returning true if the register
|
||||
* value can't be cached.
|
||||
* value can't be cached. If this field is NULL but
|
||||
* volatile_table (see below) is not, the check is performed on
|
||||
* such table (a register is volatile if it belongs to one of
|
||||
* the ranges specified by volatile_table).
|
||||
* @precious_reg: Optional callback returning true if the rgister
|
||||
* should not be read outside of a call from the driver
|
||||
* (eg, a clear on read interrupt status register).
|
||||
* should not be read outside of a call from the driver
|
||||
* (eg, a clear on read interrupt status register). If this
|
||||
* field is NULL but precious_table (see below) is not, the
|
||||
* check is performed on such table (a register is precious if
|
||||
* it belongs to one of the ranges specified by precious_table).
|
||||
* @lock: Optional lock callback (overrides regmap's default lock
|
||||
* function, based on spinlock or mutex).
|
||||
* @unlock: As above for unlocking.
|
||||
* @lock_arg: this field is passed as the only argument of lock/unlock
|
||||
* functions (ignored in case regular lock/unlock functions
|
||||
* are not overridden).
|
||||
*
|
||||
* @max_register: Optional, specifies the maximum valid register index.
|
||||
* @wr_table: Optional, points to a struct regmap_access_table specifying
|
||||
* valid ranges for write access.
|
||||
* @rd_table: As above, for read access.
|
||||
* @volatile_table: As above, for volatile registers.
|
||||
* @precious_table: As above, for precious registers.
|
||||
* @reg_defaults: Power on reset values for registers (for use with
|
||||
* register cache support).
|
||||
* @num_reg_defaults: Number of elements in reg_defaults.
|
||||
@@ -116,8 +173,15 @@ struct regmap_config {
|
||||
bool (*readable_reg)(struct device *dev, unsigned int reg);
|
||||
bool (*volatile_reg)(struct device *dev, unsigned int reg);
|
||||
bool (*precious_reg)(struct device *dev, unsigned int reg);
|
||||
regmap_lock lock;
|
||||
regmap_unlock unlock;
|
||||
void *lock_arg;
|
||||
|
||||
unsigned int max_register;
|
||||
const struct regmap_access_table *wr_table;
|
||||
const struct regmap_access_table *rd_table;
|
||||
const struct regmap_access_table *volatile_table;
|
||||
const struct regmap_access_table *precious_table;
|
||||
const struct reg_default *reg_defaults;
|
||||
unsigned int num_reg_defaults;
|
||||
enum regcache_type cache_type;
|
||||
@@ -133,7 +197,7 @@ struct regmap_config {
|
||||
enum regmap_endian val_format_endian;
|
||||
|
||||
const struct regmap_range_cfg *ranges;
|
||||
unsigned int n_ranges;
|
||||
unsigned int num_ranges;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -142,6 +206,8 @@ struct regmap_config {
|
||||
* 1. page selector register update;
|
||||
* 2. access through data window registers.
|
||||
*
|
||||
* @name: Descriptive name for diagnostics
|
||||
*
|
||||
* @range_min: Address of the lowest register address in virtual range.
|
||||
* @range_max: Address of the highest register in virtual range.
|
||||
*
|
||||
@@ -153,6 +219,8 @@ struct regmap_config {
|
||||
* @window_len: Number of registers in data window.
|
||||
*/
|
||||
struct regmap_range_cfg {
|
||||
const char *name;
|
||||
|
||||
/* Registers of virtual address range */
|
||||
unsigned int range_min;
|
||||
unsigned int range_max;
|
||||
@@ -181,7 +249,9 @@ typedef void (*regmap_hw_free_context)(void *context);
|
||||
* Description of a hardware bus for the register map infrastructure.
|
||||
*
|
||||
* @fast_io: Register IO is fast. Use a spinlock instead of a mutex
|
||||
* to perform locking.
|
||||
* to perform locking. This field is ignored if custom lock/unlock
|
||||
* functions are used (see fields lock/unlock of
|
||||
* struct regmap_config).
|
||||
* @write: Write operation.
|
||||
* @gather_write: Write operation with split register/value, return -ENOTSUPP
|
||||
* if not implemented on a given device.
|
||||
@@ -262,6 +332,16 @@ void regcache_mark_dirty(struct regmap *map);
|
||||
int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
|
||||
int num_regs);
|
||||
|
||||
static inline bool regmap_reg_in_range(unsigned int reg,
|
||||
const struct regmap_range *range)
|
||||
{
|
||||
return reg >= range->range_min && reg <= range->range_max;
|
||||
}
|
||||
|
||||
bool regmap_reg_in_ranges(unsigned int reg,
|
||||
const struct regmap_range *ranges,
|
||||
unsigned int nranges);
|
||||
|
||||
/**
|
||||
* Description of an IRQ for the generic regmap irq_chip.
|
||||
*
|
||||
@@ -317,6 +397,7 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
|
||||
void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data);
|
||||
int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data);
|
||||
int regmap_irq_get_virq(struct regmap_irq_chip_data *data, int irq);
|
||||
struct irq_domain *regmap_irq_get_domain(struct regmap_irq_chip_data *data);
|
||||
|
||||
#else
|
||||
|
||||
|
||||
Reference in New Issue
Block a user