@@ -712,6 +712,327 @@ static void cache_drop(struct kunit *test)
712712 regmap_exit (map );
713713}
714714
715+ struct raw_test_types {
716+ const char * name ;
717+
718+ enum regcache_type cache_type ;
719+ enum regmap_endian val_endian ;
720+ };
721+
722+ static void raw_to_desc (const struct raw_test_types * t , char * desc )
723+ {
724+ strcpy (desc , t -> name );
725+ }
726+
727+ static const struct raw_test_types raw_types_list [] = {
728+ { "none-little" , REGCACHE_NONE , REGMAP_ENDIAN_LITTLE },
729+ { "none-big" , REGCACHE_NONE , REGMAP_ENDIAN_BIG },
730+ { "flat-little" , REGCACHE_FLAT , REGMAP_ENDIAN_LITTLE },
731+ { "flat-big" , REGCACHE_FLAT , REGMAP_ENDIAN_BIG },
732+ { "rbtree-little" , REGCACHE_RBTREE , REGMAP_ENDIAN_LITTLE },
733+ { "rbtree-big" , REGCACHE_RBTREE , REGMAP_ENDIAN_BIG },
734+ { "maple-little" , REGCACHE_MAPLE , REGMAP_ENDIAN_LITTLE },
735+ { "maple-big" , REGCACHE_MAPLE , REGMAP_ENDIAN_BIG },
736+ };
737+
738+ KUNIT_ARRAY_PARAM (raw_test_types , raw_types_list , raw_to_desc );
739+
740+ static const struct raw_test_types raw_cache_types_list [] = {
741+ { "flat-little" , REGCACHE_FLAT , REGMAP_ENDIAN_LITTLE },
742+ { "flat-big" , REGCACHE_FLAT , REGMAP_ENDIAN_BIG },
743+ { "rbtree-little" , REGCACHE_RBTREE , REGMAP_ENDIAN_LITTLE },
744+ { "rbtree-big" , REGCACHE_RBTREE , REGMAP_ENDIAN_BIG },
745+ { "maple-little" , REGCACHE_MAPLE , REGMAP_ENDIAN_LITTLE },
746+ { "maple-big" , REGCACHE_MAPLE , REGMAP_ENDIAN_BIG },
747+ };
748+
749+ KUNIT_ARRAY_PARAM (raw_test_cache_types , raw_cache_types_list , raw_to_desc );
750+
751+ static const struct regmap_config raw_regmap_config = {
752+ .max_register = BLOCK_TEST_SIZE ,
753+
754+ .reg_format_endian = REGMAP_ENDIAN_LITTLE ,
755+ .reg_bits = 16 ,
756+ .val_bits = 16 ,
757+ };
758+
759+ static struct regmap * gen_raw_regmap (struct regmap_config * config ,
760+ struct raw_test_types * test_type ,
761+ struct regmap_ram_data * * data )
762+ {
763+ u16 * buf ;
764+ struct regmap * ret ;
765+ size_t size = (config -> max_register + 1 ) * config -> reg_bits / 8 ;
766+ int i ;
767+ struct reg_default * defaults ;
768+
769+ config -> cache_type = test_type -> cache_type ;
770+ config -> val_format_endian = test_type -> val_endian ;
771+
772+ buf = kmalloc (size , GFP_KERNEL );
773+ if (!buf )
774+ return ERR_PTR (- ENOMEM );
775+
776+ get_random_bytes (buf , size );
777+
778+ * data = kzalloc (sizeof (* * data ), GFP_KERNEL );
779+ if (!(* data ))
780+ return ERR_PTR (- ENOMEM );
781+ (* data )-> vals = (void * )buf ;
782+
783+ config -> num_reg_defaults = config -> max_register + 1 ;
784+ defaults = kcalloc (config -> num_reg_defaults ,
785+ sizeof (struct reg_default ),
786+ GFP_KERNEL );
787+ if (!defaults )
788+ return ERR_PTR (- ENOMEM );
789+ config -> reg_defaults = defaults ;
790+
791+ for (i = 0 ; i < config -> num_reg_defaults ; i ++ ) {
792+ defaults [i ].reg = i ;
793+ switch (test_type -> val_endian ) {
794+ case REGMAP_ENDIAN_LITTLE :
795+ defaults [i ].def = le16_to_cpu (buf [i ]);
796+ break ;
797+ case REGMAP_ENDIAN_BIG :
798+ defaults [i ].def = be16_to_cpu (buf [i ]);
799+ break ;
800+ default :
801+ return ERR_PTR (- EINVAL );
802+ }
803+ }
804+
805+ /*
806+ * We use the defaults in the tests but they don't make sense
807+ * to the core if there's no cache.
808+ */
809+ if (config -> cache_type == REGCACHE_NONE )
810+ config -> num_reg_defaults = 0 ;
811+
812+ ret = regmap_init_raw_ram (config , * data );
813+ if (IS_ERR (ret )) {
814+ kfree (buf );
815+ kfree (* data );
816+ }
817+
818+ return ret ;
819+ }
820+
821+ static void raw_read_defaults_single (struct kunit * test )
822+ {
823+ struct raw_test_types * t = (struct raw_test_types * )test -> param_value ;
824+ struct regmap * map ;
825+ struct regmap_config config ;
826+ struct regmap_ram_data * data ;
827+ unsigned int rval ;
828+ int i ;
829+
830+ config = raw_regmap_config ;
831+
832+ map = gen_raw_regmap (& config , t , & data );
833+ KUNIT_ASSERT_FALSE (test , IS_ERR (map ));
834+ if (IS_ERR (map ))
835+ return ;
836+
837+ /* Check that we can read the defaults via the API */
838+ for (i = 0 ; i < config .max_register + 1 ; i ++ ) {
839+ KUNIT_EXPECT_EQ (test , 0 , regmap_read (map , i , & rval ));
840+ KUNIT_EXPECT_EQ (test , config .reg_defaults [i ].def , rval );
841+ }
842+
843+ regmap_exit (map );
844+ }
845+
846+ static void raw_read_defaults (struct kunit * test )
847+ {
848+ struct raw_test_types * t = (struct raw_test_types * )test -> param_value ;
849+ struct regmap * map ;
850+ struct regmap_config config ;
851+ struct regmap_ram_data * data ;
852+ u16 * rval ;
853+ u16 def ;
854+ size_t val_len ;
855+ int i ;
856+
857+ config = raw_regmap_config ;
858+
859+ map = gen_raw_regmap (& config , t , & data );
860+ KUNIT_ASSERT_FALSE (test , IS_ERR (map ));
861+ if (IS_ERR (map ))
862+ return ;
863+
864+ val_len = sizeof (* rval ) * (config .max_register + 1 );
865+ rval = kmalloc (val_len , GFP_KERNEL );
866+ KUNIT_ASSERT_TRUE (test , rval != NULL );
867+ if (!rval )
868+ return ;
869+
870+ /* Check that we can read the defaults via the API */
871+ KUNIT_EXPECT_EQ (test , 0 , regmap_raw_read (map , 0 , rval , val_len ));
872+ for (i = 0 ; i < config .max_register + 1 ; i ++ ) {
873+ def = config .reg_defaults [i ].def ;
874+ if (config .val_format_endian == REGMAP_ENDIAN_BIG ) {
875+ KUNIT_EXPECT_EQ (test , def , be16_to_cpu (rval [i ]));
876+ } else {
877+ KUNIT_EXPECT_EQ (test , def , le16_to_cpu (rval [i ]));
878+ }
879+ }
880+
881+ kfree (rval );
882+ regmap_exit (map );
883+ }
884+
885+ static void raw_write_read_single (struct kunit * test )
886+ {
887+ struct raw_test_types * t = (struct raw_test_types * )test -> param_value ;
888+ struct regmap * map ;
889+ struct regmap_config config ;
890+ struct regmap_ram_data * data ;
891+ u16 val ;
892+ unsigned int rval ;
893+
894+ config = raw_regmap_config ;
895+
896+ map = gen_raw_regmap (& config , t , & data );
897+ KUNIT_ASSERT_FALSE (test , IS_ERR (map ));
898+ if (IS_ERR (map ))
899+ return ;
900+
901+ get_random_bytes (& val , sizeof (val ));
902+
903+ /* If we write a value to a register we can read it back */
904+ KUNIT_EXPECT_EQ (test , 0 , regmap_write (map , 0 , val ));
905+ KUNIT_EXPECT_EQ (test , 0 , regmap_read (map , 0 , & rval ));
906+ KUNIT_EXPECT_EQ (test , val , rval );
907+
908+ regmap_exit (map );
909+ }
910+
911+ static void raw_write (struct kunit * test )
912+ {
913+ struct raw_test_types * t = (struct raw_test_types * )test -> param_value ;
914+ struct regmap * map ;
915+ struct regmap_config config ;
916+ struct regmap_ram_data * data ;
917+ u16 * hw_buf ;
918+ u16 val [2 ];
919+ unsigned int rval ;
920+ int i ;
921+
922+ config = raw_regmap_config ;
923+
924+ map = gen_raw_regmap (& config , t , & data );
925+ KUNIT_ASSERT_FALSE (test , IS_ERR (map ));
926+ if (IS_ERR (map ))
927+ return ;
928+
929+ hw_buf = (u16 * )data -> vals ;
930+
931+ get_random_bytes (& val , sizeof (val ));
932+
933+ /* Do a raw write */
934+ KUNIT_EXPECT_EQ (test , 0 , regmap_raw_write (map , 2 , val , sizeof (val )));
935+
936+ /* We should read back the new values, and defaults for the rest */
937+ for (i = 0 ; i < config .max_register + 1 ; i ++ ) {
938+ KUNIT_EXPECT_EQ (test , 0 , regmap_read (map , i , & rval ));
939+
940+ switch (i ) {
941+ case 2 :
942+ case 3 :
943+ if (config .val_format_endian == REGMAP_ENDIAN_BIG ) {
944+ KUNIT_EXPECT_EQ (test , rval ,
945+ be16_to_cpu (val [i % 2 ]));
946+ } else {
947+ KUNIT_EXPECT_EQ (test , rval ,
948+ le16_to_cpu (val [i % 2 ]));
949+ }
950+ break ;
951+ default :
952+ KUNIT_EXPECT_EQ (test , config .reg_defaults [i ].def , rval );
953+ break ;
954+ }
955+ }
956+
957+ /* The values should appear in the "hardware" */
958+ KUNIT_EXPECT_MEMEQ (test , & hw_buf [2 ], val , sizeof (val ));
959+
960+ regmap_exit (map );
961+ }
962+
963+ static void raw_sync (struct kunit * test )
964+ {
965+ struct raw_test_types * t = (struct raw_test_types * )test -> param_value ;
966+ struct regmap * map ;
967+ struct regmap_config config ;
968+ struct regmap_ram_data * data ;
969+ u16 val [2 ];
970+ u16 * hw_buf ;
971+ unsigned int rval ;
972+ int i ;
973+
974+ config = raw_regmap_config ;
975+
976+ map = gen_raw_regmap (& config , t , & data );
977+ KUNIT_ASSERT_FALSE (test , IS_ERR (map ));
978+ if (IS_ERR (map ))
979+ return ;
980+
981+ hw_buf = (u16 * )data -> vals ;
982+
983+ get_random_bytes (& val , sizeof (val ));
984+
985+ /* Do a regular write and a raw write in cache only mode */
986+ regcache_cache_only (map , true);
987+ KUNIT_EXPECT_EQ (test , 0 , regmap_raw_write (map , 2 , val , sizeof (val )));
988+ if (config .val_format_endian == REGMAP_ENDIAN_BIG )
989+ KUNIT_EXPECT_EQ (test , 0 , regmap_write (map , 6 ,
990+ be16_to_cpu (val [0 ])));
991+ else
992+ KUNIT_EXPECT_EQ (test , 0 , regmap_write (map , 6 ,
993+ le16_to_cpu (val [0 ])));
994+
995+ /* We should read back the new values, and defaults for the rest */
996+ for (i = 0 ; i < config .max_register + 1 ; i ++ ) {
997+ KUNIT_EXPECT_EQ (test , 0 , regmap_read (map , i , & rval ));
998+
999+ switch (i ) {
1000+ case 2 :
1001+ case 3 :
1002+ case 6 :
1003+ if (config .val_format_endian == REGMAP_ENDIAN_BIG ) {
1004+ KUNIT_EXPECT_EQ (test , rval ,
1005+ be16_to_cpu (val [i % 2 ]));
1006+ } else {
1007+ KUNIT_EXPECT_EQ (test , rval ,
1008+ le16_to_cpu (val [i % 2 ]));
1009+ }
1010+ break ;
1011+ default :
1012+ KUNIT_EXPECT_EQ (test , config .reg_defaults [i ].def , rval );
1013+ break ;
1014+ }
1015+ }
1016+
1017+ /* The values should not appear in the "hardware" */
1018+ KUNIT_EXPECT_MEMNEQ (test , & hw_buf [2 ], val , sizeof (val ));
1019+ KUNIT_EXPECT_MEMNEQ (test , & hw_buf [6 ], val , sizeof (u16 ));
1020+
1021+ for (i = 0 ; i < config .max_register + 1 ; i ++ )
1022+ data -> written [i ] = false;
1023+
1024+ /* Do the sync */
1025+ regcache_cache_only (map , false);
1026+ regcache_mark_dirty (map );
1027+ KUNIT_EXPECT_EQ (test , 0 , regcache_sync (map ));
1028+
1029+ /* The values should now appear in the "hardware" */
1030+ KUNIT_EXPECT_MEMEQ (test , & hw_buf [2 ], val , sizeof (val ));
1031+ KUNIT_EXPECT_MEMEQ (test , & hw_buf [6 ], val , sizeof (u16 ));
1032+
1033+ regmap_exit (map );
1034+ }
1035+
7151036static struct kunit_case regmap_test_cases [] = {
7161037 KUNIT_CASE_PARAM (basic_read_write , regcache_types_gen_params ),
7171038 KUNIT_CASE_PARAM (bulk_write , regcache_types_gen_params ),
@@ -727,6 +1048,12 @@ static struct kunit_case regmap_test_cases[] = {
7271048 KUNIT_CASE_PARAM (cache_sync_defaults , real_cache_types_gen_params ),
7281049 KUNIT_CASE_PARAM (cache_sync_patch , real_cache_types_gen_params ),
7291050 KUNIT_CASE_PARAM (cache_drop , sparse_cache_types_gen_params ),
1051+
1052+ KUNIT_CASE_PARAM (raw_read_defaults_single , raw_test_types_gen_params ),
1053+ KUNIT_CASE_PARAM (raw_read_defaults , raw_test_types_gen_params ),
1054+ KUNIT_CASE_PARAM (raw_write_read_single , raw_test_types_gen_params ),
1055+ KUNIT_CASE_PARAM (raw_write , raw_test_types_gen_params ),
1056+ KUNIT_CASE_PARAM (raw_sync , raw_test_cache_types_gen_params ),
7301057 {}
7311058};
7321059
0 commit comments