@@ -1007,6 +1007,108 @@ static void cache_drop(struct kunit *test)
1007
1007
KUNIT_EXPECT_MEMEQ (test , & data -> vals [param -> from_reg ], rval , sizeof (rval ));
1008
1008
}
1009
1009
1010
+ static void cache_drop_with_non_contiguous_ranges (struct kunit * test )
1011
+ {
1012
+ const struct regmap_test_param * param = test -> param_value ;
1013
+ struct regmap * map ;
1014
+ struct regmap_config config ;
1015
+ struct regmap_ram_data * data ;
1016
+ unsigned int val [4 ][BLOCK_TEST_SIZE ];
1017
+ unsigned int reg ;
1018
+ const int num_ranges = ARRAY_SIZE (val ) * 2 ;
1019
+ int rangeidx , i ;
1020
+
1021
+ static_assert (ARRAY_SIZE (val ) == 4 );
1022
+
1023
+ config = test_regmap_config ;
1024
+ config .max_register = param -> from_reg + (num_ranges * BLOCK_TEST_SIZE );
1025
+
1026
+ map = gen_regmap (test , & config , & data );
1027
+ KUNIT_ASSERT_FALSE (test , IS_ERR (map ));
1028
+ if (IS_ERR (map ))
1029
+ return ;
1030
+
1031
+ for (i = 0 ; i < config .max_register + 1 ; i ++ )
1032
+ data -> written [i ] = false;
1033
+
1034
+ /* Create non-contiguous cache blocks by writing every other range */
1035
+ get_random_bytes (& val , sizeof (val ));
1036
+ for (rangeidx = 0 ; rangeidx < num_ranges ; rangeidx += 2 ) {
1037
+ reg = param -> from_reg + (rangeidx * BLOCK_TEST_SIZE );
1038
+ KUNIT_EXPECT_EQ (test , 0 , regmap_bulk_write (map , reg ,
1039
+ & val [rangeidx / 2 ],
1040
+ BLOCK_TEST_SIZE ));
1041
+ KUNIT_EXPECT_MEMEQ (test , & data -> vals [reg ],
1042
+ & val [rangeidx / 2 ], sizeof (val [rangeidx / 2 ]));
1043
+ }
1044
+
1045
+ /* Check that odd ranges weren't written */
1046
+ for (rangeidx = 1 ; rangeidx < num_ranges ; rangeidx += 2 ) {
1047
+ reg = param -> from_reg + (rangeidx * BLOCK_TEST_SIZE );
1048
+ for (i = 0 ; i < BLOCK_TEST_SIZE ; i ++ )
1049
+ KUNIT_EXPECT_FALSE (test , data -> written [reg + i ]);
1050
+ }
1051
+
1052
+ /* Drop range 2 */
1053
+ reg = param -> from_reg + (2 * BLOCK_TEST_SIZE );
1054
+ KUNIT_EXPECT_EQ (test , 0 , regcache_drop_region (map , reg , reg + BLOCK_TEST_SIZE - 1 ));
1055
+
1056
+ /* Drop part of range 4 */
1057
+ reg = param -> from_reg + (4 * BLOCK_TEST_SIZE );
1058
+ KUNIT_EXPECT_EQ (test , 0 , regcache_drop_region (map , reg + 3 , reg + 5 ));
1059
+
1060
+ /* Mark dirty and reset mock registers to 0 */
1061
+ regcache_mark_dirty (map );
1062
+ for (i = 0 ; i < config .max_register + 1 ; i ++ ) {
1063
+ data -> vals [i ] = 0 ;
1064
+ data -> written [i ] = false;
1065
+ }
1066
+
1067
+ /* The registers that were dropped from range 4 should now remain at 0 */
1068
+ val [4 / 2 ][3 ] = 0 ;
1069
+ val [4 / 2 ][4 ] = 0 ;
1070
+ val [4 / 2 ][5 ] = 0 ;
1071
+
1072
+ /* Sync and check that the expected register ranges were written */
1073
+ KUNIT_EXPECT_EQ (test , 0 , regcache_sync (map ));
1074
+
1075
+ /* Check that odd ranges weren't written */
1076
+ for (rangeidx = 1 ; rangeidx < num_ranges ; rangeidx += 2 ) {
1077
+ reg = param -> from_reg + (rangeidx * BLOCK_TEST_SIZE );
1078
+ for (i = 0 ; i < BLOCK_TEST_SIZE ; i ++ )
1079
+ KUNIT_EXPECT_FALSE (test , data -> written [reg + i ]);
1080
+ }
1081
+
1082
+ /* Check that even ranges (except 2 and 4) were written */
1083
+ for (rangeidx = 0 ; rangeidx < num_ranges ; rangeidx += 2 ) {
1084
+ if ((rangeidx == 2 ) || (rangeidx == 4 ))
1085
+ continue ;
1086
+
1087
+ reg = param -> from_reg + (rangeidx * BLOCK_TEST_SIZE );
1088
+ for (i = 0 ; i < BLOCK_TEST_SIZE ; i ++ )
1089
+ KUNIT_EXPECT_TRUE (test , data -> written [reg + i ]);
1090
+
1091
+ KUNIT_EXPECT_MEMEQ (test , & data -> vals [reg ],
1092
+ & val [rangeidx / 2 ], sizeof (val [rangeidx / 2 ]));
1093
+ }
1094
+
1095
+ /* Check that range 2 wasn't written */
1096
+ reg = param -> from_reg + (2 * BLOCK_TEST_SIZE );
1097
+ for (i = 0 ; i < BLOCK_TEST_SIZE ; i ++ )
1098
+ KUNIT_EXPECT_FALSE (test , data -> written [reg + i ]);
1099
+
1100
+ /* Check that range 4 was partially written */
1101
+ reg = param -> from_reg + (4 * BLOCK_TEST_SIZE );
1102
+ for (i = 0 ; i < BLOCK_TEST_SIZE ; i ++ )
1103
+ KUNIT_EXPECT_EQ (test , data -> written [reg + i ], i < 3 || i > 5 );
1104
+
1105
+ KUNIT_EXPECT_MEMEQ (test , & data -> vals [reg ], & val [4 / 2 ], sizeof (val [4 / 2 ]));
1106
+
1107
+ /* Nothing before param->from_reg should have been written */
1108
+ for (i = 0 ; i < param -> from_reg ; i ++ )
1109
+ KUNIT_EXPECT_FALSE (test , data -> written [i ]);
1110
+ }
1111
+
1010
1112
static void cache_drop_all_and_sync_marked_dirty (struct kunit * test )
1011
1113
{
1012
1114
const struct regmap_test_param * param = test -> param_value ;
@@ -1663,6 +1765,7 @@ static struct kunit_case regmap_test_cases[] = {
1663
1765
KUNIT_CASE_PARAM (cache_sync_readonly , real_cache_types_gen_params ),
1664
1766
KUNIT_CASE_PARAM (cache_sync_patch , real_cache_types_gen_params ),
1665
1767
KUNIT_CASE_PARAM (cache_drop , sparse_cache_types_gen_params ),
1768
+ KUNIT_CASE_PARAM (cache_drop_with_non_contiguous_ranges , sparse_cache_types_gen_params ),
1666
1769
KUNIT_CASE_PARAM (cache_drop_all_and_sync_marked_dirty , sparse_cache_types_gen_params ),
1667
1770
KUNIT_CASE_PARAM (cache_drop_all_and_sync_no_defaults , sparse_cache_types_gen_params ),
1668
1771
KUNIT_CASE_PARAM (cache_drop_all_and_sync_has_defaults , sparse_cache_types_gen_params ),
0 commit comments