aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2013-12-26 16:52:04 -0500
committerMark Brown <broonie@linaro.org>2013-12-30 07:39:20 -0500
commitf4298360a5c21409e04cd2b0e220c8f8521fd14c (patch)
tree5beb02472eb0a3bf30742f69b1c009a75d23ddb0
parent34f653345018c42cedea89b7f6a4aba3783ebd7b (diff)
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>
-rw-r--r--drivers/base/regmap/regmap.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 062f59860091..6a19515f8a45 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1514,21 +1514,49 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1514{ 1514{
1515 int ret = 0, i; 1515 int ret = 0, i;
1516 size_t val_bytes = map->format.val_bytes; 1516 size_t val_bytes = map->format.val_bytes;
1517 void *wval;
1518 1517
1519 if (!map->bus) 1518 if (map->bus && !map->format.parse_inplace)
1520 return -EINVAL;
1521 if (!map->format.parse_inplace)
1522 return -EINVAL; 1519 return -EINVAL;
1523 if (reg % map->reg_stride) 1520 if (reg % map->reg_stride)
1524 return -EINVAL; 1521 return -EINVAL;
1525 1522
1526 map->lock(map->lock_arg); 1523 map->lock(map->lock_arg);
1524 /*
1525 * Some devices don't support bulk write, for
1526 * them we have a series of single write operations.
1527 */
1528 if (!map->bus || map->use_single_rw) {
1529 for (i = 0; i < val_count; i++) {
1530 unsigned int ival;
1531
1532 switch (val_bytes) {
1533 case 1:
1534 ival = *(u8 *)(val + (i * val_bytes));
1535 break;
1536 case 2:
1537 ival = *(u16 *)(val + (i * val_bytes));
1538 break;
1539 case 4:
1540 ival = *(u32 *)(val + (i * val_bytes));
1541 break;
1542#ifdef CONFIG_64BIT
1543 case 8:
1544 ival = *(u64 *)(val + (i * val_bytes));
1545 break;
1546#endif
1547 default:
1548 ret = -EINVAL;
1549 goto out;
1550 }
1527 1551
1528 /* No formatting is require if val_byte is 1 */ 1552 ret = _regmap_write(map, reg + (i * map->reg_stride),
1529 if (val_bytes == 1) { 1553 ival);
1530 wval = (void *)val; 1554 if (ret != 0)
1555 goto out;
1556 }
1531 } else { 1557 } else {
1558 void *wval;
1559
1532 wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL); 1560 wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
1533 if (!wval) { 1561 if (!wval) {
1534 ret = -ENOMEM; 1562 ret = -ENOMEM;
@@ -1537,27 +1565,11 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1537 } 1565 }
1538 for (i = 0; i < val_count * val_bytes; i += val_bytes) 1566 for (i = 0; i < val_count * val_bytes; i += val_bytes)
1539 map->format.parse_inplace(wval + i); 1567 map->format.parse_inplace(wval + i);
1540 } 1568
1541 /*
1542 * Some devices does not support bulk write, for
1543 * them we have a series of single write operations.
1544 */
1545 if (map->use_single_rw) {
1546 for (i = 0; i < val_count; i++) {
1547 ret = _regmap_raw_write(map,
1548 reg + (i * map->reg_stride),
1549 val + (i * val_bytes),
1550 val_bytes);
1551 if (ret != 0)
1552 goto out;
1553 }
1554 } else {
1555 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); 1569 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
1556 }
1557 1570
1558 if (val_bytes != 1)
1559 kfree(wval); 1571 kfree(wval);
1560 1572 }
1561out: 1573out:
1562 map->unlock(map->lock_arg); 1574 map->unlock(map->lock_arg);
1563 return ret; 1575 return ret;