Merge remote-tracking branches 'regmap/topic/lockdep' and 'regmap/topic/seq-delay' into regmap-next
このコミットが含まれているのは:
@@ -136,7 +136,7 @@ struct regmap {
|
||||
/* if set, the HW registers are known to match map->reg_defaults */
|
||||
bool no_sync_defaults;
|
||||
|
||||
struct reg_default *patch;
|
||||
struct reg_sequence *patch;
|
||||
int patch_regs;
|
||||
|
||||
/* if set, converts bulk read to single read */
|
||||
|
@@ -78,37 +78,24 @@ static const struct regmap_bus ac97_regmap_bus = {
|
||||
.reg_read = regmap_ac97_reg_read,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *regmap_init_ac97(struct snd_ac97 *ac97,
|
||||
const struct regmap_config *config)
|
||||
struct regmap *__regmap_init_ac97(struct snd_ac97 *ac97,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
return regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config);
|
||||
return __regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_init_ac97);
|
||||
EXPORT_SYMBOL_GPL(__regmap_init_ac97);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *devm_regmap_init_ac97(struct snd_ac97 *ac97,
|
||||
const struct regmap_config *config)
|
||||
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)
|
||||
{
|
||||
return devm_regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config);
|
||||
return __devm_regmap_init(&ac97->dev, &ac97_regmap_bus, ac97, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regmap_init_ac97);
|
||||
EXPORT_SYMBOL_GPL(__devm_regmap_init_ac97);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -282,47 +282,34 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *regmap_init_i2c(struct i2c_client *i2c,
|
||||
const struct regmap_config *config)
|
||||
struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config);
|
||||
|
||||
if (IS_ERR(bus))
|
||||
return ERR_CAST(bus);
|
||||
|
||||
return regmap_init(&i2c->dev, bus, &i2c->dev, config);
|
||||
return __regmap_init(&i2c->dev, bus, &i2c->dev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_init_i2c);
|
||||
EXPORT_SYMBOL_GPL(__regmap_init_i2c);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
|
||||
const struct regmap_config *config)
|
||||
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)
|
||||
{
|
||||
const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config);
|
||||
|
||||
if (IS_ERR(bus))
|
||||
return ERR_CAST(bus);
|
||||
|
||||
return devm_regmap_init(&i2c->dev, bus, &i2c->dev, config);
|
||||
return __devm_regmap_init(&i2c->dev, bus, &i2c->dev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regmap_init_i2c);
|
||||
EXPORT_SYMBOL_GPL(__devm_regmap_init_i2c);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -296,20 +296,11 @@ err_free:
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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_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_mmio_context *ctx;
|
||||
|
||||
@@ -317,25 +308,17 @@ struct regmap *regmap_init_mmio_clk(struct device *dev, const char *clk_id,
|
||||
if (IS_ERR(ctx))
|
||||
return ERR_CAST(ctx);
|
||||
|
||||
return regmap_init(dev, ®map_mmio, ctx, config);
|
||||
return __regmap_init(dev, ®map_mmio, ctx, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_init_mmio_clk);
|
||||
EXPORT_SYMBOL_GPL(__regmap_init_mmio_clk);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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_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_mmio_context *ctx;
|
||||
|
||||
@@ -343,8 +326,9 @@ struct regmap *devm_regmap_init_mmio_clk(struct device *dev, const char *clk_id,
|
||||
if (IS_ERR(ctx))
|
||||
return ERR_CAST(ctx);
|
||||
|
||||
return devm_regmap_init(dev, ®map_mmio, ctx, config);
|
||||
return __devm_regmap_init(dev, ®map_mmio, ctx, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regmap_init_mmio_clk);
|
||||
EXPORT_SYMBOL_GPL(__devm_regmap_init_mmio_clk);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -113,37 +113,24 @@ static struct regmap_bus regmap_spi = {
|
||||
.val_format_endian_default = REGMAP_ENDIAN_BIG,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *regmap_init_spi(struct spi_device *spi,
|
||||
const struct regmap_config *config)
|
||||
struct regmap *__regmap_init_spi(struct spi_device *spi,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
return regmap_init(&spi->dev, ®map_spi, &spi->dev, config);
|
||||
return __regmap_init(&spi->dev, ®map_spi, &spi->dev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_init_spi);
|
||||
EXPORT_SYMBOL_GPL(__regmap_init_spi);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *devm_regmap_init_spi(struct spi_device *spi,
|
||||
const struct regmap_config *config)
|
||||
struct regmap *__devm_regmap_init_spi(struct spi_device *spi,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
return devm_regmap_init(&spi->dev, ®map_spi, &spi->dev, config);
|
||||
return __devm_regmap_init(&spi->dev, ®map_spi, &spi->dev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regmap_init_spi);
|
||||
EXPORT_SYMBOL_GPL(__devm_regmap_init_spi);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -91,36 +91,25 @@ static struct regmap_bus regmap_spmi_base = {
|
||||
.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *regmap_init_spmi_base(struct spmi_device *sdev,
|
||||
const struct regmap_config *config)
|
||||
struct regmap *__regmap_init_spmi_base(struct spmi_device *sdev,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
return regmap_init(&sdev->dev, ®map_spmi_base, sdev, config);
|
||||
return __regmap_init(&sdev->dev, ®map_spmi_base, sdev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_init_spmi_base);
|
||||
EXPORT_SYMBOL_GPL(__regmap_init_spmi_base);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *devm_regmap_init_spmi_base(struct spmi_device *sdev,
|
||||
const struct regmap_config *config)
|
||||
struct regmap *__devm_regmap_init_spmi_base(struct spmi_device *sdev,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
return devm_regmap_init(&sdev->dev, ®map_spmi_base, sdev, config);
|
||||
return __devm_regmap_init(&sdev->dev, ®map_spmi_base, sdev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regmap_init_spmi_base);
|
||||
EXPORT_SYMBOL_GPL(__devm_regmap_init_spmi_base);
|
||||
|
||||
static int regmap_spmi_ext_read(void *context,
|
||||
const void *reg, size_t reg_size,
|
||||
@@ -222,35 +211,24 @@ static struct regmap_bus regmap_spmi_ext = {
|
||||
.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *regmap_init_spmi_ext(struct spmi_device *sdev,
|
||||
const struct regmap_config *config)
|
||||
struct regmap *__regmap_init_spmi_ext(struct spmi_device *sdev,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
return regmap_init(&sdev->dev, ®map_spmi_ext, sdev, config);
|
||||
return __regmap_init(&sdev->dev, ®map_spmi_ext, sdev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_init_spmi_ext);
|
||||
EXPORT_SYMBOL_GPL(__regmap_init_spmi_ext);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *devm_regmap_init_spmi_ext(struct spmi_device *sdev,
|
||||
const struct regmap_config *config)
|
||||
struct regmap *__devm_regmap_init_spmi_ext(struct spmi_device *sdev,
|
||||
const struct regmap_config *config,
|
||||
struct lock_class_key *lock_key,
|
||||
const char *lock_name)
|
||||
{
|
||||
return devm_regmap_init(&sdev->dev, ®map_spmi_ext, sdev, config);
|
||||
return __devm_regmap_init(&sdev->dev, ®map_spmi_ext, sdev, config,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regmap_init_spmi_ext);
|
||||
EXPORT_SYMBOL_GPL(__devm_regmap_init_spmi_ext);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/rbtree.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "trace.h"
|
||||
@@ -518,22 +519,12 @@ enum regmap_endian regmap_get_val_endian(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_get_val_endian);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct regmap *regmap_init(struct device *dev,
|
||||
const struct regmap_bus *bus,
|
||||
void *bus_context,
|
||||
const struct regmap_config *config)
|
||||
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 *map;
|
||||
int ret = -EINVAL;
|
||||
@@ -559,10 +550,14 @@ struct regmap *regmap_init(struct device *dev,
|
||||
spin_lock_init(&map->spinlock);
|
||||
map->lock = regmap_lock_spinlock;
|
||||
map->unlock = regmap_unlock_spinlock;
|
||||
lockdep_set_class_and_name(&map->spinlock,
|
||||
lock_key, lock_name);
|
||||
} else {
|
||||
mutex_init(&map->mutex);
|
||||
map->lock = regmap_lock_mutex;
|
||||
map->unlock = regmap_unlock_mutex;
|
||||
lockdep_set_class_and_name(&map->mutex,
|
||||
lock_key, lock_name);
|
||||
}
|
||||
map->lock_arg = map;
|
||||
}
|
||||
@@ -907,30 +902,19 @@ err_map:
|
||||
err:
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_init);
|
||||
EXPORT_SYMBOL_GPL(__regmap_init);
|
||||
|
||||
static void devm_regmap_release(struct device *dev, void *res)
|
||||
{
|
||||
regmap_exit(*(struct regmap **)res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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(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 **ptr, *regmap;
|
||||
|
||||
@@ -938,7 +922,8 @@ struct regmap *devm_regmap_init(struct device *dev,
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
regmap = regmap_init(dev, bus, bus_context, config);
|
||||
regmap = __regmap_init(dev, bus, bus_context, config,
|
||||
lock_key, lock_name);
|
||||
if (!IS_ERR(regmap)) {
|
||||
*ptr = regmap;
|
||||
devres_add(dev, ptr);
|
||||
@@ -948,7 +933,7 @@ struct regmap *devm_regmap_init(struct device *dev,
|
||||
|
||||
return regmap;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regmap_init);
|
||||
EXPORT_SYMBOL_GPL(__devm_regmap_init);
|
||||
|
||||
static void regmap_field_init(struct regmap_field *rm_field,
|
||||
struct regmap *regmap, struct reg_field reg_field)
|
||||
@@ -1827,7 +1812,7 @@ EXPORT_SYMBOL_GPL(regmap_bulk_write);
|
||||
* relative. The page register has been written if that was necessary.
|
||||
*/
|
||||
static int _regmap_raw_multi_reg_write(struct regmap *map,
|
||||
const struct reg_default *regs,
|
||||
const struct reg_sequence *regs,
|
||||
size_t num_regs)
|
||||
{
|
||||
int ret;
|
||||
@@ -1884,17 +1869,19 @@ static unsigned int _regmap_register_page(struct regmap *map,
|
||||
}
|
||||
|
||||
static int _regmap_range_multi_paged_reg_write(struct regmap *map,
|
||||
struct reg_default *regs,
|
||||
struct reg_sequence *regs,
|
||||
size_t num_regs)
|
||||
{
|
||||
int ret;
|
||||
int i, n;
|
||||
struct reg_default *base;
|
||||
struct reg_sequence *base;
|
||||
unsigned int this_page = 0;
|
||||
unsigned int page_change = 0;
|
||||
/*
|
||||
* the set of registers are not neccessarily in order, but
|
||||
* since the order of write must be preserved this algorithm
|
||||
* chops the set each time the page changes
|
||||
* chops the set each time the page changes. This also applies
|
||||
* if there is a delay required at any point in the sequence.
|
||||
*/
|
||||
base = regs;
|
||||
for (i = 0, n = 0; i < num_regs; i++, n++) {
|
||||
@@ -1910,16 +1897,48 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
|
||||
this_page = win_page;
|
||||
if (win_page != this_page) {
|
||||
this_page = win_page;
|
||||
page_change = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have both a page change and a delay make sure to
|
||||
* write the regs and apply the delay before we change the
|
||||
* page.
|
||||
*/
|
||||
|
||||
if (page_change || regs[i].delay_us) {
|
||||
|
||||
/* For situations where the first write requires
|
||||
* a delay we need to make sure we don't call
|
||||
* raw_multi_reg_write with n=0
|
||||
* This can't occur with page breaks as we
|
||||
* never write on the first iteration
|
||||
*/
|
||||
if (regs[i].delay_us && i == 0)
|
||||
n = 1;
|
||||
|
||||
ret = _regmap_raw_multi_reg_write(map, base, n);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (regs[i].delay_us)
|
||||
udelay(regs[i].delay_us);
|
||||
|
||||
base += n;
|
||||
n = 0;
|
||||
}
|
||||
ret = _regmap_select_page(map, &base[n].reg, range, 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (page_change) {
|
||||
ret = _regmap_select_page(map,
|
||||
&base[n].reg,
|
||||
range, 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
page_change = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (n > 0)
|
||||
return _regmap_raw_multi_reg_write(map, base, n);
|
||||
@@ -1927,7 +1946,7 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
|
||||
}
|
||||
|
||||
static int _regmap_multi_reg_write(struct regmap *map,
|
||||
const struct reg_default *regs,
|
||||
const struct reg_sequence *regs,
|
||||
size_t num_regs)
|
||||
{
|
||||
int i;
|
||||
@@ -1938,6 +1957,9 @@ static int _regmap_multi_reg_write(struct regmap *map,
|
||||
ret = _regmap_write(map, regs[i].reg, regs[i].def);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (regs[i].delay_us)
|
||||
udelay(regs[i].delay_us);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1977,10 +1999,14 @@ static int _regmap_multi_reg_write(struct regmap *map,
|
||||
for (i = 0; i < num_regs; i++) {
|
||||
unsigned int reg = regs[i].reg;
|
||||
struct regmap_range_node *range;
|
||||
|
||||
/* Coalesce all the writes between a page break or a delay
|
||||
* in a sequence
|
||||
*/
|
||||
range = _regmap_range_lookup(map, reg);
|
||||
if (range) {
|
||||
size_t len = sizeof(struct reg_default)*num_regs;
|
||||
struct reg_default *base = kmemdup(regs, len,
|
||||
if (range || regs[i].delay_us) {
|
||||
size_t len = sizeof(struct reg_sequence)*num_regs;
|
||||
struct reg_sequence *base = kmemdup(regs, len,
|
||||
GFP_KERNEL);
|
||||
if (!base)
|
||||
return -ENOMEM;
|
||||
@@ -2013,7 +2039,7 @@ static int _regmap_multi_reg_write(struct regmap *map,
|
||||
* 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_default *regs,
|
||||
int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs,
|
||||
int num_regs)
|
||||
{
|
||||
int ret;
|
||||
@@ -2046,7 +2072,7 @@ EXPORT_SYMBOL_GPL(regmap_multi_reg_write);
|
||||
* be returned in error cases.
|
||||
*/
|
||||
int regmap_multi_reg_write_bypassed(struct regmap *map,
|
||||
const struct reg_default *regs,
|
||||
const struct reg_sequence *regs,
|
||||
int num_regs)
|
||||
{
|
||||
int ret;
|
||||
@@ -2726,10 +2752,10 @@ EXPORT_SYMBOL_GPL(regmap_async_complete);
|
||||
* 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_default *regs,
|
||||
int regmap_register_patch(struct regmap *map, const struct reg_sequence *regs,
|
||||
int num_regs)
|
||||
{
|
||||
struct reg_default *p;
|
||||
struct reg_sequence *p;
|
||||
int ret;
|
||||
bool bypass;
|
||||
|
||||
@@ -2738,7 +2764,7 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
|
||||
return 0;
|
||||
|
||||
p = krealloc(map->patch,
|
||||
sizeof(struct reg_default) * (map->patch_regs + num_regs),
|
||||
sizeof(struct reg_sequence) * (map->patch_regs + num_regs),
|
||||
GFP_KERNEL);
|
||||
if (p) {
|
||||
memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs));
|
||||
|
新しいイシューから参照
ユーザーをブロックする