regmap: Allow installing custom reg_update_bits function
[cascardo/linux.git] / include / linux / regmap.h
index 4a67590..b49d413 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/rbtree.h>
 #include <linux/err.h>
 #include <linux/bug.h>
+#include <linux/lockdep.h>
 
 struct module;
 struct device;
@@ -51,14 +52,17 @@ struct reg_default {
 };
 
 /**
- * Register/value pairs for sequences of writes
+ * Register/value pairs for sequences of writes with an optional delay in
+ * microseconds to be applied after each write.
  *
  * @reg: Register address.
  * @def: Register value.
+ * @delay_us: Delay to be applied after the register write in microseconds
  */
 struct reg_sequence {
        unsigned int reg;
        unsigned int def;
+       unsigned int delay_us;
 };
 
 #ifdef CONFIG_REGMAP
@@ -292,6 +296,8 @@ typedef int (*regmap_hw_reg_read)(void *context, unsigned int reg,
                                  unsigned int *val);
 typedef int (*regmap_hw_reg_write)(void *context, unsigned int reg,
                                   unsigned int val);
+typedef int (*regmap_hw_reg_update_bits)(void *context, unsigned int reg,
+                                        unsigned int mask, unsigned int val);
 typedef struct regmap_async *(*regmap_hw_async_alloc)(void);
 typedef void (*regmap_hw_free_context)(void *context);
 
@@ -307,8 +313,12 @@ typedef void (*regmap_hw_free_context)(void *context);
  *                if not implemented  on a given device.
  * @async_write: Write operation which completes asynchronously, optional and
  *               must serialise with respect to non-async I/O.
+ * @reg_write: Write a single register value to the given register address. This
+ *             write operation has to complete when returning from the function.
  * @read: Read operation.  Data is returned in the buffer used to transmit
  *         data.
+ * @reg_read: Read a single register value from a given register address.
+ * @free_context: Free context.
  * @async_alloc: Allocate a regmap_async() structure.
  * @read_flag_mask: Mask to be set in the top byte of the register when doing
  *                  a read.
@@ -318,7 +328,8 @@ typedef void (*regmap_hw_free_context)(void *context);
  * @val_format_endian_default: Default endianness for formatted register
  *     values. Used when the regmap_config specifies DEFAULT. If this is
  *     DEFAULT, BIG is assumed.
