Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regmap: Custom bulk operations for regmaps

Merge series from Marek Vasut:

This patch adds an API for custom bulk operations on a simple regmap,
the number of single use bus implementations shows there's a need for
this.

+56 -36
+4
drivers/base/regmap/internal.h
··· 110 110 int (*reg_write)(void *context, unsigned int reg, unsigned int val); 111 111 int (*reg_update_bits)(void *context, unsigned int reg, 112 112 unsigned int mask, unsigned int val); 113 + /* Bulk read/write */ 114 + int (*read)(void *context, const void *reg_buf, size_t reg_size, 115 + void *val_buf, size_t val_size); 116 + int (*write)(void *context, const void *data, size_t count); 113 117 114 118 bool defer_caching; 115 119
+40 -36
drivers/base/regmap/regmap.c
··· 838 838 map->reg_stride_order = ilog2(map->reg_stride); 839 839 else 840 840 map->reg_stride_order = -1; 841 - map->use_single_read = config->use_single_read || !bus || !bus->read; 842 - map->use_single_write = config->use_single_write || !bus || !bus->write; 843 - map->can_multi_write = config->can_multi_write && bus && bus->write; 841 + map->use_single_read = config->use_single_read || !(config->read || (bus && bus->read)); 842 + map->use_single_write = config->use_single_write || !(config->write || (bus && bus->write)); 843 + map->can_multi_write = config->can_multi_write && (config->write || (bus && bus->write)); 844 844 if (bus) { 845 845 map->max_raw_read = bus->max_raw_read; 846 846 map->max_raw_write = bus->max_raw_write; 847 + } else if (config->max_raw_read && config->max_raw_write) { 848 + map->max_raw_read = config->max_raw_read; 849 + map->max_raw_write = config->max_raw_write; 847 850 } 848 851 map->dev = dev; 849 852 map->bus = bus; ··· 880 877 map->read_flag_mask = bus->read_flag_mask; 881 878 } 882 879 883 - if (!bus) { 880 + if (config && config->read && config->write) { 881 + map->reg_read = _regmap_bus_read; 882 + 883 + /* Bulk read/write */ 884 + map->read = config->read; 885 + map->write = config->write; 886 + 887 + reg_endian = REGMAP_ENDIAN_NATIVE; 888 + val_endian = REGMAP_ENDIAN_NATIVE; 889 + } else if (!bus) { 884 890 map->reg_read = config->reg_read; 885 891 map->reg_write = config->reg_write; 886 892 map->reg_update_bits = config->reg_update_bits; ··· 906 894 } else { 907 895 map->reg_read = _regmap_bus_read; 908 896 map->reg_update_bits = bus->reg_update_bits; 909 - } 897 + /* Bulk read/write */ 898 + map->read = bus->read; 899 + map->write = bus->write; 910 900 911 - reg_endian = regmap_get_reg_endian(bus, config); 912 - val_endian = regmap_get_val_endian(dev, bus, config); 901 + reg_endian = regmap_get_reg_endian(bus, config); 902 + val_endian = regmap_get_val_endian(dev, bus, config); 903 + } 913 904 914 905 switch (config->reg_bits + map->reg_shift) { 915 906 case 2: ··· 1686 1671 size_t len; 1687 1672 int i; 1688 1673 1689 - WARN_ON(!map->bus); 1690 - 1691 1674 /* Check for unwritable or noinc registers in range 1692 1675 * before we start 1693 1676 */ ··· 1767 1754 val = work_val; 1768 1755 } 1769 1756 1770 - if (map->async && map->bus->async_write) { 1757 + if (map->async && map->bus && map->bus->async_write) { 1771 1758 struct regmap_async *async; 1772 1759 1773 1760 trace_regmap_async_write_start(map, reg, val_len); ··· 1835 1822 * write. 1836 1823 */ 1837 1824 if (val == work_val) 1838 - ret = map->bus->write(map->bus_context, map->work_buf, 1839 - map->format.reg_bytes + 1840 - map->format.pad_bytes + 1841 - val_len); 1825 + ret = map->write(map->bus_context, map->work_buf, 1826 + map->format.reg_bytes + 1827 + map->format.pad_bytes + 1828 + val_len); 1842 1829 else if (map->bus->gather_write) 1843 1830 ret = map->bus->gather_write(map->bus_context, map->work_buf, 1844 1831 map->format.reg_bytes + ··· 1857 1844 memcpy(buf, map->work_buf, map->format.reg_bytes); 1858 1845 memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, 1859 1846 val, val_len); 1860 - ret = map->bus->write(map->bus_context, buf, len); 1847 + ret = map->write(map->bus_context, buf, len); 1861 1848 1862 1849 kfree(buf); 1863 1850 } else if (ret != 0 && !map->cache_bypass && map->format.parse_val) { ··· 1914 1901 struct regmap_range_node *range; 1915 1902 struct regmap *map = context; 1916 1903 1917 - WARN_ON(!map->bus || !map->format.format_write); 1904 + WARN_ON(!map->format.format_write); 1918 1905 1919 1906 range = _regmap_range_lookup(map, reg); 1920 1907 if (range) { ··· 1929 1916 1930 1917 trace_regmap_hw_write_start(map, reg, 1); 1931 1918 1932 - ret = map->bus->write(map->bus_context, map->work_buf, 1933 - map->format.buf_size); 1919 + ret = map->write(map->bus_context, map->work_buf, map->format.buf_size); 1934 1920 1935 1921 trace_regmap_hw_write_done(map, reg, 1); 1936 1922 ··· 1949 1937 { 1950 1938 struct regmap *map = context; 1951 1939 1952 - WARN_ON(!map->bus || !map->format.format_val); 1940 + WARN_ON(!map->format.format_val); 1953 1941 1954 1942 map->format.format_val(map->work_buf + map->format.reg_bytes 1955 1943 + map->format.pad_bytes, val, 0); ··· 1963 1951 1964 1952 static inline void *_regmap_map_get_context(struct regmap *map) 1965 1953 { 1966 - return (map->bus) ? map : map->bus_context; 1954 + return (map->bus || (!map->bus && map->read)) ? map : map->bus_context; 1967 1955 } 1968 1956 1969 1957 int _regmap_write(struct regmap *map, unsigned int reg, ··· 2375 2363 u8 = buf; 2376 2364 *u8 |= map->write_flag_mask; 2377 2365 2378 - ret = map->bus->write(map->bus_context, buf, len); 2366 + ret = map->write(map->bus_context, buf, len); 2379 2367 2380 2368 kfree(buf); 2381 2369 ··· 2681 2669 struct regmap_range_node *range; 2682 2670 int ret; 2683 2671 2684 - WARN_ON(!map->bus); 2685 - 2686 - if (!map->bus || !map->bus->read) 2672 + if (!map->read) 2687 2673 return -EINVAL; 2688 2674 2689 2675 range = _regmap_range_lookup(map, reg); ··· 2699 2689 map->read_flag_mask); 2700 2690 trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes); 2701 2691 2702 - ret = map->bus->read(map->bus_context, map->work_buf, 2703 - map->format.reg_bytes + map->format.pad_bytes, 2704 - val, val_len); 2692 + ret = map->read(map->bus_context, map->work_buf, 2693 + map->format.reg_bytes + map->format.pad_bytes, 2694 + val, val_len); 2705 2695 2706 2696 trace_regmap_hw_read_done(map, reg, val_len / map->format.val_bytes); 2707 2697 ··· 2812 2802 unsigned int v; 2813 2803 int ret, i; 2814 2804 2815 - if (!map->bus) 2816 - return -EINVAL; 2817 2805 if (val_len % map->format.val_bytes) 2818 2806 return -EINVAL; 2819 2807 if (!IS_ALIGNED(reg, map->reg_stride)) ··· 2826 2818 size_t chunk_count, chunk_bytes; 2827 2819 size_t chunk_regs = val_count; 2828 2820 2829 - if (!map->bus->read) { 2821 + if (!map->read) { 2830 2822 ret = -ENOTSUPP; 2831 2823 goto out; 2832 2824 } ··· 2886 2878 * @val: Pointer to data buffer 2887 2879 * @val_len: Length of output buffer in bytes. 2888 2880 * 2889 - * The regmap API usually assumes that bulk bus read operations will read a 2881 + * The regmap API usually assumes that bulk read operations will read a 2890 2882 * range of registers. Some devices have certain registers for which a read 2891 2883 * operation read will read from an internal FIFO. 2892 2884 * ··· 2904 2896 size_t read_len; 2905 2897 int ret; 2906 2898 2907 - if (!map->bus) 2908 - return -EINVAL; 2909 - if (!map->bus->read) 2910 - return -ENOTSUPP; 2911 2899 if (val_len % map->format.val_bytes) 2912 2900 return -EINVAL; 2913 2901 if (!IS_ALIGNED(reg, map->reg_stride)) ··· 3017 3013 if (val_count == 0) 3018 3014 return -EINVAL; 3019 3015 3020 - if (map->bus && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { 3016 + if (map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { 3021 3017 ret = regmap_raw_read(map, reg, val, val_bytes * val_count); 3022 3018 if (ret != 0) 3023 3019 return ret;
+12
include/linux/regmap.h
··· 299 299 * if the function require special handling with lock and reg 300 300 * handling and the operation cannot be represented as a simple 301 301 * update_bits operation on a bus such as SPI, I2C, etc. 302 + * @read: Optional callback that if filled will be used to perform all the 303 + * bulk reads from the registers. Data is returned in the buffer used 304 + * to transmit data. 305 + * @write: Same as above for writing. 306 + * @max_raw_read: Max raw read size that can be used on the device. 307 + * @max_raw_write: Max raw write size that can be used on the device. 302 308 * @fast_io: Register IO is fast. Use a spinlock instead of a mutex 303 309 * to perform locking. This field is ignored if custom lock/unlock 304 310 * functions are used (see fields lock/unlock of struct regmap_config). ··· 391 385 int (*reg_write)(void *context, unsigned int reg, unsigned int val); 392 386 int (*reg_update_bits)(void *context, unsigned int reg, 393 387 unsigned int mask, unsigned int val); 388 + /* Bulk read/write */ 389 + int (*read)(void *context, const void *reg_buf, size_t reg_size, 390 + void *val_buf, size_t val_size); 391 + int (*write)(void *context, const void *data, size_t count); 392 + size_t max_raw_read; 393 + size_t max_raw_write; 394 394 395 395 bool fast_io; 396 396