@@ -397,11 +397,16 @@ static int rbtree_all(const void *key, const struct rb_node *node)
397397 * volatile. In general drivers can choose not to use the provided
398398 * syncing functionality if they so require.
399399 *
400+ * This pushes cached changes made while cache_only (e.g. suspend) down
401+ * to hardware. The caller must disable cache_only before calling this
402+ * function.
403+ *
400404 * Return a negative value on failure, 0 on success.
401405 */
402406int regcache_sync (struct regmap * map )
403407{
404- int ret = 0 ;
408+ int sync_ret = 0 ;
409+ int selector_ret = 0 ;
405410 unsigned int i ;
406411 const char * name ;
407412 bool bypass ;
@@ -413,6 +418,12 @@ int regcache_sync(struct regmap *map)
413418 BUG_ON (!map -> cache_ops );
414419
415420 map -> lock (map -> lock_arg );
421+
422+ if (WARN_ON (map -> cache_only )) {
423+ map -> unlock (map -> lock_arg );
424+ return - EINVAL ;
425+ }
426+
416427 /* Remember the initial bypass state */
417428 bypass = map -> cache_bypass ;
418429 dev_dbg (map -> dev , "Syncing %s cache\n" ,
@@ -426,21 +437,21 @@ int regcache_sync(struct regmap *map)
426437 /* Apply any patch first */
427438 map -> cache_bypass = true;
428439 for (i = 0 ; i < map -> patch_regs ; i ++ ) {
429- ret = _regmap_write (map , map -> patch [i ].reg , map -> patch [i ].def );
430- if (ret != 0 ) {
440+ sync_ret = _regmap_write (map , map -> patch [i ].reg , map -> patch [i ].def );
441+ if (sync_ret != 0 ) {
431442 dev_err (map -> dev , "Failed to write %x = %x: %d\n" ,
432- map -> patch [i ].reg , map -> patch [i ].def , ret );
443+ map -> patch [i ].reg , map -> patch [i ].def , sync_ret );
433444 goto out ;
434445 }
435446 }
436447 map -> cache_bypass = false;
437448
438449 if (map -> cache_ops -> sync )
439- ret = map -> cache_ops -> sync (map , 0 , map -> max_register );
450+ sync_ret = map -> cache_ops -> sync (map , 0 , map -> max_register );
440451 else
441- ret = regcache_default_sync (map , 0 , map -> max_register );
452+ sync_ret = regcache_default_sync (map , 0 , map -> max_register );
442453
443- if (ret == 0 )
454+ if (sync_ret == 0 )
444455 map -> cache_dirty = false;
445456
446457out :
@@ -462,10 +473,11 @@ int regcache_sync(struct regmap *map)
462473 if (regcache_read (map , this -> selector_reg , & i ) != 0 )
463474 continue ;
464475
465- ret = _regmap_write (map , this -> selector_reg , i );
466- if (ret != 0 ) {
476+ selector_ret = _regmap_write (map , this -> selector_reg , i );
477+ if (selector_ret != 0 ) {
478+ map -> cache_dirty = true;
467479 dev_err (map -> dev , "Failed to write %x = %x: %d\n" ,
468- this -> selector_reg , i , ret );
480+ this -> selector_reg , i , selector_ret );
469481 break ;
470482 }
471483 }
@@ -476,7 +488,7 @@ int regcache_sync(struct regmap *map)
476488
477489 trace_regcache_sync (map , name , "stop" );
478490
479- return ret ;
491+ return sync_ret ? sync_ret : selector_ret ;
480492}
481493EXPORT_SYMBOL_GPL (regcache_sync );
482494
@@ -506,6 +518,10 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
506518
507519 map -> lock (map -> lock_arg );
508520
521+ if (WARN_ON (map -> cache_only )) {
522+ map -> unlock (map -> lock_arg );
523+ return - EINVAL ;
524+ }
509525 /* Remember the initial bypass state */
510526 bypass = map -> cache_bypass ;
511527
0 commit comments