- * @async_size: Size of struct used for async work.
+ * @max_raw_read: Max raw read size that can be used on the bus.
+ * @max_raw_write: Max raw write size that can be used on the bus.
  */
 struct regmap_bus {
        bool fast_io;
@@ -326,6 +337,7 @@ struct regmap_bus {
        regmap_hw_gather_write gather_write;
        regmap_hw_async_write async_write;
        regmap_hw_reg_write reg_write;
+       regmap_hw_reg_update_bits reg_update_bits;
        regmap_hw_read read;
        regmap_hw_reg_read reg_read;
        regmap_hw_free_context free_context;
@@ -333,47 +345,186 @@ struct regmap_bus {
        u8 read_flag_mask;
        enum regmap_endian reg_format_endian_default;
        enum regmap_endian val_format_endian_default;
+       size_t max_raw_read;
+       size_t max_raw_write;
 };
 
-struct regmap *regmap_init(struct device *dev,
-                          const struct regmap_bus *bus,
-                          void *bus_context,
-                          const struct regmap_config *config);
+/*
+ * __regmap_init functions.
+ *
+ * These functions take a lock key and name parameter, and should not be called
+ * directly. Instead, use the regmap_init macros that generate a key and name
+ * for each call.
+ */
+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);
+struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
+                                const struct regmap_config *config,
+                                struct lock_class_key *lock_key,
+                                const char *lock_name);
+struct regmap *__regmap_init_spi(struct spi_device *dev,
+                                const struct regmap_config *config,
+                                struct lock_class_key *lock_key,
+                                const char *lock_name);
+struct regmap *__regmap_init_spmi_base(struct spmi_device *dev,
+                                      const struct regmap_config *config,
+                                      struct lock_class_key *lock_key,
+                                      const char *lock_name);
+struct regmap *__regmap_init_spmi_ext(struct spmi_device *dev,
+                                     const struct regmap_config *config,
+                                     struct lock_class_key *lock_key,
+                                     const char *lock_name);
+struct regmap *__regmap_init_mmio_clk(struct device *dev, const char *clk_id,
+                                     void __iomem *regs,
+                                     const struct regmap_config *config,
+                                     struct lock_class_key *lock_key,
+                                     const char *lock_name);
+struct regmap *__regmap_init_ac97(struct snd_ac97 *ac97,
+                                 const struct regmap_config *config,
+                                 struct lock_class_key *lock_key,
+                                 const char *lock_name);
+
+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);
+struct regmap *__devm_regmap_init_i2c(struct i2c_client *i2c,
+                                     const struct regmap_config *config,
+                                     struct lock_class_key *lock_key,
+                                     const char *lock_name);
+struct regmap *__devm_regmap_init_spi(struct spi_device *dev,
+                                     const struct regmap_config *config,
+                                     struct lock_class_key *lock_key,
+                                     const char *lock_name);
+struct regmap *__devm_regmap_init_spmi_base(struct spmi_device *dev,
+                                           const struct regmap_config *config,
+                                           struct lock_class_key *lock_key,
+                                           const char *lock_name);
+struct regmap *__devm_regmap_init_spmi_ext(struct spmi_device *dev,
+                                          const struct regmap_config *config,
+                                          struct lock_class_key *lock_key,
+                                          const char *lock_name);
+struct regmap *__devm_regmap_init_mmio_clk(struct device *dev,
+                                          const char *clk_id,
+                                          void __iomem *regs,
+                                          const struct regmap_config *config,
+                                          struct lock_class_key *lock_key,
+                                          const char *lock_name);
+struct regmap *__devm_regmap_init_ac97(struct snd_ac97 *ac97,
+                                      const struct regmap_config *config,
+                                      struct lock_class_key *lock_key,
+                                      const char *lock_name);
+
+/*
+ * Wrapper for regmap_init macros to include a unique lockdep key and name
+ * for each call. No-op if CONFIG_LOCKDEP is not set.
+ *
+ * @fn: Real function to call (in the form __[*_]regmap_init[_*])
+ * @name: Config variable name (#config in the calling macro)
+ **/
+#ifdef CONFIG_LOCKDEP
+#define __regmap_lockdep_wrapper(fn, name, ...)                                \
+(                                                                      \
+       ({                                                              \
+               static struct lock_class_key _key;                      \
+               fn(__VA_ARGS__, &_key,                                  \
+                       KBUILD_BASENAME ":"                             \
+                       __stringify(__LINE__) ":"                       \
+                       "(" name ")->lock");                            \
+       })                                                              \
+)
+#else
+#define __regmap_lockdep_wrapper(fn, name, ...) fn(__VA_ARGS__, NULL, NULL)
+#endif
+
+/**
+ * regmap_init(): Initialise register map
+ *
+ * @dev: Device that will be interacted with
+ * @bus: Bus-specific callbacks to use with device
+ * @bus_context: Data passed to bus-specific callbacks
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.  This function should generally not be called
+ * directly, it should be called by bus-specific init functions.
+ */
+#define regmap_init(dev, bus, bus_context, config)                     \
+       __regmap_lockdep_wrapper(__regmap_init, #config,                \
+                               dev, bus, bus_context, config)
 int regmap_attach_dev(struct device *dev, struct regmap *map,
-                                const struct regmap_config *config);
-struct regmap *regmap_init_i2c(struct i2c_client *i2c,
-                              const struct regmap_config *config);
-struct regmap *regmap_init_spi(struct spi_device *dev,
-                              const struct regmap_config *config);
-struct regmap *regmap_init_spmi_base(struct spmi_device *dev,
-                                    const struct regmap_config *config);
-struct regmap *regmap_init_spmi_ext(struct spmi_device *dev,
-                                   const struct regmap_config *config);
-struct regmap *regmap_init_mmio_clk(struct device *dev, const char *clk_id,
-                                   void __iomem *regs,
-                                   const struct regmap_config *config);
-struct regmap *regmap_init_ac97(struct snd_ac97 *ac97,
-                               const struct regmap_config *config);
-
-struct regmap *devm_regmap_init(struct device *dev,
-                               const struct regmap_bus *bus,
-                               void *bus_context,
-                               const struct regmap_config *config);
-struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
-                                   const struct regmap_config *config);
-struct regmap *devm_regmap_init_spi(struct spi_device *dev,
-                                   const struct regmap_config *config);
-struct regmap *devm_regmap_init_spmi_base(struct spmi_device *dev,
-                                         const struct regmap_config *config);
-struct regmap *devm_regmap_init_spmi_ext(struct spmi_device *dev,
-                                        const struct regmap_config *config);
-struct regmap *devm_regmap_init_mmio_clk(struct device *dev, const char *clk_id,
-                                        void __iomem *regs,
-                                        const struct regmap_config *config);
-struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97,
-                                    const struct regmap_config *config);
+                     const struct regmap_config *config);
 
-bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
+/**
+ * regmap_init_i2c(): Initialise register map
+ *
+ * @i2c: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_i2c(i2c, config)                                   \
+       __regmap_lockdep_wrapper(__regmap_init_i2c, #config,            \
+                               i2c, config)
+
+/**
+ * regmap_init_spi(): Initialise register map
+ *
+ * @spi: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_spi(dev, config)                                   \
+       __regmap_lockdep_wrapper(__regmap_init_spi, #config,            \
+                               dev, config)
+
+/**
+ * regmap_init_spmi_base(): Create regmap for the Base register space
+ * @sdev:      SPMI device that will be interacted with
+ * @config:    Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_spmi_base(dev, config)                             \
+       __regmap_lockdep_wrapper(__regmap_init_spmi_base, #config,      \
+                               dev, config)
+
+/**
+ * regmap_init_spmi_ext(): Create regmap for Ext register space
+ * @sdev:      Device that will be interacted with
+ * @config:    Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_spmi_ext(dev, config)                              \
+       __regmap_lockdep_wrapper(__regmap_init_spmi_ext, #config,       \
+                               dev, config)
+
+/**
+ * regmap_init_mmio_clk(): Initialise register map with register clock
+ *
+ * @dev: Device that will be interacted with
+ * @clk_id: register clock consumer ID
+ * @regs: Pointer to memory-mapped IO region
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_mmio_clk(dev, clk_id, regs, config)                        \
+       __regmap_lockdep_wrapper(__regmap_init_mmio_clk, #config,       \
+                               dev, clk_id, regs, config)
 
 /**
  * regmap_init_mmio(): Initialise register map
@@ -385,12 +536,109 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
  * The return value will be an ERR_PTR() on error or a valid pointer to
  * a struct regmap.
  */
