Merge branch 'for-linus' of git://opensource.wolfsonmicro.com/regmap

* 'for-linus' of git://opensource.wolfsonmicro.com/regmap: (62 commits)
  mfd: Enable rbtree cache for wm831x devices
  regmap: Support some block operations on cached devices
  regmap: Allow caches for devices with no defaults
  regmap: Ensure rbtree syncs registers set to zero properly
  regmap: Allow rbtree to cache zero default values
  regmap: Warn on raw I/O as well as bulk reads that bypass cache
  regmap: Return a sensible error code if we fail to read the cache
  regmap: Use bsearch() to search the register defaults
  regmap: Fix doc comment
  regmap: Optimize the lookup path to use binary search
  regmap: Ensure we scream if we enable cache bypass/only at the same time
  regmap: Implement regcache_cache_bypass helper function
  regmap: Save/restore the bypass state upon syncing
  regmap: Lock the sync path, ensure we use the lockless _regmap_write()
  regmap: Fix apostrophe usage
  regmap: Make _regmap_write() global
  regmap: Fix lock used for regcache_cache_only()
  regmap: Grab the lock in regcache_cache_only()
  regmap: Modify map->cache_bypass directly
  regmap: Fix regcache_sync generic implementation
  ...
This commit is contained in:
Linus Torvalds
2011-10-25 13:57:45 +02:00
23 changed files with 2420 additions and 566 deletions
+7 -5
View File
@@ -18,6 +18,7 @@
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/regmap.h>
/*
* Register values.
@@ -361,12 +362,8 @@ struct wm831x {
struct mutex io_lock;
struct device *dev;
int (*read_dev)(struct wm831x *wm831x, unsigned short reg,
int bytes, void *dest);
int (*write_dev)(struct wm831x *wm831x, unsigned short reg,
int bytes, void *src);
void *control_data;
struct regmap *regmap;
int irq; /* Our chip IRQ */
struct mutex irq_lock;
@@ -374,6 +371,8 @@ struct wm831x {
int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */
int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */
bool soft_shutdown;
/* Chip revision based flags */
unsigned has_gpio_ena:1; /* Has GPIO enable bit */
unsigned has_cs_sts:1; /* Has current sink status bit */
@@ -412,8 +411,11 @@ int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq);
void wm831x_device_exit(struct wm831x *wm831x);
int wm831x_device_suspend(struct wm831x *wm831x);
void wm831x_device_shutdown(struct wm831x *wm831x);
int wm831x_irq_init(struct wm831x *wm831x, int irq);
void wm831x_irq_exit(struct wm831x *wm831x);
void wm831x_auxadc_init(struct wm831x *wm831x);
extern struct regmap_config wm831x_regmap_config;
#endif
+3
View File
@@ -123,6 +123,9 @@ struct wm831x_pdata {
/** Disable the touchscreen */
bool disable_touch;
/** The driver should initiate a power off sequence during shutdown */
bool soft_shutdown;
int irq_base;
int gpio_base;
int gpio_defaults[WM831X_GPIO_NUM];
+3 -4
View File
@@ -25,16 +25,15 @@
#include <linux/mutex.h>
#include <linux/platform_device.h>
struct regmap;
#define WM8400_REGISTER_COUNT 0x55
struct wm8400 {
struct device *dev;
int (*read_dev)(void *data, char reg, int count, u16 *dst);
int (*write_dev)(void *data, char reg, int count, const u16 *src);
struct mutex io_lock;
void *io_data;
struct regmap *regmap;
u16 reg_cache[WM8400_REGISTER_COUNT];
+2 -7
View File
@@ -24,6 +24,7 @@ enum wm8994_type {
struct regulator_dev;
struct regulator_bulk_data;
struct regmap;
#define WM8994_NUM_GPIO_REGS 11
#define WM8994_NUM_LDO_REGS 2
@@ -50,18 +51,12 @@ struct regulator_bulk_data;
#define WM8994_IRQ_GPIO(x) (x + WM8994_IRQ_TEMP_WARN)
struct wm8994 {
struct mutex io_lock;
struct mutex irq_lock;
enum wm8994_type type;
struct device *dev;
int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
int bytes, void *dest);
int (*write_dev)(struct wm8994 *wm8994, unsigned short reg,
int bytes, const void *src);
void *control_data;
struct regmap *regmap;
int gpio_base;
int irq_base;
+72 -7
View File
@@ -20,9 +20,77 @@
struct i2c_client;
struct spi_device;
/* An enum of all the supported cache types */
enum regcache_type {
REGCACHE_NONE,
REGCACHE_INDEXED,
REGCACHE_RBTREE,
REGCACHE_LZO
};
/**
* Default value for a register. We use an array of structs rather
* than a simple array as many modern devices have very sparse
* register maps.
*
* @reg: Register address.
* @def: Register default value.
*/
struct reg_default {
unsigned int reg;
unsigned int def;
};
/**
* Configuration for the register map of a device.
*
* @reg_bits: Number of bits in a register address, mandatory.
* @val_bits: Number of bits in a register value, mandatory.
*
* @writeable_reg: Optional callback returning true if the register
* can be written to.
* @readable_reg: Optional callback returning true if the register
* can be read from.
* @volatile_reg: Optional callback returning true if the register
* value can't be cached.
* @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).
*
* @max_register: Optional, specifies the maximum valid register index.
* @reg_defaults: Power on reset values for registers (for use with
* register cache support).
* @num_reg_defaults: Number of elements in reg_defaults.
*
* @read_flag_mask: Mask to be set in the top byte of the register when doing
* a read.
* @write_flag_mask: Mask to be set in the top byte of the register when doing
* a write. If both read_flag_mask and write_flag_mask are
* empty the regmap_bus default masks are used.
*
* @cache_type: The actual cache type.
* @reg_defaults_raw: Power on reset values for registers (for use with
* register cache support).
* @num_reg_defaults_raw: Number of elements in reg_defaults_raw.
*/
struct regmap_config {
int reg_bits;
int val_bits;
bool (*writeable_reg)(struct device *dev, unsigned int reg);
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);
unsigned int max_register;
struct reg_default *reg_defaults;
unsigned int num_reg_defaults;
enum regcache_type cache_type;
const void *reg_defaults_raw;
unsigned int num_reg_defaults_raw;
u8 read_flag_mask;
u8 write_flag_mask;
};
typedef int (*regmap_hw_write)(struct device *dev, const void *data,
@@ -37,25 +105,18 @@ typedef int (*regmap_hw_read)(struct device *dev,
/**
* Description of a hardware bus for the register map infrastructure.
*
* @list: Internal use.
* @type: Bus type, used to identify bus to be used for a device.
* @write: Write operation.
* @gather_write: Write operation with split register/value, return -ENOTSUPP
* if not implemented on a given device.
* @read: Read operation. Data is returned in the buffer used to transmit
* data.
* @owner: Module with the bus implementation, used to pin the implementation
* in memory.
* @read_flag_mask: Mask to be set in the top byte of the register when doing
* a read.
*/
struct regmap_bus {
struct list_head list;
struct bus_type *type;
regmap_hw_write write;
regmap_hw_gather_write gather_write;
regmap_hw_read read;
struct module *owner;
u8 read_flag_mask;
};
@@ -79,4 +140,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
int regmap_update_bits(struct regmap *map, unsigned int reg,
unsigned int mask, unsigned int val);
int regcache_sync(struct regmap *map);
void regcache_cache_only(struct regmap *map, bool enable);
void regcache_cache_bypass(struct regmap *map, bool enable);
#endif
+136
View File
@@ -0,0 +1,136 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM regmap
#if !defined(_TRACE_REGMAP_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_REGMAP_H
#include <linux/device.h>
#include <linux/ktime.h>
#include <linux/tracepoint.h>
struct regmap;
/*
* Log register events
*/
DECLARE_EVENT_CLASS(regmap_reg,
TP_PROTO(struct device *dev, unsigned int reg,
unsigned int val),
TP_ARGS(dev, reg, val),
TP_STRUCT__entry(
__string( name, dev_name(dev) )
__field( unsigned int, reg )
__field( unsigned int, val )
),
TP_fast_assign(
__assign_str(name, dev_name(dev));
__entry->reg = reg;
__entry->val = val;
),
TP_printk("%s reg=%x val=%x", __get_str(name),
(unsigned int)__entry->reg,
(unsigned int)__entry->val)
);
DEFINE_EVENT(regmap_reg, regmap_reg_write,
TP_PROTO(struct device *dev, unsigned int reg,
unsigned int val),
TP_ARGS(dev, reg, val)
);
DEFINE_EVENT(regmap_reg, regmap_reg_read,
TP_PROTO(struct device *dev, unsigned int reg,
unsigned int val),
TP_ARGS(dev, reg, val)
);
DECLARE_EVENT_CLASS(regmap_block,
TP_PROTO(struct device *dev, unsigned int reg, int count),
TP_ARGS(dev, reg, count),
TP_STRUCT__entry(
__string( name, dev_name(dev) )
__field( unsigned int, reg )
__field( int, count )
),
TP_fast_assign(
__assign_str(name, dev_name(dev));
__entry->reg = reg;
__entry->count = count;
),
TP_printk("%s reg=%x count=%d", __get_str(name),
(unsigned int)__entry->reg,
(int)__entry->count)
);
DEFINE_EVENT(regmap_block, regmap_hw_read_start,
TP_PROTO(struct device *dev, unsigned int reg, int count),
TP_ARGS(dev, reg, count)
);
DEFINE_EVENT(regmap_block, regmap_hw_read_done,
TP_PROTO(struct device *dev, unsigned int reg, int count),
TP_ARGS(dev, reg, count)
);
DEFINE_EVENT(regmap_block, regmap_hw_write_start,
TP_PROTO(struct device *dev, unsigned int reg, int count),
TP_ARGS(dev, reg, count)
);
DEFINE_EVENT(regmap_block, regmap_hw_write_done,
TP_PROTO(struct device *dev, unsigned int reg, int count),
TP_ARGS(dev, reg, count)
);
TRACE_EVENT(regcache_sync,
TP_PROTO(struct device *dev, const char *type,
const char *status),
TP_ARGS(dev, type, status),
TP_STRUCT__entry(
__string( name, dev_name(dev) )
__string( status, status )
__string( type, type )
__field( int, type )
),
TP_fast_assign(
__assign_str(name, dev_name(dev));
__assign_str(status, status);
__assign_str(type, type);
),
TP_printk("%s type=%s status=%s", __get_str(name),
__get_str(type), __get_str(status))
);
#endif /* _TRACE_REGMAP_H */
/* This part must be outside protection */
#include <trace/define_trace.h>