summaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2016-06-19 22:52:11 -0400
committerMark Brown <broonie@kernel.org>2016-06-29 14:48:00 -0400
commit5bf75b44972a7edffa9f52cddb291d66bc16a4d6 (patch)
treeb14f98269f20a31edf901527e703007f284376c6 /drivers/base
parent1a695a905c18548062509178b98bc91e67510864 (diff)
regmap: Support bulk writes for devices without raw formatting
When doing a bulk writes from a device which lacks raw I/O support we fall back to doing register at a time reads but we still use the raw formatters in order to render the data into the word size used by the device (since bulk reads still operate on the device word size rather than unsigned ints). This means that devices without raw formatting such as those that provide reg_read() are not supported. Provide handling for them by copying the values read into native endian values of the appropriate size. This complements commit d5b98eb12420 ("regmap: Support bulk reads for devices without raw formatting"). Signed-off-by: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/regmap/regmap.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index df2d2ef5d6b3..51fa7d66a393 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1777,8 +1777,6 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1777 size_t val_bytes = map->format.val_bytes; 1777 size_t val_bytes = map->format.val_bytes;
1778 size_t total_size = val_bytes * val_count; 1778 size_t total_size = val_bytes * val_count;
1779 1779
1780 if (map->bus && !map->format.parse_inplace)
1781 return -EINVAL;
1782 if (!IS_ALIGNED(reg, map->reg_stride)) 1780 if (!IS_ALIGNED(reg, map->reg_stride))
1783 return -EINVAL; 1781 return -EINVAL;
1784 1782
@@ -1789,7 +1787,8 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1789 * 1787 *
1790 * The first if block is used for memory mapped io. It does not allow 1788 * The first if block is used for memory mapped io. It does not allow
1791 * val_bytes of 3 for example. 1789 * val_bytes of 3 for example.
1792 * The second one is used for busses which do not have this limitation 1790 * The second one is for busses that do not provide raw I/O.
1791 * The third one is used for busses which do not have these limitations
1793 * and can write arbitrary value lengths. 1792 * and can write arbitrary value lengths.
1794 */ 1793 */
1795 if (!map->bus) { 1794 if (!map->bus) {
@@ -1825,6 +1824,32 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
1825 } 1824 }
1826out: 1825out:
1827 map->unlock(map->lock_arg); 1826 map->unlock(map->lock_arg);
1827 } else if (map->bus && !map->format.parse_inplace) {
1828 const u8 *u8 = val;
1829 const u16 *u16 = val;
1830 const u32 *u32 = val;
1831 unsigned int ival;
1832
1833 for (i = 0; i < val_count; i++) {
1834 switch (map->format.val_bytes) {
1835 case 4:
1836 ival = u32[i];
1837 break;
1838 case 2:
1839 ival = u16[i];
1840 break;
1841 case 1:
1842 ival = u8[i];
1843 break;
1844 default:
1845 return -EINVAL;
1846 }
1847
1848 ret = regmap_write(map, reg + (i * map->reg_stride),
1849 ival);
1850 if (ret)
1851 return ret;
1852 }
1828 } else if (map->use_single_write || 1853 } else if (map->use_single_write ||
1829 (map->max_raw_write && map->max_raw_write < total_size)) { 1854 (map->max_raw_write && map->max_raw_write < total_size)) {
1830 int chunk_stride = map->reg_stride; 1855 int chunk_stride = map->reg_stride;