@@ -412,11 +412,16 @@ static int rbtree_all(const void *key, const struct rb_node *node)
412412 * volatile. In general drivers can choose not to use the provided
413413 * syncing functionality if they so require.
414414 *
415+ * This pushes cached changes made while cache_only (e.g. suspend) down
416+ * to hardware. The caller must disable cache_only before calling this
417+ * function.
418+ *
415419 * Return a negative value on failure, 0 on success.
416420 */
417421int regcache_sync (struct regmap * map )
418422{
419- int ret = 0 ;
423+ int sync_ret = 0 ;
424+ int selector_ret = 0 ;
420425 unsigned int i ;
421426 const char * name ;
422427 bool bypass ;
@@ -428,6 +433,12 @@ int regcache_sync(struct regmap *map)
428433 BUG_ON (!map -> cache_ops );
429434
430435 map -> lock (map -> lock_arg );
436+
437+ if (WARN_ON (map -> cache_only )) {
438+ map -> unlock (map -> lock_arg );
439+ return - EINVAL ;
440+ }
441+
431442 /* Remember the initial bypass state */
432443 bypass = map -> cache_bypass ;
433444 dev_dbg (map -> dev , "Syncing %s cache\n" ,
@@ -441,21 +452,21 @@ int regcache_sync(struct regmap *map)
441452 /* Apply any patch first */
442453 map -> cache_bypass = true;
443454 for (i = 0 ; i < map -> patch_regs ; i ++ ) {
444- ret = _regmap_write (map , map -> patch [i ].reg , map -> patch [i ].def );
445- if (ret != 0 ) {
455+ sync_ret = _regmap_write (map , map -> patch [i ].reg , map -> patch [i ].def );
456+ if (sync_ret != 0 ) {
446457 dev_err (map -> dev , "Failed to write %x = %x: %d\n" ,
447- map -> patch [i ].reg , map -> patch [i ].def , ret );
458+ map -> patch [i ].reg , map -> patch [i ].def , sync_ret );
448459 goto out ;
449460 }
450461 }
451462 map -> cache_bypass = false;
452463
453464 if (map -> cache_ops -> sync )
454- ret = map -> cache_ops -> sync (map , 0 , map -> max_register );
465+ sync_ret = map -> cache_ops -> sync (map , 0 , map -> max_register );
455466 else
456- ret = regcache_default_sync (map , 0 , map -> max_register );
467+ sync_ret = regcache_default_sync (map , 0 , map -> max_register );
457468
458- if (ret == 0 )
469+ if (sync_ret == 0 )
459470 map -> cache_dirty = false;
460471
461472out :
@@ -477,10 +488,11 @@ int regcache_sync(struct regmap *map)
477488 if (regcache_read (map , this -> selector_reg , & i ) != 0 )
478489 continue ;
479490
480- ret = _regmap_write (map , this -> selector_reg , i );
481- if (ret != 0 ) {
491+ selector_ret = _regmap_write (map , this -> selector_reg , i );
492+ if (selector_ret != 0 ) {
493+ map -> cache_dirty = true;
482494 dev_err (map -> dev , "Failed to write %x = %x: %d\n" ,
483- this -> selector_reg , i , ret );
495+ this -> selector_reg , i , selector_ret );
484496 break ;
485497 }
486498 }
@@ -491,7 +503,7 @@ int regcache_sync(struct regmap *map)
491503
492504 trace_regcache_sync (map , name , "stop" );
493505
494- return ret ;
506+ return sync_ret ? sync_ret : selector_ret ;
495507}
496508EXPORT_SYMBOL_GPL (regcache_sync );
497509
@@ -521,6 +533,10 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
521533
522534 map -> lock (map -> lock_arg );
523535
536+ if (WARN_ON (map -> cache_only )) {
537+ map -> unlock (map -> lock_arg );
538+ return - EINVAL ;
539+ }
524540 /* Remember the initial bypass state */
525541 bypass = map -> cache_bypass ;
526542
0 commit comments