regmap: Allow regmap_bulk_write() to work for "no-bus" regmaps
regmap_bulk_write() should decay to performing individual writes if we're using a "no-bus" regmap. Unfortunately, it returns an error because there is no map->bus pointer. Fix it. Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
34f6533450
commit
f4298360a5
@ -1514,21 +1514,49 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
|
|||||||
{
|
{
|
||||||
int ret = 0, i;
|
int ret = 0, i;
|
||||||
size_t val_bytes = map->format.val_bytes;
|
size_t val_bytes = map->format.val_bytes;
|
||||||
void *wval;
|
|
||||||
|
|
||||||
if (!map->bus)
|
if (map->bus && !map->format.parse_inplace)
|
||||||
return -EINVAL;
|
|
||||||
if (!map->format.parse_inplace)
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (reg % map->reg_stride)
|
if (reg % map->reg_stride)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
map->lock(map->lock_arg);
|
map->lock(map->lock_arg);
|
||||||
|
/*
|
||||||
|
* Some devices don't support bulk write, for
|
||||||
|
* them we have a series of single write operations.
|
||||||
|
*/
|
||||||
|
if (!map->bus || map->use_single_rw) {
|
||||||
|
for (i = 0; i < val_count; i++) {
|
||||||
|
unsigned int ival;
|
||||||
|
|
||||||
/* No formatting is require if val_byte is 1 */
|
switch (val_bytes) {
|
||||||
if (val_bytes == 1) {
|
case 1:
|
||||||
wval = (void *)val;
|
ival = *(u8 *)(val + (i * val_bytes));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ival = *(u16 *)(val + (i * val_bytes));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ival = *(u32 *)(val + (i * val_bytes));
|
||||||
|
break;
|
||||||
|
#ifdef CONFIG_64BIT
|
||||||
|
case 8:
|
||||||
|
ival = *(u64 *)(val + (i * val_bytes));
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _regmap_write(map, reg + (i * map->reg_stride),
|
||||||
|
ival);
|
||||||
|
if (ret != 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
void *wval;
|
||||||
|
|
||||||
wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
|
wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
|
||||||
if (!wval) {
|
if (!wval) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
@ -1537,27 +1565,11 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
|
|||||||
}
|
}
|
||||||
for (i = 0; i < val_count * val_bytes; i += val_bytes)
|
for (i = 0; i < val_count * val_bytes; i += val_bytes)
|
||||||
map->format.parse_inplace(wval + i);
|
map->format.parse_inplace(wval + i);
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Some devices does not support bulk write, for
|
|
||||||
* them we have a series of single write operations.
|
|
||||||
*/
|
|
||||||
if (map->use_single_rw) {
|
|
||||||
for (i = 0; i < val_count; i++) {
|
|
||||||
ret = _regmap_raw_write(map,
|
|
||||||
reg + (i * map->reg_stride),
|
|
||||||
val + (i * val_bytes),
|
|
||||||
val_bytes);
|
|
||||||
if (ret != 0)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
|
ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
|
||||||
}
|
|
||||||
|
|
||||||
if (val_bytes != 1)
|
|
||||||
kfree(wval);
|
kfree(wval);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
map->unlock(map->lock_arg);
|
map->unlock(map->lock_arg);
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user