-static inline struct regmap *regmap_init_mmio(struct device *dev,
-                                       void __iomem *regs,
-                                       const struct regmap_config *config)
-{
-       return regmap_init_mmio_clk(dev, NULL, regs, config);
-}
+#define regmap_init_mmio(dev, regs, config)            \
+       regmap_init_mmio_clk(dev, NULL, regs, config)
+
+/**
+ * regmap_init_ac97(): Initialise AC'97 register map
+ *
+ * @ac97: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_ac97(ac97, config)                                 \
+       __regmap_lockdep_wrapper(__regmap_init_ac97, #config,           \
+                               ac97, config)
+bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
+
+/**
+ * devm_regmap_init(): Initialise managed register map
+ *
+ * @dev: Device that will be interacted with
+ * @bus: Bus-specific callbacks to use with device
+ * @bus_context: Data passed to bus-specific callbacks
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  This function should generally not be called
+ * directly, it should be called by bus-specific init functions.  The
+ * map will be automatically freed by the device management code.
+ */
+#define devm_regmap_init(dev, bus, bus_context, config)                        \
+       __regmap_lockdep_wrapper(__devm_regmap_init, #config,           \
+                               dev, bus, bus_context, config)
+
+/**
+ * devm_regmap_init_i2c(): Initialise managed register map
+ *
+ * @i2c: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_i2c(i2c, config)                              \
+       __regmap_lockdep_wrapper(__devm_regmap_init_i2c, #config,       \
+                               i2c, config)
+
+/**
+ * devm_regmap_init_spi(): Initialise register map
+ *
+ * @spi: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The map will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_spi(dev, config)                              \
+       __regmap_lockdep_wrapper(__devm_regmap_init_spi, #config,       \
+                               dev, config)
+
+/**
+ * devm_regmap_init_spmi_base(): Create managed regmap for Base register space
+ * @sdev:      SPMI device that will be interacted with
+ * @config:    Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_spmi_base(dev, config)                                \
+       __regmap_lockdep_wrapper(__devm_regmap_init_spmi_base, #config, \
+                               dev, config)
+
+/**
+ * devm_regmap_init_spmi_ext(): Create managed regmap for Ext register space
+ * @sdev:      SPMI device that will be interacted with
+ * @config:    Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_spmi_ext(dev, config)                         \
+       __regmap_lockdep_wrapper(__devm_regmap_init_spmi_ext, #config,  \
+                               dev, config)
+
+/**
+ * devm_regmap_init_mmio_clk(): Initialise managed register map with clock
+ *
+ * @dev: Device that will be interacted with
+ * @clk_id: register clock consumer ID
+ * @regs: Pointer to memory-mapped IO region
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_mmio_clk(dev, clk_id, regs, config)           \
+       __regmap_lockdep_wrapper(__devm_regmap_init_mmio_clk, #config,  \
+                               dev, clk_id, regs, config)
 
 /**
  * devm_regmap_init_mmio(): Initialise managed register map
@@ -403,12 +651,22 @@ static inline struct regmap *regmap_init_mmio(struct device *dev,
  * to a struct regmap.  The regmap will be automatically freed by the
  * device management code.
  */
-static inline struct regmap *devm_regmap_init_mmio(struct device *dev,
-                                       void __iomem *regs,
-                                       const struct regmap_config *config)
-{
-       return devm_regmap_init_mmio_clk(dev, NULL, regs, config);
-}
+#define devm_regmap_init_mmio(dev, regs, config)               \
+       devm_regmap_init_mmio_clk(dev, NULL, regs, config)
+
+/**
+ * devm_regmap_init_ac97(): Initialise AC'97 register map
+ *
+ * @ac97: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_ac97(ac97, config)                            \
+       __regmap_lockdep_wrapper(__devm_regmap_init_ac97, #config,      \
+                               ac97, config)
 
 void regmap_exit(struct regmap *map);
 int regmap_reinit_cache(struct regmap *map,
@@ -450,6 +708,8 @@ int regmap_get_max_register(struct regmap *map);
 int regmap_get_reg_stride(struct regmap *map);
 int regmap_async_complete(struct regmap *map);
 bool regmap_can_raw_write(struct regmap *map);
+size_t regmap_get_raw_read_max(struct regmap *map);
+size_t regmap_get_raw_write_max(struct regmap *map);
 
 int regcache_sync(struct regmap *map);
 int regcache_sync_region(struct regmap *map, unsigned int min,