@@ -39,6 +39,12 @@ static int calculate_array_location(struct tgu_drvdata *drvdata,
3939 case TGU_CONDITION_SELECT :
4040 ret = step_index * (drvdata -> max_condition_select ) + reg_index ;
4141 break ;
42+ case TGU_COUNTER :
43+ ret = step_index * (drvdata -> max_counter ) + reg_index ;
44+ break ;
45+ case TGU_TIMER :
46+ ret = step_index * (drvdata -> max_timer ) + reg_index ;
47+ break ;
4248 default :
4349 break ;
4450 }
@@ -90,6 +96,16 @@ static ssize_t tgu_dataset_show(struct device *dev,
9096 drvdata , tgu_attr -> step_index ,
9197 tgu_attr -> operation_index ,
9298 tgu_attr -> reg_num )]);
99+ case TGU_TIMER :
100+ return sysfs_emit (buf , "0x%x\n" ,
101+ drvdata -> value_table -> timer [calculate_array_location (
102+ drvdata , tgu_attr -> step_index , tgu_attr -> operation_index ,
103+ tgu_attr -> reg_num )]);
104+ case TGU_COUNTER :
105+ return sysfs_emit (buf , "0x%x\n" ,
106+ drvdata -> value_table -> counter [calculate_array_location (
107+ drvdata , tgu_attr -> step_index , tgu_attr -> operation_index ,
108+ tgu_attr -> reg_num )]);
93109 default :
94110 break ;
95111 }
@@ -143,6 +159,18 @@ static ssize_t tgu_dataset_store(struct device *dev,
143159 tgu_attr -> reg_num )] = val ;
144160 ret = size ;
145161 break ;
162+ case TGU_TIMER :
163+ tgu_drvdata -> value_table -> timer [calculate_array_location (
164+ tgu_drvdata , tgu_attr -> step_index , tgu_attr -> operation_index ,
165+ tgu_attr -> reg_num )] = val ;
166+ ret = size ;
167+ break ;
168+ case TGU_COUNTER :
169+ tgu_drvdata -> value_table -> counter [calculate_array_location (
170+ tgu_drvdata , tgu_attr -> step_index , tgu_attr -> operation_index ,
171+ tgu_attr -> reg_num )] = val ;
172+ ret = size ;
173+ break ;
146174 default :
147175 break ;
148176 }
@@ -188,6 +216,24 @@ static umode_t tgu_node_visible(struct kobject *kobject,
188216 attr -> mode :
189217 0 ;
190218 break ;
219+ case TGU_COUNTER :
220+ if (drvdata -> max_counter == 0 )
221+ ret = SYSFS_GROUP_INVISIBLE ;
222+ else
223+ ret = (tgu_attr -> reg_num <
224+ drvdata -> max_counter ) ?
225+ attr -> mode :
226+ 0 ;
227+ break ;
228+ case TGU_TIMER :
229+ if (drvdata -> max_timer == 0 )
230+ ret = SYSFS_GROUP_INVISIBLE ;
231+ else
232+ ret = (tgu_attr -> reg_num <
233+ drvdata -> max_timer ) ?
234+ attr -> mode :
235+ 0 ;
236+ break ;
191237 default :
192238 break ;
193239 }
@@ -246,6 +292,34 @@ static ssize_t tgu_write_all_hw_regs(struct tgu_drvdata *drvdata)
246292 CONDITION_SELECT_STEP (i , j ));
247293 }
248294 }
295+
296+ for (i = 0 ; i < drvdata -> max_step ; i ++ ) {
297+ for (j = 0 ; j < drvdata -> max_timer ; j ++ ) {
298+ ret = check_array_location (drvdata , i , TGU_TIMER , j );
299+ if (ret == - EINVAL )
300+ goto exit ;
301+
302+ tgu_writel (drvdata ,
303+ drvdata -> value_table -> timer
304+ [calculate_array_location (drvdata , i ,
305+ TGU_TIMER , j )],
306+ TIMER_COMPARE_STEP (i , j ));
307+ }
308+ }
309+
310+ for (i = 0 ; i < drvdata -> max_step ; i ++ ) {
311+ for (j = 0 ; j < drvdata -> max_counter ; j ++ ) {
312+ ret = check_array_location (drvdata , i , TGU_COUNTER , j );
313+ if (ret == - EINVAL )
314+ goto exit ;
315+
316+ tgu_writel (drvdata ,
317+ drvdata -> value_table -> counter
318+ [calculate_array_location (drvdata , i ,
319+ TGU_COUNTER , j )],
320+ COUNTER_COMPARE_STEP (i , j ));
321+ }
322+ }
249323 /* Enable TGU to program the triggers */
250324 tgu_writel (drvdata , 1 , TGU_CONTROL );
251325exit :
@@ -294,6 +368,31 @@ static void tgu_set_conditions(struct tgu_drvdata *drvdata)
294368 drvdata -> max_condition_select = num_conditions + 1 ;
295369}
296370
371+ static void tgu_set_timer_counter (struct tgu_drvdata * drvdata )
372+ {
373+ int num_timers , num_counters ;
374+ u32 devid2 ;
375+
376+ devid2 = readl_relaxed (drvdata -> base + CORESIGHT_DEVID2 );
377+
378+ if (TGU_DEVID2_TIMER0 (devid2 ) && TGU_DEVID2_TIMER1 (devid2 ))
379+ num_timers = 2 ;
380+ else if (TGU_DEVID2_TIMER0 (devid2 ) || TGU_DEVID2_TIMER1 (devid2 ))
381+ num_timers = 1 ;
382+ else
383+ num_timers = 0 ;
384+
385+ if (TGU_DEVID2_COUNTER0 (devid2 ) && TGU_DEVID2_COUNTER1 (devid2 ))
386+ num_counters = 2 ;
387+ else if (TGU_DEVID2_COUNTER0 (devid2 ) || TGU_DEVID2_COUNTER1 (devid2 ))
388+ num_counters = 1 ;
389+ else
390+ num_counters = 0 ;
391+
392+ drvdata -> max_timer = num_timers ;
393+ drvdata -> max_counter = num_counters ;
394+ }
395+
297396static int tgu_enable (struct coresight_device * csdev , enum cs_mode mode ,
298397 void * data )
299398{
@@ -447,6 +546,22 @@ static const struct attribute_group *tgu_attr_groups[] = {
447546 CONDITION_SELECT_ATTRIBUTE_GROUP_INIT (5 ),
448547 CONDITION_SELECT_ATTRIBUTE_GROUP_INIT (6 ),
449548 CONDITION_SELECT_ATTRIBUTE_GROUP_INIT (7 ),
549+ TIMER_ATTRIBUTE_GROUP_INIT (0 ),
550+ TIMER_ATTRIBUTE_GROUP_INIT (1 ),
551+ TIMER_ATTRIBUTE_GROUP_INIT (2 ),
552+ TIMER_ATTRIBUTE_GROUP_INIT (3 ),
553+ TIMER_ATTRIBUTE_GROUP_INIT (4 ),
554+ TIMER_ATTRIBUTE_GROUP_INIT (5 ),
555+ TIMER_ATTRIBUTE_GROUP_INIT (6 ),
556+ TIMER_ATTRIBUTE_GROUP_INIT (7 ),
557+ COUNTER_ATTRIBUTE_GROUP_INIT (0 ),
558+ COUNTER_ATTRIBUTE_GROUP_INIT (1 ),
559+ COUNTER_ATTRIBUTE_GROUP_INIT (2 ),
560+ COUNTER_ATTRIBUTE_GROUP_INIT (3 ),
561+ COUNTER_ATTRIBUTE_GROUP_INIT (4 ),
562+ COUNTER_ATTRIBUTE_GROUP_INIT (5 ),
563+ COUNTER_ATTRIBUTE_GROUP_INIT (6 ),
564+ COUNTER_ATTRIBUTE_GROUP_INIT (7 ),
450565 NULL ,
451566};
452567
@@ -484,6 +599,7 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id)
484599 tgu_set_reg_number (drvdata );
485600 tgu_set_steps (drvdata );
486601 tgu_set_conditions (drvdata );
602+ tgu_set_timer_counter (drvdata );
487603
488604 drvdata -> value_table =
489605 devm_kzalloc (dev , sizeof (* drvdata -> value_table ), GFP_KERNEL );
@@ -517,6 +633,24 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id)
517633 if (!drvdata -> value_table -> condition_select )
518634 return - ENOMEM ;
519635
636+ drvdata -> value_table -> timer = devm_kzalloc (
637+ dev ,
638+ drvdata -> max_step * drvdata -> max_timer *
639+ sizeof (* (drvdata -> value_table -> timer )),
640+ GFP_KERNEL );
641+
642+ if (!drvdata -> value_table -> timer )
643+ return - ENOMEM ;
644+
645+ drvdata -> value_table -> counter = devm_kzalloc (
646+ dev ,
647+ drvdata -> max_step * drvdata -> max_counter *
648+ sizeof (* (drvdata -> value_table -> counter )),
649+ GFP_KERNEL );
650+
651+ if (!drvdata -> value_table -> counter )
652+ return - ENOMEM ;
653+
520654 drvdata -> enable = false;
521655 desc .type = CORESIGHT_DEV_TYPE_HELPER ;
522656 desc .pdata = adev -> dev .platform_data ;
0 commit comments