enum regmap_endian reg_endian, val_endian;
        int i, j;
 
-       if (!bus || !config)
+       if (!config)
                goto err;
 
        map = kzalloc(sizeof(*map), GFP_KERNEL);
                map->unlock = config->unlock;
                map->lock_arg = config->lock_arg;
        } else {
-               if (bus->fast_io) {
+               if ((bus && bus->fast_io) ||
+                   config->fast_io) {
                        spin_lock_init(&map->spinlock);
                        map->lock = regmap_lock_spinlock;
                        map->unlock = regmap_unlock_spinlock;
        if (config->read_flag_mask || config->write_flag_mask) {
                map->read_flag_mask = config->read_flag_mask;
                map->write_flag_mask = config->write_flag_mask;
-       } else {
+       } else if (bus) {
                map->read_flag_mask = bus->read_flag_mask;
        }
 
-       map->reg_read = _regmap_bus_read;
+       if (!bus) {
+               map->reg_read  = config->reg_read;
+               map->reg_write = config->reg_write;
+
+               map->defer_caching = false;
+               goto skip_format_initialization;
+       } else {
+               map->reg_read  = _regmap_bus_read;
+       }
 
        reg_endian = config->reg_format_endian;
        if (reg_endian == REGMAP_ENDIAN_DEFAULT)
                goto err_map;
        }
 
-       if (map->format.format_write)
+       if (map->format.format_write) {
+               map->defer_caching = false;
                map->reg_write = _regmap_bus_formatted_write;
-       else if (map->format.format_val)
+       } else if (map->format.format_val) {
+               map->defer_caching = true;
                map->reg_write = _regmap_bus_raw_write;
+       }
+
+skip_format_initialization:
 
        map->range_tree = RB_ROOT;
        for (i = 0; i < config->num_ranges; i++) {
        regcache_exit(map);
        regmap_debugfs_exit(map);
        regmap_range_exit(map);
-       if (map->bus->free_context)
+       if (map->bus && map->bus->free_context)
                map->bus->free_context(map->bus_context);
        kfree(map->work_buf);
        kfree(map);
        size_t len;
        int i;
 
+       BUG_ON(!map->bus);
+
        /* Check for unwritable registers before we start */
        if (map->writeable_reg)
                for (i = 0; i < val_len / map->format.val_bytes; i++)
        struct regmap_range_node *range;
        struct regmap *map = context;
 
-       BUG_ON(!map->format.format_write);
+       BUG_ON(!map->bus || !map->format.format_write);
 
        range = _regmap_range_lookup(map, reg);
        if (range) {
 {
        struct regmap *map = context;
 
-       BUG_ON(!map->format.format_val);
+       BUG_ON(!map->bus || !map->format.format_val);
 
        map->format.format_val(map->work_buf + map->format.reg_bytes
                               + map->format.pad_bytes, val, 0);
                                 map->format.val_bytes);
 }
 
+static inline void *_regmap_map_get_context(struct regmap *map)
+{
+       return (map->bus) ? map : map->bus_context;
+}
+
 int _regmap_write(struct regmap *map, unsigned int reg,
                  unsigned int val)
 {
        int ret;
+       void *context = _regmap_map_get_context(map);
 
-       if (!map->cache_bypass && map->format.format_write) {
+       if (!map->cache_bypass && !map->defer_caching) {
                ret = regcache_write(map, reg, val);
                if (ret != 0)
                        return ret;
 
        trace_regmap_reg_write(map->dev, reg, val);
 
-       return map->reg_write(map, reg, val);
+       return map->reg_write(context, reg, val);
 }
 
 /**
 {
        int ret;
 
+       if (!map->bus)
+               return -EINVAL;
        if (val_len % map->format.val_bytes)
                return -EINVAL;
        if (reg % map->reg_stride)
        size_t val_bytes = map->format.val_bytes;
        void *wval;
 
+       if (!map->bus)
+               return -EINVAL;
        if (!map->format.parse_val)
                return -EINVAL;
        if (reg % map->reg_stride)
        u8 *u8 = map->work_buf;
        int ret;
 
+       BUG_ON(!map->bus);
+
        range = _regmap_range_lookup(map, reg);
        if (range) {
                ret = _regmap_select_page(map, ®, range,
                        unsigned int *val)
 {
        int ret;
+       void *context = _regmap_map_get_context(map);
+
        BUG_ON(!map->reg_read);
 
        if (!map->cache_bypass) {
        if (map->cache_only)
                return -EBUSY;
 
-       ret = map->reg_read(map, reg, val);
+       ret = map->reg_read(context, reg, val);
        if (ret == 0) {
 #ifdef LOG_DEVICE
                if (strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
        unsigned int v;
        int ret, i;
 
+       if (!map->bus)
+               return -EINVAL;
        if (val_len % map->format.val_bytes)
                return -EINVAL;
        if (reg % map->reg_stride)
        size_t val_bytes = map->format.val_bytes;
        bool vol = regmap_volatile_range(map, reg, val_count);
 
+       if (!map->bus)
+               return -EINVAL;
        if (!map->format.parse_val)
                return -EINVAL;
        if (reg % map->reg_stride)
 
  * @lock_arg:    this field is passed as the only argument of lock/unlock
  *               functions (ignored in case regular lock/unlock functions
  *               are not overridden).
- *
+ * @reg_read:    Optional callback that if filled will be used to perform
+ *               all the reads from the registers. Should only be provided for
+ *               devices whos read operation cannot be represented as a simple read
+ *               operation on a bus such as SPI, I2C, etc. Most of the devices do
+ *               not need this.
+ * @reg_write:   Same as above for writing.
+ * @fast_io:     Register IO is fast. Use a spinlock instead of a mutex
+ *               to perform locking. This field is ignored if custom lock/unlock
+ *               functions are used (see fields lock/unlock of struct regmap_config).
+ *               This field is a duplicate of a similar file in
+ *               'struct regmap_bus' and serves exact same purpose.
+ *                Use it only for "no-bus" cases.
  * @max_register: Optional, specifies the maximum valid register index.
  * @wr_table:     Optional, points to a struct regmap_access_table specifying
  *                valid ranges for write access.
        regmap_unlock unlock;
        void *lock_arg;
 
+       int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
+       int (*reg_write)(void *context, unsigned int reg, unsigned int val);
+
+       bool fast_io;
+
        unsigned int max_register;
        const struct regmap_access_table *wr_table;
        const struct regmap_access_table *rd_table;