@@ -629,6 +629,141 @@ int irq_timings_alloc(int irq)
629629}
630630
631631#ifdef CONFIG_TEST_IRQ_TIMINGS
632+ struct timings_intervals {
633+ u64 * intervals ;
634+ size_t count ;
635+ };
636+
637+ /*
638+ * Intervals are given in nanosecond base
639+ */
640+ static u64 intervals0 [] __initdata = {
641+ 10000 , 50000 , 200000 , 500000 ,
642+ 10000 , 50000 , 200000 , 500000 ,
643+ 10000 , 50000 , 200000 , 500000 ,
644+ 10000 , 50000 , 200000 , 500000 ,
645+ 10000 , 50000 , 200000 , 500000 ,
646+ 10000 , 50000 , 200000 , 500000 ,
647+ 10000 , 50000 , 200000 , 500000 ,
648+ 10000 , 50000 , 200000 , 500000 ,
649+ 10000 , 50000 , 200000 ,
650+ };
651+
652+ static u64 intervals1 [] __initdata = {
653+ 223947000 , 1240000 , 1384000 , 1386000 , 1386000 ,
654+ 217416000 , 1236000 , 1384000 , 1386000 , 1387000 ,
655+ 214719000 , 1241000 , 1386000 , 1387000 , 1384000 ,
656+ 213696000 , 1234000 , 1384000 , 1386000 , 1388000 ,
657+ 219904000 , 1240000 , 1385000 , 1389000 , 1385000 ,
658+ 212240000 , 1240000 , 1386000 , 1386000 , 1386000 ,
659+ 214415000 , 1236000 , 1384000 , 1386000 , 1387000 ,
660+ 214276000 , 1234000 ,
661+ };
662+
663+ static u64 intervals2 [] __initdata = {
664+ 4000 , 3000 , 5000 , 100000 ,
665+ 3000 , 3000 , 5000 , 117000 ,
666+ 4000 , 4000 , 5000 , 112000 ,
667+ 4000 , 3000 , 4000 , 110000 ,
668+ 3000 , 5000 , 3000 , 117000 ,
669+ 4000 , 4000 , 5000 , 112000 ,
670+ 4000 , 3000 , 4000 , 110000 ,
671+ 3000 , 4000 , 5000 , 112000 ,
672+ 4000 ,
673+ };
674+
675+ static u64 intervals3 [] __initdata = {
676+ 1385000 , 212240000 , 1240000 ,
677+ 1386000 , 214415000 , 1236000 ,
678+ 1384000 , 214276000 , 1234000 ,
679+ 1386000 , 214415000 , 1236000 ,
680+ 1385000 , 212240000 , 1240000 ,
681+ 1386000 , 214415000 , 1236000 ,
682+ 1384000 , 214276000 , 1234000 ,
683+ 1386000 , 214415000 , 1236000 ,
684+ 1385000 , 212240000 , 1240000 ,
685+ };
686+
687+ static u64 intervals4 [] __initdata = {
688+ 10000 , 50000 , 10000 , 50000 ,
689+ 10000 , 50000 , 10000 , 50000 ,
690+ 10000 , 50000 , 10000 , 50000 ,
691+ 10000 , 50000 , 10000 , 50000 ,
692+ 10000 , 50000 , 10000 , 50000 ,
693+ 10000 , 50000 , 10000 , 50000 ,
694+ 10000 , 50000 , 10000 , 50000 ,
695+ 10000 , 50000 , 10000 , 50000 ,
696+ 10000 ,
697+ };
698+
699+ static struct timings_intervals tis [] __initdata = {
700+ { intervals0 , ARRAY_SIZE (intervals0 ) },
701+ { intervals1 , ARRAY_SIZE (intervals1 ) },
702+ { intervals2 , ARRAY_SIZE (intervals2 ) },
703+ { intervals3 , ARRAY_SIZE (intervals3 ) },
704+ { intervals4 , ARRAY_SIZE (intervals4 ) },
705+ };
706+
707+ static int __init irq_timings_test_irqs (struct timings_intervals * ti )
708+ {
709+ struct irqt_stat __percpu * s ;
710+ struct irqt_stat * irqs ;
711+ int i , index , ret , irq = 0xACE5 ;
712+
713+ ret = irq_timings_alloc (irq );
714+ if (ret ) {
715+ pr_err ("Failed to allocate irq timings\n" );
716+ return ret ;
717+ }
718+
719+ s = idr_find (& irqt_stats , irq );
720+ if (!s ) {
721+ ret = - EIDRM ;
722+ goto out ;
723+ }
724+
725+ irqs = this_cpu_ptr (s );
726+
727+ for (i = 0 ; i < ti -> count ; i ++ ) {
728+
729+ index = irq_timings_interval_index (ti -> intervals [i ]);
730+ pr_debug ("%d: interval=%llu ema_index=%d\n" ,
731+ i , ti -> intervals [i ], index );
732+
733+ __irq_timings_store (irq , irqs , ti -> intervals [i ]);
734+ if (irqs -> circ_timings [i & IRQ_TIMINGS_MASK ] != index ) {
735+ pr_err ("Failed to store in the circular buffer\n" );
736+ goto out ;
737+ }
738+ }
739+
740+ if (irqs -> count != ti -> count ) {
741+ pr_err ("Count differs\n" );
742+ goto out ;
743+ }
744+
745+ ret = 0 ;
746+ out :
747+ irq_timings_free (irq );
748+
749+ return ret ;
750+ }
751+
752+ static int __init irq_timings_irqs_selftest (void )
753+ {
754+ int i , ret ;
755+
756+ for (i = 0 ; i < ARRAY_SIZE (tis ); i ++ ) {
757+ pr_info ("---> Injecting intervals number #%d (count=%zd)\n" ,
758+ i , tis [i ].count );
759+ ret = irq_timings_test_irqs (& tis [i ]);
760+ if (ret )
761+ break ;
762+ }
763+
764+ return ret ;
765+ }
766+
632767static int __init irq_timings_test_irqts (struct irq_timings * irqts ,
633768 unsigned count )
634769{
@@ -736,7 +871,11 @@ static int __init irq_timings_selftest(void)
736871 }
737872
738873 ret = irq_timings_irqts_selftest ();
874+ if (ret )
875+ goto out ;
739876
877+ ret = irq_timings_irqs_selftest ();
878+ out :
740879 pr_info ("---------- selftest end with %s -----------\n" ,
741880 ret ? "failure" : "success" );
742881
0 commit comments