regmap: introduce explicit bus_context for bus callbacks
The only context needed by I2C and SPI bus definitions is the device itself; this can be converted to an i2c_client or spi_device in order to perform IO on the device. However, other bus types may need more context in order to perform IO. Enable this by having regmap_init accept a bus_context parameter, and pass this to all bus callbacks. The existing callbacks simply pass the struct device here. Future bus types may pass something else. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
55c1371c79
commit
26b5e74d31
@ -38,6 +38,7 @@ struct regmap {
|
|||||||
void *work_buf; /* Scratch buffer used to format I/O */
|
void *work_buf; /* Scratch buffer used to format I/O */
|
||||||
struct regmap_format format; /* Buffer format */
|
struct regmap_format format; /* Buffer format */
|
||||||
const struct regmap_bus *bus;
|
const struct regmap_bus *bus;
|
||||||
|
void *bus_context;
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
struct dentry *debugfs;
|
struct dentry *debugfs;
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
|
||||||
static int regmap_i2c_write(struct device *dev, const void *data, size_t count)
|
static int regmap_i2c_write(void *context, const void *data, size_t count)
|
||||||
{
|
{
|
||||||
|
struct device *dev = context;
|
||||||
struct i2c_client *i2c = to_i2c_client(dev);
|
struct i2c_client *i2c = to_i2c_client(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -29,10 +30,11 @@ static int regmap_i2c_write(struct device *dev, const void *data, size_t count)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regmap_i2c_gather_write(struct device *dev,
|
static int regmap_i2c_gather_write(void *context,
|
||||||
const void *reg, size_t reg_size,
|
const void *reg, size_t reg_size,
|
||||||
const void *val, size_t val_size)
|
const void *val, size_t val_size)
|
||||||
{
|
{
|
||||||
|
struct device *dev = context;
|
||||||
struct i2c_client *i2c = to_i2c_client(dev);
|
struct i2c_client *i2c = to_i2c_client(dev);
|
||||||
struct i2c_msg xfer[2];
|
struct i2c_msg xfer[2];
|
||||||
int ret;
|
int ret;
|
||||||
@ -62,10 +64,11 @@ static int regmap_i2c_gather_write(struct device *dev,
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regmap_i2c_read(struct device *dev,
|
static int regmap_i2c_read(void *context,
|
||||||
const void *reg, size_t reg_size,
|
const void *reg, size_t reg_size,
|
||||||
void *val, size_t val_size)
|
void *val, size_t val_size)
|
||||||
{
|
{
|
||||||
|
struct device *dev = context;
|
||||||
struct i2c_client *i2c = to_i2c_client(dev);
|
struct i2c_client *i2c = to_i2c_client(dev);
|
||||||
struct i2c_msg xfer[2];
|
struct i2c_msg xfer[2];
|
||||||
int ret;
|
int ret;
|
||||||
@ -107,7 +110,7 @@ static struct regmap_bus regmap_i2c = {
|
|||||||
struct regmap *regmap_init_i2c(struct i2c_client *i2c,
|
struct regmap *regmap_init_i2c(struct i2c_client *i2c,
|
||||||
const struct regmap_config *config)
|
const struct regmap_config *config)
|
||||||
{
|
{
|
||||||
return regmap_init(&i2c->dev, ®map_i2c, config);
|
return regmap_init(&i2c->dev, ®map_i2c, &i2c->dev, config);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regmap_init_i2c);
|
EXPORT_SYMBOL_GPL(regmap_init_i2c);
|
||||||
|
|
||||||
@ -124,7 +127,7 @@ EXPORT_SYMBOL_GPL(regmap_init_i2c);
|
|||||||
struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
|
struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
|
||||||
const struct regmap_config *config)
|
const struct regmap_config *config)
|
||||||
{
|
{
|
||||||
return devm_regmap_init(&i2c->dev, ®map_i2c, config);
|
return devm_regmap_init(&i2c->dev, ®map_i2c, &i2c->dev, config);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(devm_regmap_init_i2c);
|
EXPORT_SYMBOL_GPL(devm_regmap_init_i2c);
|
||||||
|
|
||||||
|
@ -15,17 +15,19 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
static int regmap_spi_write(struct device *dev, const void *data, size_t count)
|
static int regmap_spi_write(void *context, const void *data, size_t count)
|
||||||
{
|
{
|
||||||
|
struct device *dev = context;
|
||||||
struct spi_device *spi = to_spi_device(dev);
|
struct spi_device *spi = to_spi_device(dev);
|
||||||
|
|
||||||
return spi_write(spi, data, count);
|
return spi_write(spi, data, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regmap_spi_gather_write(struct device *dev,
|
static int regmap_spi_gather_write(void *context,
|
||||||
const void *reg, size_t reg_len,
|
const void *reg, size_t reg_len,
|
||||||
const void *val, size_t val_len)
|
const void *val, size_t val_len)
|
||||||
{
|
{
|
||||||
|
struct device *dev = context;
|
||||||
struct spi_device *spi = to_spi_device(dev);
|
struct spi_device *spi = to_spi_device(dev);
|
||||||
struct spi_message m;
|
struct spi_message m;
|
||||||
struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, },
|
struct spi_transfer t[2] = { { .tx_buf = reg, .len = reg_len, },
|
||||||
@ -38,10 +40,11 @@ static int regmap_spi_gather_write(struct device *dev,
|
|||||||
return spi_sync(spi, &m);
|
return spi_sync(spi, &m);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int regmap_spi_read(struct device *dev,
|
static int regmap_spi_read(void *context,
|
||||||
const void *reg, size_t reg_size,
|
const void *reg, size_t reg_size,
|
||||||
void *val, size_t val_size)
|
void *val, size_t val_size)
|
||||||
{
|
{
|
||||||
|
struct device *dev = context;
|
||||||
struct spi_device *spi = to_spi_device(dev);
|
struct spi_device *spi = to_spi_device(dev);
|
||||||
|
|
||||||
return spi_write_then_read(spi, reg, reg_size, val, val_size);
|
return spi_write_then_read(spi, reg, reg_size, val, val_size);
|
||||||
@ -66,7 +69,7 @@ static struct regmap_bus regmap_spi = {
|
|||||||
struct regmap *regmap_init_spi(struct spi_device *spi,
|
struct regmap *regmap_init_spi(struct spi_device *spi,
|
||||||
const struct regmap_config *config)
|
const struct regmap_config *config)
|
||||||
{
|
{
|
||||||
return regmap_init(&spi->dev, ®map_spi, config);
|
return regmap_init(&spi->dev, ®map_spi, &spi->dev, config);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regmap_init_spi);
|
EXPORT_SYMBOL_GPL(regmap_init_spi);
|
||||||
|
|
||||||
@ -83,7 +86,7 @@ EXPORT_SYMBOL_GPL(regmap_init_spi);
|
|||||||
struct regmap *devm_regmap_init_spi(struct spi_device *spi,
|
struct regmap *devm_regmap_init_spi(struct spi_device *spi,
|
||||||
const struct regmap_config *config)
|
const struct regmap_config *config)
|
||||||
{
|
{
|
||||||
return devm_regmap_init(&spi->dev, ®map_spi, config);
|
return devm_regmap_init(&spi->dev, ®map_spi, &spi->dev, config);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(devm_regmap_init_spi);
|
EXPORT_SYMBOL_GPL(devm_regmap_init_spi);
|
||||||
|
|
||||||
|
@ -184,6 +184,7 @@ static unsigned int regmap_parse_32(void *buf)
|
|||||||
*
|
*
|
||||||
* @dev: Device that will be interacted with
|
* @dev: Device that will be interacted with
|
||||||
* @bus: Bus-specific callbacks to use with device
|
* @bus: Bus-specific callbacks to use with device
|
||||||
|
* @bus_context: Data passed to bus-specific callbacks
|
||||||
* @config: Configuration for register map
|
* @config: Configuration for register map
|
||||||
*
|
*
|
||||||
* The return value will be an ERR_PTR() on error or a valid pointer to
|
* The return value will be an ERR_PTR() on error or a valid pointer to
|
||||||
@ -192,6 +193,7 @@ static unsigned int regmap_parse_32(void *buf)
|
|||||||
*/
|
*/
|
||||||
struct regmap *regmap_init(struct device *dev,
|
struct regmap *regmap_init(struct device *dev,
|
||||||
const struct regmap_bus *bus,
|
const struct regmap_bus *bus,
|
||||||
|
void *bus_context,
|
||||||
const struct regmap_config *config)
|
const struct regmap_config *config)
|
||||||
{
|
{
|
||||||
struct regmap *map;
|
struct regmap *map;
|
||||||
@ -215,6 +217,7 @@ struct regmap *regmap_init(struct device *dev,
|
|||||||
map->reg_shift = config->pad_bits % 8;
|
map->reg_shift = config->pad_bits % 8;
|
||||||
map->dev = dev;
|
map->dev = dev;
|
||||||
map->bus = bus;
|
map->bus = bus;
|
||||||
|
map->bus_context = bus_context;
|
||||||
map->max_register = config->max_register;
|
map->max_register = config->max_register;
|
||||||
map->writeable_reg = config->writeable_reg;
|
map->writeable_reg = config->writeable_reg;
|
||||||
map->readable_reg = config->readable_reg;
|
map->readable_reg = config->readable_reg;
|
||||||
@ -342,6 +345,7 @@ static void devm_regmap_release(struct device *dev, void *res)
|
|||||||
*
|
*
|
||||||
* @dev: Device that will be interacted with
|
* @dev: Device that will be interacted with
|
||||||
* @bus: Bus-specific callbacks to use with device
|
* @bus: Bus-specific callbacks to use with device
|
||||||
|
* @bus_context: Data passed to bus-specific callbacks
|
||||||
* @config: Configuration for register map
|
* @config: Configuration for register map
|
||||||
*
|
*
|
||||||
* The return value will be an ERR_PTR() on error or a valid pointer
|
* The return value will be an ERR_PTR() on error or a valid pointer
|
||||||
@ -351,6 +355,7 @@ static void devm_regmap_release(struct device *dev, void *res)
|
|||||||
*/
|
*/
|
||||||
struct regmap *devm_regmap_init(struct device *dev,
|
struct regmap *devm_regmap_init(struct device *dev,
|
||||||
const struct regmap_bus *bus,
|
const struct regmap_bus *bus,
|
||||||
|
void *bus_context,
|
||||||
const struct regmap_config *config)
|
const struct regmap_config *config)
|
||||||
{
|
{
|
||||||
struct regmap **ptr, *regmap;
|
struct regmap **ptr, *regmap;
|
||||||
@ -359,7 +364,7 @@ struct regmap *devm_regmap_init(struct device *dev,
|
|||||||
if (!ptr)
|
if (!ptr)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
regmap = regmap_init(dev, bus, config);
|
regmap = regmap_init(dev, bus, bus_context, config);
|
||||||
if (!IS_ERR(regmap)) {
|
if (!IS_ERR(regmap)) {
|
||||||
*ptr = regmap;
|
*ptr = regmap;
|
||||||
devres_add(dev, ptr);
|
devres_add(dev, ptr);
|
||||||
@ -417,6 +422,8 @@ void regmap_exit(struct regmap *map)
|
|||||||
{
|
{
|
||||||
regcache_exit(map);
|
regcache_exit(map);
|
||||||
regmap_debugfs_exit(map);
|
regmap_debugfs_exit(map);
|
||||||
|
if (map->bus->free_context)
|
||||||
|
map->bus->free_context(map->bus_context);
|
||||||
kfree(map->work_buf);
|
kfree(map->work_buf);
|
||||||
kfree(map);
|
kfree(map);
|
||||||
}
|
}
|
||||||
@ -470,12 +477,12 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
|
|||||||
*/
|
*/
|
||||||
if (val == (map->work_buf + map->format.pad_bytes +
|
if (val == (map->work_buf + map->format.pad_bytes +
|
||||||
map->format.reg_bytes))
|
map->format.reg_bytes))
|
||||||
ret = map->bus->write(map->dev, map->work_buf,
|
ret = map->bus->write(map->bus_context, map->work_buf,
|
||||||
map->format.reg_bytes +
|
map->format.reg_bytes +
|
||||||
map->format.pad_bytes +
|
map->format.pad_bytes +
|
||||||
val_len);
|
val_len);
|
||||||
else if (map->bus->gather_write)
|
else if (map->bus->gather_write)
|
||||||
ret = map->bus->gather_write(map->dev, map->work_buf,
|
ret = map->bus->gather_write(map->bus_context, map->work_buf,
|
||||||
map->format.reg_bytes +
|
map->format.reg_bytes +
|
||||||
map->format.pad_bytes,
|
map->format.pad_bytes,
|
||||||
val, val_len);
|
val, val_len);
|
||||||
@ -490,7 +497,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
|
|||||||
memcpy(buf, map->work_buf, map->format.reg_bytes);
|
memcpy(buf, map->work_buf, map->format.reg_bytes);
|
||||||
memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
|
memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
|
||||||
val, val_len);
|
val, val_len);
|
||||||
ret = map->bus->write(map->dev, buf, len);
|
ret = map->bus->write(map->bus_context, buf, len);
|
||||||
|
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
}
|
}
|
||||||
@ -524,7 +531,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
|
|||||||
|
|
||||||
trace_regmap_hw_write_start(map->dev, reg, 1);
|
trace_regmap_hw_write_start(map->dev, reg, 1);
|
||||||
|
|
||||||
ret = map->bus->write(map->dev, map->work_buf,
|
ret = map->bus->write(map->bus_context, map->work_buf,
|
||||||
map->format.buf_size);
|
map->format.buf_size);
|
||||||
|
|
||||||
trace_regmap_hw_write_done(map->dev, reg, 1);
|
trace_regmap_hw_write_done(map->dev, reg, 1);
|
||||||
@ -665,7 +672,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
|||||||
trace_regmap_hw_read_start(map->dev, reg,
|
trace_regmap_hw_read_start(map->dev, reg,
|
||||||
val_len / map->format.val_bytes);
|
val_len / map->format.val_bytes);
|
||||||
|
|
||||||
ret = map->bus->read(map->dev, map->work_buf,
|
ret = map->bus->read(map->bus_context, map->work_buf,
|
||||||
map->format.reg_bytes + map->format.pad_bytes,
|
map->format.reg_bytes + map->format.pad_bytes,
|
||||||
val, val_len);
|
val, val_len);
|
||||||
|
|
||||||
|
@ -97,14 +97,15 @@ struct regmap_config {
|
|||||||
u8 write_flag_mask;
|
u8 write_flag_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*regmap_hw_write)(struct device *dev, const void *data,
|
typedef int (*regmap_hw_write)(void *context, const void *data,
|
||||||
size_t count);
|
size_t count);
|
||||||
typedef int (*regmap_hw_gather_write)(struct device *dev,
|
typedef int (*regmap_hw_gather_write)(void *context,
|
||||||
const void *reg, size_t reg_len,
|
const void *reg, size_t reg_len,
|
||||||
const void *val, size_t val_len);
|
const void *val, size_t val_len);
|
||||||
typedef int (*regmap_hw_read)(struct device *dev,
|
typedef int (*regmap_hw_read)(void *context,
|
||||||
const void *reg_buf, size_t reg_size,
|
const void *reg_buf, size_t reg_size,
|
||||||
void *val_buf, size_t val_size);
|
void *val_buf, size_t val_size);
|
||||||
|
typedef void (*regmap_hw_free_context)(void *context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of a hardware bus for the register map infrastructure.
|
* Description of a hardware bus for the register map infrastructure.
|
||||||
@ -121,11 +122,13 @@ struct regmap_bus {
|
|||||||
regmap_hw_write write;
|
regmap_hw_write write;
|
||||||
regmap_hw_gather_write gather_write;
|
regmap_hw_gather_write gather_write;
|
||||||
regmap_hw_read read;
|
regmap_hw_read read;
|
||||||
|
regmap_hw_free_context free_context;
|
||||||
u8 read_flag_mask;
|
u8 read_flag_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct regmap *regmap_init(struct device *dev,
|
struct regmap *regmap_init(struct device *dev,
|
||||||
const struct regmap_bus *bus,
|
const struct regmap_bus *bus,
|
||||||
|
void *bus_context,
|
||||||
const struct regmap_config *config);
|
const struct regmap_config *config);
|
||||||
struct regmap *regmap_init_i2c(struct i2c_client *i2c,
|
struct regmap *regmap_init_i2c(struct i2c_client *i2c,
|
||||||
const struct regmap_config *config);
|
const struct regmap_config *config);
|
||||||
@ -134,6 +137,7 @@ struct regmap *regmap_init_spi(struct spi_device *dev,
|
|||||||
|
|
||||||
struct regmap *devm_regmap_init(struct device *dev,
|
struct regmap *devm_regmap_init(struct device *dev,
|
||||||
const struct regmap_bus *bus,
|
const struct regmap_bus *bus,
|
||||||
|
void *bus_context,
|
||||||
const struct regmap_config *config);
|
const struct regmap_config *config);
|
||||||
struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
|
struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
|
||||||
const struct regmap_config *config);
|
const struct regmap_config *config);
|
||||||
|
Loading…
Reference in New Issue
Block a user