// SPDX-License-Identifier: GPL-2.0 // // Register map access API // // Copyright 2011 Wolfson Microelectronics plc // // Author: Mark Brown <[email protected]> #include <linux/device.h> #include <linux/slab.h> #include <linux/export.h> #include <linux/mutex.h> #include <linux/err.h> #include <linux/property.h> #include <linux/rbtree.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/log2.h> #include <linux/hwspinlock.h> #include <linux/unaligned.h> #define CREATE_TRACE_POINTS #include "trace.h" #include "internal.h" /* * Sometimes for failures during very early init the trace * infrastructure isn't available early enough to be used. For this * sort of problem defining LOG_DEVICE will add printks for basic * register I/O on a specific device. */ #undef LOG_DEVICE #ifdef LOG_DEVICE static inline bool regmap_should_log(struct regmap *map) { return (map->dev && strcmp(dev_name(map->dev), LOG_DEVICE) == 0); } #else static inline bool regmap_should_log(struct regmap *map) { … } #endif static int _regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change, bool force_write); static int _regmap_bus_reg_read(void *context, unsigned int reg, unsigned int *val); static int _regmap_bus_read(void *context, unsigned int reg, unsigned int *val); static int _regmap_bus_formatted_write(void *context, unsigned int reg, unsigned int val); static int _regmap_bus_reg_write(void *context, unsigned int reg, unsigned int val); static int _regmap_bus_raw_write(void *context, unsigned int reg, unsigned int val); bool regmap_reg_in_ranges(unsigned int reg, const struct regmap_range *ranges, unsigned int nranges) { … } EXPORT_SYMBOL_GPL(…); bool regmap_check_range_table(struct regmap *map, unsigned int reg, const struct regmap_access_table *table) { … } EXPORT_SYMBOL_GPL(…); bool regmap_writeable(struct regmap *map, unsigned int reg) { … } bool regmap_cached(struct regmap *map, unsigned int reg) { … } bool regmap_readable(struct regmap *map, unsigned int reg) { … } bool regmap_volatile(struct regmap *map, unsigned int reg) { … } bool regmap_precious(struct regmap *map, unsigned int reg) { … } bool regmap_writeable_noinc(struct regmap *map, unsigned int reg) { … } bool regmap_readable_noinc(struct regmap *map, unsigned int reg) { … } static bool regmap_volatile_range(struct regmap *map, unsigned int reg, size_t num) { … } static void regmap_format_12_20_write(struct regmap *map, unsigned int reg, unsigned int val) { … } static void regmap_format_2_6_write(struct regmap *map, unsigned int reg, unsigned int val) { … } static void regmap_format_4_12_write(struct regmap *map, unsigned int reg, unsigned int val) { … } static void regmap_format_7_9_write(struct regmap *map, unsigned int reg, unsigned int val) { … } static void regmap_format_7_17_write(struct regmap *map, unsigned int reg, unsigned int val) { … } static void regmap_format_10_14_write(struct regmap *map, unsigned int reg, unsigned int val) { … } static void regmap_format_8(void *buf, unsigned int val, unsigned int shift) { … } static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift) { … } static void regmap_format_16_le(void *buf, unsigned int val, unsigned int shift) { … } static void regmap_format_16_native(void *buf, unsigned int val, unsigned int shift) { … } static void regmap_format_24_be(void *buf, unsigned int val, unsigned int shift) { … } static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift) { … } static void regmap_format_32_le(void *buf, unsigned int val, unsigned int shift) { … } static void regmap_format_32_native(void *buf, unsigned int val, unsigned int shift) { … } static void regmap_parse_inplace_noop(void *buf) { … } static unsigned int regmap_parse_8(const void *buf) { … } static unsigned int regmap_parse_16_be(const void *buf) { … } static unsigned int regmap_parse_16_le(const void *buf) { … } static void regmap_parse_16_be_inplace(void *buf) { … } static void regmap_parse_16_le_inplace(void *buf) { … } static unsigned int regmap_parse_16_native(const void *buf) { … } static unsigned int regmap_parse_24_be(const void *buf) { … } static unsigned int regmap_parse_32_be(const void *buf) { … } static unsigned int regmap_parse_32_le(const void *buf) { … } static void regmap_parse_32_be_inplace(void *buf) { … } static void regmap_parse_32_le_inplace(void *buf) { … } static unsigned int regmap_parse_32_native(const void *buf) { … } static void regmap_lock_hwlock(void *__map) { … } static void regmap_lock_hwlock_irq(void *__map) { … } static void regmap_lock_hwlock_irqsave(void *__map) { … } static void regmap_unlock_hwlock(void *__map) { … } static void regmap_unlock_hwlock_irq(void *__map) { … } static void regmap_unlock_hwlock_irqrestore(void *__map) { … } static void regmap_lock_unlock_none(void *__map) { … } static void regmap_lock_mutex(void *__map) { … } static void regmap_unlock_mutex(void *__map) { … } static void regmap_lock_spinlock(void *__map) __acquires(&map->spinlock) { … } static void regmap_unlock_spinlock(void *__map) __releases(&map->spinlock) { … } static void regmap_lock_raw_spinlock(void *__map) __acquires(&map->raw_spinlock) { … } static void regmap_unlock_raw_spinlock(void *__map) __releases(&map->raw_spinlock) { … } static void dev_get_regmap_release(struct device *dev, void *res) { … } static bool _regmap_range_add(struct regmap *map, struct regmap_range_node *data) { … } static struct regmap_range_node *_regmap_range_lookup(struct regmap *map, unsigned int reg) { … } static void regmap_range_exit(struct regmap *map) { … } static int regmap_set_name(struct regmap *map, const struct regmap_config *config) { … } int regmap_attach_dev(struct device *dev, struct regmap *map, const struct regmap_config *config) { … } EXPORT_SYMBOL_GPL(…); static enum regmap_endian regmap_get_reg_endian(const struct regmap_bus *bus, const struct regmap_config *config) { … } enum regmap_endian regmap_get_val_endian(struct device *dev, const struct regmap_bus *bus, const struct regmap_config *config) { … } EXPORT_SYMBOL_GPL(…); struct regmap *__regmap_init(struct device *dev, const struct regmap_bus *bus, void *bus_context, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { … } EXPORT_SYMBOL_GPL(…); static void devm_regmap_release(struct device *dev, void *res) { … } struct regmap *__devm_regmap_init(struct device *dev, const struct regmap_bus *bus, void *bus_context, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { … } EXPORT_SYMBOL_GPL(…); static void regmap_field_init(struct regmap_field *rm_field, struct regmap *regmap, struct reg_field reg_field) { … } /** * devm_regmap_field_alloc() - Allocate and initialise a register field. * * @dev: Device that will be interacted with * @regmap: regmap bank in which this register field is located. * @reg_field: Register field with in the bank. * * The return value will be an ERR_PTR() on error or a valid pointer * to a struct regmap_field. The regmap_field will be automatically freed * by the device management code. */ struct regmap_field *devm_regmap_field_alloc(struct device *dev, struct regmap *regmap, struct reg_field reg_field) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_field_bulk_alloc() - Allocate and initialise a bulk register field. * * @regmap: regmap bank in which this register field is located. * @rm_field: regmap register fields within the bank. * @reg_field: Register fields within the bank. * @num_fields: Number of register fields. * * The return value will be an -ENOMEM on error or zero for success. * Newly allocated regmap_fields should be freed by calling * regmap_field_bulk_free() */ int regmap_field_bulk_alloc(struct regmap *regmap, struct regmap_field **rm_field, const struct reg_field *reg_field, int num_fields) { … } EXPORT_SYMBOL_GPL(…); /** * devm_regmap_field_bulk_alloc() - Allocate and initialise a bulk register * fields. * * @dev: Device that will be interacted with * @regmap: regmap bank in which this register field is located. * @rm_field: regmap register fields within the bank. * @reg_field: Register fields within the bank. * @num_fields: Number of register fields. * * The return value will be an -ENOMEM on error or zero for success. * Newly allocated regmap_fields will be automatically freed by the * device management code. */ int devm_regmap_field_bulk_alloc(struct device *dev, struct regmap *regmap, struct regmap_field **rm_field, const struct reg_field *reg_field, int num_fields) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_field_bulk_free() - Free register field allocated using * regmap_field_bulk_alloc. * * @field: regmap fields which should be freed. */ void regmap_field_bulk_free(struct regmap_field *field) { … } EXPORT_SYMBOL_GPL(…); /** * devm_regmap_field_bulk_free() - Free a bulk register field allocated using * devm_regmap_field_bulk_alloc. * * @dev: Device that will be interacted with * @field: regmap field which should be freed. * * Free register field allocated using devm_regmap_field_bulk_alloc(). Usually * drivers need not call this function, as the memory allocated via devm * will be freed as per device-driver life-cycle. */ void devm_regmap_field_bulk_free(struct device *dev, struct regmap_field *field) { … } EXPORT_SYMBOL_GPL(…); /** * devm_regmap_field_free() - Free a register field allocated using * devm_regmap_field_alloc. * * @dev: Device that will be interacted with * @field: regmap field which should be freed. * * Free register field allocated using devm_regmap_field_alloc(). Usually * drivers need not call this function, as the memory allocated via devm * will be freed as per device-driver life-cyle. */ void devm_regmap_field_free(struct device *dev, struct regmap_field *field) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_field_alloc() - Allocate and initialise a register field. * * @regmap: regmap bank in which this register field is located. * @reg_field: Register field with in the bank. * * The return value will be an ERR_PTR() on error or a valid pointer * to a struct regmap_field. The regmap_field should be freed by the * user once its finished working with it using regmap_field_free(). */ struct regmap_field *regmap_field_alloc(struct regmap *regmap, struct reg_field reg_field) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_field_free() - Free register field allocated using * regmap_field_alloc. * * @field: regmap field which should be freed. */ void regmap_field_free(struct regmap_field *field) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_reinit_cache() - Reinitialise the current register cache * * @map: Register map to operate on. * @config: New configuration. Only the cache data will be used. * * Discard any existing register cache for the map and initialize a * new cache. This can be used to restore the cache to defaults or to * update the cache configuration to reflect runtime discovery of the * hardware. * * No explicit locking is done here, the user needs to ensure that * this function will not race with other calls to regmap. */ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_exit() - Free a previously allocated register map * * @map: Register map to operate on. */ void regmap_exit(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); static int dev_get_regmap_match(struct device *dev, void *res, void *data) { … } /** * dev_get_regmap() - Obtain the regmap (if any) for a device * * @dev: Device to retrieve the map for * @name: Optional name for the register map, usually NULL. * * Returns the regmap for the device if one is present, or NULL. If * name is specified then it must match the name specified when * registering the device, if it is NULL then the first regmap found * will be used. Devices with multiple register maps are very rare, * generic code should normally not need to specify a name. */ struct regmap *dev_get_regmap(struct device *dev, const char *name) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_get_device() - Obtain the device from a regmap * * @map: Register map to operate on. * * Returns the underlying device that the regmap has been created for. */ struct device *regmap_get_device(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); static int _regmap_select_page(struct regmap *map, unsigned int *reg, struct regmap_range_node *range, unsigned int val_num) { … } static void regmap_set_work_buf_flag_mask(struct regmap *map, int max_bytes, unsigned long mask) { … } static unsigned int regmap_reg_addr(struct regmap *map, unsigned int reg) { … } static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, const void *val, size_t val_len, bool noinc) { … } /** * regmap_can_raw_write - Test if regmap_raw_write() is supported * * @map: Map to check. */ bool regmap_can_raw_write(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_get_raw_read_max - Get the maximum size we can read * * @map: Map to check. */ size_t regmap_get_raw_read_max(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_get_raw_write_max - Get the maximum size we can read * * @map: Map to check. */ size_t regmap_get_raw_write_max(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); static int _regmap_bus_formatted_write(void *context, unsigned int reg, unsigned int val) { … } static int _regmap_bus_reg_write(void *context, unsigned int reg, unsigned int val) { … } static int _regmap_bus_raw_write(void *context, unsigned int reg, unsigned int val) { … } static inline void *_regmap_map_get_context(struct regmap *map) { … } int _regmap_write(struct regmap *map, unsigned int reg, unsigned int val) { … } /** * regmap_write() - Write a value to a single register * * @map: Register map to write to * @reg: Register to write to * @val: Value to be written * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_write_async() - Write a value to a single register asynchronously * * @map: Register map to write to * @reg: Register to write to * @val: Value to be written * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_write_async(struct regmap *map, unsigned int reg, unsigned int val) { … } EXPORT_SYMBOL_GPL(…); int _regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len, bool noinc) { … } /** * regmap_raw_write() - Write raw values to one or more registers * * @map: Register map to write to * @reg: Initial register to write to * @val: Block of data to be written, laid out for direct transmission to the * device * @val_len: Length of data pointed to by val. * * This function is intended to be used for things like firmware * download where a large block of data needs to be transferred to the * device. No formatting will be done on the data provided. * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { … } EXPORT_SYMBOL_GPL(…); static int regmap_noinc_readwrite(struct regmap *map, unsigned int reg, void *val, unsigned int val_len, bool write) { … } /** * regmap_noinc_write(): Write data to a register without incrementing the * register number * * @map: Register map to write to * @reg: Register to write to * @val: Pointer to data buffer * @val_len: Length of output buffer in bytes. * * The regmap API usually assumes that bulk bus write operations will write a * range of registers. Some devices have certain registers for which a write * operation can write to an internal FIFO. * * The target register must be volatile but registers after it can be * completely unrelated cacheable registers. * * This will attempt multiple writes as required to write val_len bytes. * * A value of zero will be returned on success, a negative errno will be * returned in error cases. */ int regmap_noinc_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_field_update_bits_base() - Perform a read/modify/write cycle a * register field. * * @field: Register field to write to * @mask: Bitmask to change * @val: Value to be written * @change: Boolean indicating if a write was done * @async: Boolean indicating asynchronously * @force: Boolean indicating use force update * * Perform a read/modify/write cycle on the register field with change, * async, force option. * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_field_update_bits_base(struct regmap_field *field, unsigned int mask, unsigned int val, bool *change, bool async, bool force) { … } EXPORT_SYMBOL_GPL(…); /** * 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) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_fields_update_bits_base() - Perform a read/modify/write cycle a * register field with port ID * * @field: Register field to write to * @id: port ID * @mask: Bitmask to change * @val: Value to be written * @change: Boolean indicating if a write was done * @async: Boolean indicating asynchronously * @force: Boolean indicating use force update * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_fields_update_bits_base(struct regmap_field *field, unsigned int id, unsigned int mask, unsigned int val, bool *change, bool async, bool force) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_bulk_write() - Write multiple registers to the device * * @map: Register map to write to * @reg: First register to be write from * @val: Block of data to be written, in native register size for device * @val_count: Number of registers to write * * This function is intended to be used for writing a large block of * data to the device either in single transfer or multiple transfer. * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, size_t val_count) { … } EXPORT_SYMBOL_GPL(…); /* * _regmap_raw_multi_reg_write() * * the (register,newvalue) pairs in regs have not been formatted, but * they are all in the same page and have been changed to being page * relative. The page register has been written if that was necessary. */ static int _regmap_raw_multi_reg_write(struct regmap *map, const struct reg_sequence *regs, size_t num_regs) { … } static unsigned int _regmap_register_page(struct regmap *map, unsigned int reg, struct regmap_range_node *range) { … } static int _regmap_range_multi_paged_reg_write(struct regmap *map, struct reg_sequence *regs, size_t num_regs) { … } static int _regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs, size_t num_regs) { … } /** * regmap_multi_reg_write() - Write multiple registers to the device * * @map: Register map to write to * @regs: Array of structures containing register,value to be written * @num_regs: Number of registers to write * * Write multiple registers to the device where the set of register, value * pairs are supplied in any order, possibly not all in a single range. * * The 'normal' block write mode will send ultimately send data on the * target bus as R,V1,V2,V3,..,Vn where successively higher registers are * addressed. However, this alternative block multi write mode will send * the data as R1,V1,R2,V2,..,Rn,Vn on the target bus. The target device * must of course support the mode. * * A value of zero will be returned on success, a negative errno will be * returned in error cases. */ int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs, int num_regs) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_multi_reg_write_bypassed() - Write multiple registers to the * device but not the cache * * @map: Register map to write to * @regs: Array of structures containing register,value to be written * @num_regs: Number of registers to write * * Write multiple registers to the device but not the cache where the set * of register are supplied in any order. * * This function is intended to be used for writing a large block of data * atomically to the device in single transfer for those I2C client devices * that implement this alternative block write mode. * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_multi_reg_write_bypassed(struct regmap *map, const struct reg_sequence *regs, int num_regs) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_raw_write_async() - Write raw values to one or more registers * asynchronously * * @map: Register map to write to * @reg: Initial register to write to * @val: Block of data to be written, laid out for direct transmission to the * device. Must be valid until regmap_async_complete() is called. * @val_len: Length of data pointed to by val. * * This function is intended to be used for things like firmware * download where a large block of data needs to be transferred to the * device. No formatting will be done on the data provided. * * If supported by the underlying bus the write will be scheduled * asynchronously, helping maximise I/O speed on higher speed buses * like SPI. regmap_async_complete() can be called to ensure that all * asynchrnous writes have been completed. * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_raw_write_async(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { … } EXPORT_SYMBOL_GPL(…); static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, unsigned int val_len, bool noinc) { … } static int _regmap_bus_reg_read(void *context, unsigned int reg, unsigned int *val) { … } static int _regmap_bus_read(void *context, unsigned int reg, unsigned int *val) { … } static int _regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) { … } /** * regmap_read() - Read a value from a single register * * @map: Register map to read from * @reg: Register to be read from * @val: Pointer to store read value * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_read_bypassed() - Read a value from a single register direct * from the device, bypassing the cache * * @map: Register map to read from * @reg: Register to be read from * @val: Pointer to store read value * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_raw_read() - Read raw data from the device * * @map: Register map to read from * @reg: First register to be read from * @val: Pointer to store read value * @val_len: Size of data to read * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, size_t val_len) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_noinc_read(): Read data from a register without incrementing the * register number * * @map: Register map to read from * @reg: Register to read from * @val: Pointer to data buffer * @val_len: Length of output buffer in bytes. * * The regmap API usually assumes that bulk read operations will read a * range of registers. Some devices have certain registers for which a read * operation read will read from an internal FIFO. * * The target register must be volatile but registers after it can be * completely unrelated cacheable registers. * * This will attempt multiple reads as required to read val_len bytes. * * A value of zero will be returned on success, a negative errno will be * returned in error cases. */ int regmap_noinc_read(struct regmap *map, unsigned int reg, void *val, size_t val_len) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_field_read(): Read a value to a single register field * * @field: Register field to read from * @val: Pointer to store read value * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_field_read(struct regmap_field *field, unsigned int *val) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_fields_read() - Read a value to a single register field with port ID * * @field: Register field to read from * @id: port ID * @val: Pointer to store read value * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_fields_read(struct regmap_field *field, unsigned int id, unsigned int *val) { … } EXPORT_SYMBOL_GPL(…); static int _regmap_bulk_read(struct regmap *map, unsigned int reg, unsigned int *regs, void *val, size_t val_count) { … } /** * regmap_bulk_read() - Read multiple sequential registers from the device * * @map: Register map to read from * @reg: First register to be read from * @val: Pointer to store read value, in native register size for device * @val_count: Number of registers to read * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, size_t val_count) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_multi_reg_read() - Read multiple non-sequential registers from the device * * @map: Register map to read from * @regs: Array of registers to read from * @val: Pointer to store read value, in native register size for device * @val_count: Number of registers to read * * A value of zero will be returned on success, a negative errno will * be returned in error cases. */ int regmap_multi_reg_read(struct regmap *map, unsigned int *regs, void *val, size_t val_count) { … } EXPORT_SYMBOL_GPL(…); static int _regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change, bool force_write) { … } /** * regmap_update_bits_base() - Perform a read/modify/write cycle on a register * * @map: Register map to update * @reg: Register to update * @mask: Bitmask to change * @val: New value for bitmask * @change: Boolean indicating if a write was done * @async: Boolean indicating asynchronously * @force: Boolean indicating use force update * * Perform a read/modify/write cycle on a register map with change, async, force * options. * * If async is true: * * With most buses the read must be done synchronously so this is most useful * for devices with a cache which do not need to interact with the hardware to * determine the current register value. * * Returns zero for success, a negative number on error. */ int regmap_update_bits_base(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val, bool *change, bool async, bool force) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_test_bits() - Check if all specified bits are set in a register. * * @map: Register map to operate on * @reg: Register to read from * @bits: Bits to test * * Returns 0 if at least one of the tested bits is not set, 1 if all tested * bits are set and a negative error number if the underlying regmap_read() * fails. */ int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits) { … } EXPORT_SYMBOL_GPL(…); void regmap_async_complete_cb(struct regmap_async *async, int ret) { … } EXPORT_SYMBOL_GPL(…); static int regmap_async_is_done(struct regmap *map) { … } /** * regmap_async_complete - Ensure all asynchronous I/O has completed. * * @map: Map to operate on. * * Blocks until any pending asynchronous I/O has completed. Returns * an error code for any failed I/O operations. */ int regmap_async_complete(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_register_patch - Register and apply register updates to be applied * on device initialistion * * @map: Register map to apply updates to. * @regs: Values to update. * @num_regs: Number of entries in regs. * * Register a set of register updates to be applied to the device * whenever the device registers are synchronised with the cache and * apply them immediately. Typically this is used to apply * corrections to be applied to the device defaults on startup, such * as the updates some vendors provide to undocumented registers. * * The caller must ensure that this function cannot be called * concurrently with either itself or regcache_sync(). */ int regmap_register_patch(struct regmap *map, const struct reg_sequence *regs, int num_regs) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_get_val_bytes() - Report the size of a register value * * @map: Register map to operate on. * * Report the size of a register value, mainly intended to for use by * generic infrastructure built on top of regmap. */ int regmap_get_val_bytes(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_get_max_register() - Report the max register value * * @map: Register map to operate on. * * Report the max register value, mainly intended to for use by * generic infrastructure built on top of regmap. */ int regmap_get_max_register(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_get_reg_stride() - Report the register address stride * * @map: Register map to operate on. * * Report the register address stride, mainly intended to for use by * generic infrastructure built on top of regmap. */ int regmap_get_reg_stride(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); /** * regmap_might_sleep() - Returns whether a regmap access might sleep. * * @map: Register map to operate on. * * Returns true if an access to the register might sleep, else false. */ bool regmap_might_sleep(struct regmap *map) { … } EXPORT_SYMBOL_GPL(…); int regmap_parse_val(struct regmap *map, const void *buf, unsigned int *val) { … } EXPORT_SYMBOL_GPL(…); static int __init regmap_initcall(void) { … } postcore_initcall(regmap_initcall);