aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/internal.h2
-rw-r--r--drivers/base/regmap/regcache.c9
-rw-r--r--drivers/base/regmap/regmap-irq.c6
-rw-r--r--drivers/base/regmap/regmap-mmio.c56
-rw-r--r--drivers/base/regmap/regmap.c336
5 files changed, 341 insertions, 68 deletions
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 33414b1de201..7d1326985bee 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -134,6 +134,8 @@ struct regmap {
134 134
135 /* if set, converts bulk rw to single rw */ 135 /* if set, converts bulk rw to single rw */
136 bool use_single_rw; 136 bool use_single_rw;
137 /* if set, the device supports multi write mode */
138 bool can_multi_write;
137 139
138 struct rb_root range_tree; 140 struct rb_root range_tree;
139 void *selector_work_buf; /* Scratch buffer used for selector */ 141 void *selector_work_buf; /* Scratch buffer used for selector */
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index dd56177b7010..29b4128da0b0 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -249,11 +249,12 @@ static int regcache_default_sync(struct regmap *map, unsigned int min,
249{ 249{
250 unsigned int reg; 250 unsigned int reg;
251 251
252 for (reg = min; reg <= max; reg++) { 252 for (reg = min; reg <= max; reg += map->reg_stride) {
253 unsigned int val; 253 unsigned int val;
254 int ret; 254 int ret;
255 255
256 if (regmap_volatile(map, reg)) 256 if (regmap_volatile(map, reg) ||
257 !regmap_writeable(map, reg))
257 continue; 258 continue;
258 259
259 ret = regcache_read(map, reg, &val); 260 ret = regcache_read(map, reg, &val);
@@ -312,10 +313,6 @@ int regcache_sync(struct regmap *map)
312 /* Apply any patch first */ 313 /* Apply any patch first */
313 map->cache_bypass = 1; 314 map->cache_bypass = 1;
314 for (i = 0; i < map->patch_regs; i++) { 315 for (i = 0; i < map->patch_regs; i++) {
315 if (map->patch[i].reg % map->reg_stride) {
316 ret = -EINVAL;
317 goto out;
318 }
319 ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); 316 ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
320 if (ret != 0) { 317 if (ret != 0) {
321 dev_err(map->dev, "Failed to write %x = %x: %d\n", 318 dev_err(map->dev, "Failed to write %x = %x: %d\n",
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 82692068d3cb..edf88f20cbce 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -368,8 +368,6 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
368 if (!d) 368 if (!d)
369 return -ENOMEM; 369 return -ENOMEM;
370 370
371 *data = d;
372
373 d->status_buf = kzalloc(sizeof(unsigned int) * chip->num_regs, 371 d->status_buf = kzalloc(sizeof(unsigned int) * chip->num_regs,
374 GFP_KERNEL); 372 GFP_KERNEL);
375 if (!d->status_buf) 373 if (!d->status_buf)
@@ -506,6 +504,8 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
506 goto err_domain; 504 goto err_domain;
507 } 505 }
508 506
507 *data = d;
508
509 return 0; 509 return 0;
510 510
511err_domain: 511err_domain:
@@ -533,7 +533,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
533 return; 533 return;
534 534
535 free_irq(irq, d); 535 free_irq(irq, d);
536 /* We should unmap the domain but... */ 536 irq_domain_remove(d->domain);
537 kfree(d->wake_buf); 537 kfree(d->wake_buf);
538 kfree(d->mask_buf_def); 538 kfree(d->mask_buf_def);
539 kfree(d->mask_buf); 539 kfree(d->mask_buf);
diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c
index 81f977510775..de45a1e1548f 100644
--- a/drivers/base/regmap/regmap-mmio.c
+++ b/drivers/base/regmap/regmap-mmio.c
@@ -26,10 +26,47 @@
26 26
27struct regmap_mmio_context { 27struct regmap_mmio_context {
28 void __iomem *regs; 28 void __iomem *regs;
29 unsigned reg_bytes;
29 unsigned val_bytes; 30 unsigned val_bytes;
31 unsigned pad_bytes;
30 struct clk *clk; 32 struct clk *clk;
31}; 33};
32 34
35static inline void regmap_mmio_regsize_check(size_t reg_size)
36{
37 switch (reg_size) {
38 case 1:
39 case 2:
40 case 4:
41#ifdef CONFIG_64BIT
42 case 8:
43#endif
44 break;
45 default:
46 BUG();
47 }
48}
49
50static int regmap_mmio_regbits_check(size_t reg_bits)
51{
52 switch (reg_bits) {
53 case 8:
54 case 16:
55 case 32:
56#ifdef CONFIG_64BIT
57 case 64:
58#endif
59 return 0;
60 default:
61 return -EINVAL;
62 }
63}
64
65static inline void regmap_mmio_count_check(size_t count)
66{
67 BUG_ON(count % 2 != 0);
68}
69
33static int regmap_mmio_gather_write(void *context, 70static int regmap_mmio_gather_write(void *context,
34 const void *reg, size_t reg_size, 71 const void *reg, size_t reg_size,
35 const void *val, size_t val_size) 72 const void *val, size_t val_size)
@@ -38,7 +75,7 @@ static int regmap_mmio_gather_write(void *context,
38 u32 offset; 75 u32 offset;
39 int ret; 76 int ret;
40 77
41 BUG_ON(reg_size != 4); 78 regmap_mmio_regsize_check(reg_size);
42 79
43 if (!IS_ERR(ctx->clk)) { 80 if (!IS_ERR(ctx->clk)) {
44 ret = clk_enable(ctx->clk); 81 ret = clk_enable(ctx->clk);
@@ -81,9 +118,13 @@ static int regmap_mmio_gather_write(void *context,
81 118
82static int regmap_mmio_write(void *context, const void *data, size_t count) 119static int regmap_mmio_write(void *context, const void *data, size_t count)
83{ 120{
84 BUG_ON(count < 4); 121 struct regmap_mmio_context *ctx = context;
122 u32 offset = ctx->reg_bytes + ctx->pad_bytes;
123
124 regmap_mmio_count_check(count);
85 125
86 return regmap_mmio_gather_write(context, data, 4, data + 4, count - 4); 126 return regmap_mmio_gather_write(context, data, ctx->reg_bytes,
127 data + offset, count - offset);
87} 128}
88 129
89static int regmap_mmio_read(void *context, 130static int regmap_mmio_read(void *context,
@@ -94,7 +135,7 @@ static int regmap_mmio_read(void *context,
94 u32 offset; 135 u32 offset;
95 int ret; 136 int ret;
96 137
97 BUG_ON(reg_size != 4); 138 regmap_mmio_regsize_check(reg_size);
98 139
99 if (!IS_ERR(ctx->clk)) { 140 if (!IS_ERR(ctx->clk)) {
100 ret = clk_enable(ctx->clk); 141 ret = clk_enable(ctx->clk);
@@ -165,8 +206,9 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
165 int min_stride; 206 int min_stride;
166 int ret; 207 int ret;
167 208
168 if (config->reg_bits != 32) 209 ret = regmap_mmio_regbits_check(config->reg_bits);
169 return ERR_PTR(-EINVAL); 210 if (ret)
211 return ERR_PTR(ret);
170 212
171 if (config->pad_bits) 213 if (config->pad_bits)
172 return ERR_PTR(-EINVAL); 214 return ERR_PTR(-EINVAL);
@@ -209,6 +251,8 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
209 251
210 ctx->regs = regs; 252 ctx->regs = regs;
211 ctx->val_bytes = config->val_bits / 8; 253 ctx->val_bytes = config->val_bits / 8;
254 ctx->reg_bytes = config->reg_bits / 8;
255 ctx->pad_bytes = config->pad_bits / 8;
212 ctx->clk = ERR_PTR(-ENODEV); 256 ctx->clk = ERR_PTR(-ENODEV);
213 257
214 if (clk_id == NULL) 258 if (clk_id == NULL)
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 92d9b79ff93e..d0a072463a04 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -380,6 +380,28 @@ static void regmap_range_exit(struct regmap *map)
380 kfree(map->selector_work_buf); 380 kfree(map->selector_work_buf);
381} 381}
382 382
383int regmap_attach_dev(struct device *dev, struct regmap *map,
384 const struct regmap_config *config)
385{
386 struct regmap **m;
387
388 map->dev = dev;
389
390 regmap_debugfs_init(map, config->name);
391
392 /* Add a devres resource for dev_get_regmap() */
393 m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL);
394 if (!m) {
395 regmap_debugfs_exit(map);
396 return -ENOMEM;
397 }
398 *m = map;
399 devres_add(dev, m);
400
401 return 0;
402}
403EXPORT_SYMBOL_GPL(regmap_attach_dev);
404
383/** 405/**
384 * regmap_init(): Initialise register map 406 * regmap_init(): Initialise register map
385 * 407 *
@@ -397,7 +419,7 @@ struct regmap *regmap_init(struct device *dev,
397 void *bus_context, 419 void *bus_context,
398 const struct regmap_config *config) 420 const struct regmap_config *config)
399{ 421{
400 struct regmap *map, **m; 422 struct regmap *map;
401 int ret = -EINVAL; 423 int ret = -EINVAL;
402 enum regmap_endian reg_endian, val_endian; 424 enum regmap_endian reg_endian, val_endian;
403 int i, j; 425 int i, j;
@@ -439,6 +461,7 @@ struct regmap *regmap_init(struct device *dev,
439 else 461 else
440 map->reg_stride = 1; 462 map->reg_stride = 1;
441 map->use_single_rw = config->use_single_rw; 463 map->use_single_rw = config->use_single_rw;
464 map->can_multi_write = config->can_multi_write;
442 map->dev = dev; 465 map->dev = dev;
443 map->bus = bus; 466 map->bus = bus;
444 map->bus_context = bus_context; 467 map->bus_context = bus_context;
@@ -734,25 +757,18 @@ skip_format_initialization:
734 } 757 }
735 } 758 }
736 759
737 regmap_debugfs_init(map, config->name);
738
739 ret = regcache_init(map, config); 760 ret = regcache_init(map, config);
740 if (ret != 0) 761 if (ret != 0)
741 goto err_range; 762 goto err_range;
742 763
743 /* Add a devres resource for dev_get_regmap() */ 764 if (dev)
744 m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); 765 ret = regmap_attach_dev(dev, map, config);
745 if (!m) { 766 if (ret != 0)
746 ret = -ENOMEM; 767 goto err_regcache;
747 goto err_debugfs;
748 }
749 *m = map;
750 devres_add(dev, m);
751 768
752 return map; 769 return map;
753 770
754err_debugfs: 771err_regcache:
755 regmap_debugfs_exit(map);
756 regcache_exit(map); 772 regcache_exit(map);
757err_range: 773err_range:
758 regmap_range_exit(map); 774 regmap_range_exit(map);
@@ -1520,12 +1536,12 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1520 if (reg % map->reg_stride) 1536 if (reg % map->reg_stride)
1521 return -EINVAL; 1537 return -EINVAL;
1522 1538
1523 map->lock(map->lock_arg);
1524 /* 1539 /*
1525 * Some devices don't support bulk write, for 1540 * Some devices don't support bulk write, for
1526 * them we have a series of single write operations. 1541 * them we have a series of single write operations.
1527 */ 1542 */
1528 if (!map->bus || map->use_single_rw) { 1543 if (!map->bus || map->use_single_rw) {
1544 map->lock(map->lock_arg);
1529 for (i = 0; i < val_count; i++) { 1545 for (i = 0; i < val_count; i++) {
1530 unsigned int ival; 1546 unsigned int ival;
1531 1547
@@ -1554,31 +1570,239 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1554 if (ret != 0) 1570 if (ret != 0)
1555 goto out; 1571 goto out;
1556 } 1572 }
1573out:
1574 map->unlock(map->lock_arg);
1557 } else { 1575 } else {
1558 void *wval; 1576 void *wval;
1559 1577
1560 wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL); 1578 wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
1561 if (!wval) { 1579 if (!wval) {
1562 ret = -ENOMEM;
1563 dev_err(map->dev, "Error in memory allocation\n"); 1580 dev_err(map->dev, "Error in memory allocation\n");
1564 goto out; 1581 return -ENOMEM;
1565 } 1582 }
1566 for (i = 0; i < val_count * val_bytes; i += val_bytes) 1583 for (i = 0; i < val_count * val_bytes; i += val_bytes)
1567 map->format.parse_inplace(wval + i); 1584 map->format.parse_inplace(wval + i);
1568 1585
1586 map->lock(map->lock_arg);
1569 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count); 1587 ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
1588 map->unlock(map->lock_arg);
1570 1589
1571 kfree(wval); 1590 kfree(wval);
1572 } 1591 }
1573out:
1574 map->unlock(map->lock_arg);
1575 return ret; 1592 return ret;
1576} 1593}
1577EXPORT_SYMBOL_GPL(regmap_bulk_write); 1594EXPORT_SYMBOL_GPL(regmap_bulk_write);
1578 1595
1579/* 1596/*
1597 * _regmap_raw_multi_reg_write()
1598 *
1599 * the (register,newvalue) pairs in regs have not been formatted, but
1600 * they are all in the same page and have been changed to being page
1601 * relative. The page register has been written if that was neccessary.
1602 */
1603static int _regmap_raw_multi_reg_write(struct regmap *map,
1604 const struct reg_default *regs,
1605 size_t num_regs)
1606{
1607 int ret;
1608 void *buf;
1609 int i;
1610 u8 *u8;
1611 size_t val_bytes = map->format.val_bytes;
1612 size_t reg_bytes = map->format.reg_bytes;
1613 size_t pad_bytes = map->format.pad_bytes;
1614 size_t pair_size = reg_bytes + pad_bytes + val_bytes;
1615 size_t len = pair_size * num_regs;
1616
1617 buf = kzalloc(len, GFP_KERNEL);
1618 if (!buf)
1619 return -ENOMEM;
1620
1621 /* We have to linearise by hand. */
1622
1623 u8 = buf;
1624
1625 for (i = 0; i < num_regs; i++) {
1626 int reg = regs[i].reg;
1627 int val = regs[i].def;
1628 trace_regmap_hw_write_start(map->dev, reg, 1);
1629 map->format.format_reg(u8, reg, map->reg_shift);
1630 u8 += reg_bytes + pad_bytes;
1631 map->format.format_val(u8, val, 0);
1632 u8 += val_bytes;
1633 }
1634 u8 = buf;
1635 *u8 |= map->write_flag_mask;
1636
1637 ret = map->bus->write(map->bus_context, buf, len);
1638
1639 kfree(buf);
1640
1641 for (i = 0; i < num_regs; i++) {
1642 int reg = regs[i].reg;
1643 trace_regmap_hw_write_done(map->dev, reg, 1);
1644 }
1645 return ret;
1646}
1647
1648static unsigned int _regmap_register_page(struct regmap *map,
1649 unsigned int reg,
1650 struct regmap_range_node *range)
1651{
1652 unsigned int win_page = (reg - range->range_min) / range->window_len;
1653
1654 return win_page;
1655}
1656
1657static int _regmap_range_multi_paged_reg_write(struct regmap *map,
1658 struct reg_default *regs,
1659 size_t num_regs)
1660{
1661 int ret;
1662 int i, n;
1663 struct reg_default *base;
1664 unsigned int this_page;
1665 /*
1666 * the set of registers are not neccessarily in order, but
1667 * since the order of write must be preserved this algorithm
1668 * chops the set each time the page changes
1669 */
1670 base = regs;
1671 for (i = 0, n = 0; i < num_regs; i++, n++) {
1672 unsigned int reg = regs[i].reg;
1673 struct regmap_range_node *range;
1674
1675 range = _regmap_range_lookup(map, reg);
1676 if (range) {
1677 unsigned int win_page = _regmap_register_page(map, reg,
1678 range);
1679
1680 if (i == 0)
1681 this_page = win_page;
1682 if (win_page != this_page) {
1683 this_page = win_page;
1684 ret = _regmap_raw_multi_reg_write(map, base, n);
1685 if (ret != 0)
1686 return ret;
1687 base += n;
1688 n = 0;
1689 }
1690 ret = _regmap_select_page(map, &base[n].reg, range, 1);
1691 if (ret != 0)
1692 return ret;
1693 }
1694 }
1695 if (n > 0)
1696 return _regmap_raw_multi_reg_write(map, base, n);
1697 return 0;
1698}
1699
1700static int _regmap_multi_reg_write(struct regmap *map,
1701 const struct reg_default *regs,
1702 size_t num_regs)
1703{
1704 int i;
1705 int ret;
1706
1707 if (!map->can_multi_write) {
1708 for (i = 0; i < num_regs; i++) {
1709 ret = _regmap_write(map, regs[i].reg, regs[i].def);
1710 if (ret != 0)
1711 return ret;
1712 }
1713 return 0;
1714 }
1715
1716 if (!map->format.parse_inplace)
1717 return -EINVAL;
1718
1719 if (map->writeable_reg)
1720 for (i = 0; i < num_regs; i++) {
1721 int reg = regs[i].reg;
1722 if (!map->writeable_reg(map->dev, reg))
1723 return -EINVAL;
1724 if (reg % map->reg_stride)
1725 return -EINVAL;
1726 }
1727
1728 if (!map->cache_bypass) {
1729 for (i = 0; i < num_regs; i++) {
1730 unsigned int val = regs[i].def;
1731 unsigned int reg = regs[i].reg;
1732 ret = regcache_write(map, reg, val);
1733 if (ret) {
1734 dev_err(map->dev,
1735 "Error in caching of register: %x ret: %d\n",
1736 reg, ret);
1737 return ret;
1738 }
1739 }
1740 if (map->cache_only) {
1741 map->cache_dirty = true;
1742 return 0;
1743 }
1744 }
1745
1746 WARN_ON(!map->bus);
1747
1748 for (i = 0; i < num_regs; i++) {
1749 unsigned int reg = regs[i].reg;
1750 struct regmap_range_node *range;
1751 range = _regmap_range_lookup(map, reg);
1752 if (range) {
1753 size_t len = sizeof(struct reg_default)*num_regs;
1754 struct reg_default *base = kmemdup(regs, len,
1755 GFP_KERNEL);
1756 if (!base)
1757 return -ENOMEM;
1758 ret = _regmap_range_multi_paged_reg_write(map, base,
1759 num_regs);
1760 kfree(base);
1761
1762 return ret;
1763 }
1764 }
1765 return _regmap_raw_multi_reg_write(map, regs, num_regs);
1766}
1767
1768/*
1580 * regmap_multi_reg_write(): Write multiple registers to the device 1769 * regmap_multi_reg_write(): Write multiple registers to the device
1581 * 1770 *
1771 * where the set of register,value pairs are supplied in any order,
1772 * possibly not all in a single range.
1773 *
1774 * @map: Register map to write to
1775 * @regs: Array of structures containing register,value to be written
1776 * @num_regs: Number of registers to write
1777 *
1778 * The 'normal' block write mode will send ultimately send data on the
1779 * target bus as R,V1,V2,V3,..,Vn where successively higer registers are
1780 * addressed. However, this alternative block multi write mode will send
1781 * the data as R1,V1,R2,V2,..,Rn,Vn on the target bus. The target device
1782 * must of course support the mode.
1783 *
1784 * A value of zero will be returned on success, a negative errno will be
1785 * returned in error cases.
1786 */
1787int regmap_multi_reg_write(struct regmap *map, const struct reg_default *regs,
1788 int num_regs)
1789{
1790 int ret;
1791
1792 map->lock(map->lock_arg);
1793
1794 ret = _regmap_multi_reg_write(map, regs, num_regs);
1795
1796 map->unlock(map->lock_arg);
1797
1798 return ret;
1799}
1800EXPORT_SYMBOL_GPL(regmap_multi_reg_write);
1801
1802/*
1803 * regmap_multi_reg_write_bypassed(): Write multiple registers to the
1804 * device but not the cache
1805 *
1582 * where the set of register are supplied in any order 1806 * where the set of register are supplied in any order
1583 * 1807 *
1584 * @map: Register map to write to 1808 * @map: Register map to write to
@@ -1592,30 +1816,27 @@ EXPORT_SYMBOL_GPL(regmap_bulk_write);
1592 * A value of zero will be returned on success, a negative errno will 1816 * A value of zero will be returned on success, a negative errno will
1593 * be returned in error cases. 1817 * be returned in error cases.
1594 */ 1818 */
1595int regmap_multi_reg_write(struct regmap *map, struct reg_default *regs, 1819int regmap_multi_reg_write_bypassed(struct regmap *map,
1596 int num_regs) 1820 const struct reg_default *regs,
1821 int num_regs)
1597{ 1822{
1598 int ret = 0, i; 1823 int ret;
1599 1824 bool bypass;
1600 for (i = 0; i < num_regs; i++) {
1601 int reg = regs[i].reg;
1602 if (reg % map->reg_stride)
1603 return -EINVAL;
1604 }
1605 1825
1606 map->lock(map->lock_arg); 1826 map->lock(map->lock_arg);
1607 1827
1608 for (i = 0; i < num_regs; i++) { 1828 bypass = map->cache_bypass;
1609 ret = _regmap_write(map, regs[i].reg, regs[i].def); 1829 map->cache_bypass = true;
1610 if (ret != 0) 1830
1611 goto out; 1831 ret = _regmap_multi_reg_write(map, regs, num_regs);
1612 } 1832
1613out: 1833 map->cache_bypass = bypass;
1834
1614 map->unlock(map->lock_arg); 1835 map->unlock(map->lock_arg);
1615 1836
1616 return ret; 1837 return ret;
1617} 1838}
1618EXPORT_SYMBOL_GPL(regmap_multi_reg_write); 1839EXPORT_SYMBOL_GPL(regmap_multi_reg_write_bypassed);
1619 1840
1620/** 1841/**
1621 * regmap_raw_write_async(): Write raw values to one or more registers 1842 * regmap_raw_write_async(): Write raw values to one or more registers
@@ -2176,35 +2397,21 @@ EXPORT_SYMBOL_GPL(regmap_async_complete);
2176 * apply them immediately. Typically this is used to apply 2397 * apply them immediately. Typically this is used to apply
2177 * corrections to be applied to the device defaults on startup, such 2398 * corrections to be applied to the device defaults on startup, such
2178 * as the updates some vendors provide to undocumented registers. 2399 * as the updates some vendors provide to undocumented registers.
2400 *
2401 * The caller must ensure that this function cannot be called
2402 * concurrently with either itself or regcache_sync().
2179 */ 2403 */
2180int regmap_register_patch(struct regmap *map, const struct reg_default *regs, 2404int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
2181 int num_regs) 2405 int num_regs)
2182{ 2406{
2183 struct reg_default *p; 2407 struct reg_default *p;
2184 int i, ret; 2408 int ret;
2185 bool bypass; 2409 bool bypass;
2186 2410
2187 if (WARN_ONCE(num_regs <= 0, "invalid registers number (%d)\n", 2411 if (WARN_ONCE(num_regs <= 0, "invalid registers number (%d)\n",
2188 num_regs)) 2412 num_regs))
2189 return 0; 2413 return 0;
2190 2414
2191 map->lock(map->lock_arg);
2192
2193 bypass = map->cache_bypass;
2194
2195 map->cache_bypass = true;
2196 map->async = true;
2197
2198 /* Write out first; it's useful to apply even if we fail later. */
2199 for (i = 0; i < num_regs; i++) {
2200 ret = _regmap_write(map, regs[i].reg, regs[i].def);
2201 if (ret != 0) {
2202 dev_err(map->dev, "Failed to write %x = %x: %d\n",
2203 regs[i].reg, regs[i].def, ret);
2204 goto out;
2205 }
2206 }
2207
2208 p = krealloc(map->patch, 2415 p = krealloc(map->patch,
2209 sizeof(struct reg_default) * (map->patch_regs + num_regs), 2416 sizeof(struct reg_default) * (map->patch_regs + num_regs),
2210 GFP_KERNEL); 2417 GFP_KERNEL);
@@ -2213,9 +2420,20 @@ int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
2213 map->patch = p; 2420 map->patch = p;
2214 map->patch_regs += num_regs; 2421 map->patch_regs += num_regs;
2215 } else { 2422 } else {
2216 ret = -ENOMEM; 2423 return -ENOMEM;
2217 } 2424 }
2218 2425
2426 map->lock(map->lock_arg);
2427
2428 bypass = map->cache_bypass;
2429
2430 map->cache_bypass = true;
2431 map->async = true;
2432
2433 ret = _regmap_multi_reg_write(map, regs, num_regs);
2434 if (ret != 0)
2435 goto out;
2436
2219out: 2437out:
2220 map->async = false; 2438 map->async = false;
2221 map->cache_bypass = bypass; 2439 map->cache_bypass = bypass;
@@ -2243,6 +2461,18 @@ int regmap_get_val_bytes(struct regmap *map)
2243} 2461}
2244EXPORT_SYMBOL_GPL(regmap_get_val_bytes); 2462EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
2245 2463
2464int regmap_parse_val(struct regmap *map, const void *buf,
2465 unsigned int *val)
2466{
2467 if (!map->format.parse_val)
2468 return -EINVAL;
2469
2470 *val = map->format.parse_val(buf);
2471
2472 return 0;
2473}
2474EXPORT_SYMBOL_GPL(regmap_parse_val);
2475
2246static int __init regmap_initcall(void) 2476static int __init regmap_initcall(void)
2247{ 2477{
2248 regmap_debugfs_initcall(); 2478 regmap_debugfs_initcall();