@@ -21,13 +21,35 @@ static int calculate_array_location(struct tgu_drvdata *drvdata,
2121 int step_index , int operation_index ,
2222 int reg_index )
2323{
24- int ret ;
24+ int ret = - EINVAL ;
25+
26+ switch (operation_index ) {
27+ case TGU_PRIORITY0 :
28+ case TGU_PRIORITY1 :
29+ case TGU_PRIORITY2 :
30+ case TGU_PRIORITY3 :
31+ ret = operation_index * (drvdata -> max_step ) *
32+ (drvdata -> max_reg ) +
33+ step_index * (drvdata -> max_reg ) + reg_index ;
34+ break ;
35+ case TGU_CONDITION_DECODE :
36+ ret = step_index * (drvdata -> max_condition_decode ) +
37+ reg_index ;
38+ break ;
39+ default :
40+ break ;
41+ }
42+ return ret ;
43+ }
2544
26- ret = operation_index * (drvdata -> max_step ) *
27- (drvdata -> max_reg ) +
28- step_index * (drvdata -> max_reg ) + reg_index ;
45+ static int check_array_location (struct tgu_drvdata * drvdata , int step ,
46+ int ops , int reg )
47+ {
48+ int result = calculate_array_location (drvdata , step , ops , reg );
2949
30- return ret ;
50+ if (result == - EINVAL )
51+ dev_err (& drvdata -> csdev -> dev , "%s - Fail\n" , __func__ );
52+ return result ;
3153}
3254
3355static ssize_t tgu_dataset_show (struct device * dev ,
@@ -36,13 +58,33 @@ static ssize_t tgu_dataset_show(struct device *dev,
3658 struct tgu_drvdata * drvdata = dev_get_drvdata (dev -> parent );
3759 struct tgu_attribute * tgu_attr =
3860 container_of (attr , struct tgu_attribute , attr );
61+ int ret = 0 ;
62+
63+ ret = check_array_location (drvdata , tgu_attr -> step_index ,
64+ tgu_attr -> operation_index , tgu_attr -> reg_num );
65+ if (ret == - EINVAL )
66+ return ret ;
3967
40- return sysfs_emit (buf , "0x%x\n" ,
41- drvdata -> value_table -> priority [
42- calculate_array_location (
43- drvdata , tgu_attr -> step_index ,
44- tgu_attr -> operation_index ,
45- tgu_attr -> reg_num )]);
68+ switch (tgu_attr -> operation_index ) {
69+ case TGU_PRIORITY0 :
70+ case TGU_PRIORITY1 :
71+ case TGU_PRIORITY2 :
72+ case TGU_PRIORITY3 :
73+ return sysfs_emit (buf , "0x%x\n" ,
74+ drvdata -> value_table -> priority [calculate_array_location (
75+ drvdata , tgu_attr -> step_index ,
76+ tgu_attr -> operation_index ,
77+ tgu_attr -> reg_num )]);
78+ case TGU_CONDITION_DECODE :
79+ return sysfs_emit (buf , "0x%x\n" ,
80+ drvdata -> value_table -> condition_decode [calculate_array_location (
81+ drvdata , tgu_attr -> step_index ,
82+ tgu_attr -> operation_index ,
83+ tgu_attr -> reg_num )]);
84+ default :
85+ break ;
86+ }
87+ return - EINVAL ;
4688}
4789
4890static ssize_t tgu_dataset_store (struct device * dev ,
@@ -51,20 +93,44 @@ static ssize_t tgu_dataset_store(struct device *dev,
5193 size_t size )
5294{
5395 unsigned long val ;
96+ int ret = - EINVAL ;
5497
5598 struct tgu_drvdata * tgu_drvdata = dev_get_drvdata (dev -> parent );
5699 struct tgu_attribute * tgu_attr =
57100 container_of (attr , struct tgu_attribute , attr );
58101
59102 if (kstrtoul (buf , 0 , & val ))
60- return - EINVAL ;
103+ return ret ;
61104
62- guard (spinlock )(& tgu_drvdata -> spinlock );
63- tgu_drvdata -> value_table -> priority [calculate_array_location (
64- tgu_drvdata , tgu_attr -> step_index , tgu_attr -> operation_index ,
65- tgu_attr -> reg_num )] = val ;
105+ ret = check_array_location (tgu_drvdata , tgu_attr -> step_index ,
106+ tgu_attr -> operation_index , tgu_attr -> reg_num );
66107
67- return size ;
108+ if (ret == - EINVAL )
109+ return ret ;
110+
111+ guard (spinlock )(& tgu_drvdata -> spinlock );
112+ switch (tgu_attr -> operation_index ) {
113+ case TGU_PRIORITY0 :
114+ case TGU_PRIORITY1 :
115+ case TGU_PRIORITY2 :
116+ case TGU_PRIORITY3 :
117+ tgu_drvdata -> value_table -> priority [calculate_array_location (
118+ tgu_drvdata , tgu_attr -> step_index ,
119+ tgu_attr -> operation_index ,
120+ tgu_attr -> reg_num )] = val ;
121+ ret = size ;
122+ break ;
123+ case TGU_CONDITION_DECODE :
124+ tgu_drvdata -> value_table -> condition_decode [calculate_array_location (
125+ tgu_drvdata , tgu_attr -> step_index ,
126+ tgu_attr -> operation_index ,
127+ tgu_attr -> reg_num )] = val ;
128+ ret = size ;
129+ break ;
130+ default :
131+ break ;
132+ }
133+ return ret ;
68134}
69135
70136static umode_t tgu_node_visible (struct kobject * kobject ,
@@ -81,34 +147,70 @@ static umode_t tgu_node_visible(struct kobject *kobject,
81147 container_of (dev_attr , struct tgu_attribute , attr );
82148
83149 if (tgu_attr -> step_index < drvdata -> max_step ) {
84- ret = (tgu_attr -> reg_num < drvdata -> max_reg ) ?
85- attr -> mode :
86- 0 ;
150+ switch (tgu_attr -> operation_index ) {
151+ case TGU_PRIORITY0 :
152+ case TGU_PRIORITY1 :
153+ case TGU_PRIORITY2 :
154+ case TGU_PRIORITY3 :
155+ ret = (tgu_attr -> reg_num < drvdata -> max_reg ) ?
156+ attr -> mode :
157+ 0 ;
158+ break ;
159+ case TGU_CONDITION_DECODE :
160+ ret = (tgu_attr -> reg_num <
161+ drvdata -> max_condition_decode ) ?
162+ attr -> mode :
163+ 0 ;
164+ break ;
165+ default :
166+ break ;
167+ }
87168 }
88169 return ret ;
89170}
90171
91- static void tgu_write_all_hw_regs (struct tgu_drvdata * drvdata )
172+ static ssize_t tgu_write_all_hw_regs (struct tgu_drvdata * drvdata )
92173{
93- int i , j , k ;
174+ int i , j , k , ret ;
94175
95176 CS_UNLOCK (drvdata -> base );
96177
97178 for (i = 0 ; i < drvdata -> max_step ; i ++ ) {
98179 for (j = 0 ; j < MAX_PRIORITY ; j ++ ) {
99180 for (k = 0 ; k < drvdata -> max_reg ; k ++ ) {
181+
182+ ret = check_array_location (drvdata , i , j , k );
183+ if (ret == - EINVAL )
184+ goto exit ;
185+
100186 tgu_writel (drvdata ,
101187 drvdata -> value_table -> priority
102188 [calculate_array_location (
103- drvdata , i , j , k )],
189+ drvdata , i , j , k )],
104190 PRIORITY_REG_STEP (i , j , k ));
105191 }
106192 }
107193 }
108194
195+ for (i = 0 ; i < drvdata -> max_step ; i ++ ) {
196+ for (j = 0 ; j < drvdata -> max_condition_decode ; j ++ ) {
197+ ret = check_array_location (drvdata , i , TGU_CONDITION_DECODE , j );
198+ if (ret == - EINVAL )
199+ goto exit ;
200+
201+ tgu_writel (drvdata ,
202+ drvdata -> value_table -> condition_decode
203+ [calculate_array_location (
204+ drvdata , i ,
205+ TGU_CONDITION_DECODE , j )],
206+ CONDITION_DECODE_STEP (i , j ));
207+ }
208+ }
109209 /* Enable TGU to program the triggers */
110210 tgu_writel (drvdata , 1 , TGU_CONTROL );
211+ exit :
111212 CS_LOCK (drvdata -> base );
213+ return ret >= 0 ? 0 : ret ;
112214}
113215
114216static void tgu_set_reg_number (struct tgu_drvdata * drvdata )
@@ -139,9 +241,21 @@ static void tgu_set_steps(struct tgu_drvdata *drvdata)
139241 drvdata -> max_step = num_steps ;
140242}
141243
244+ static void tgu_set_conditions (struct tgu_drvdata * drvdata )
245+ {
246+ int num_conditions ;
247+ u32 devid ;
248+
249+ devid = readl_relaxed (drvdata -> base + CORESIGHT_DEVID );
250+
251+ num_conditions = TGU_DEVID_CONDITIONS (devid );
252+ drvdata -> max_condition_decode = num_conditions ;
253+ }
254+
142255static int tgu_enable (struct coresight_device * csdev , enum cs_mode mode ,
143256 void * data )
144257{
258+ int ret = 0 ;
145259 struct tgu_drvdata * drvdata = dev_get_drvdata (csdev -> dev .parent );
146260
147261 spin_lock (& drvdata -> spinlock );
@@ -150,11 +264,15 @@ static int tgu_enable(struct coresight_device *csdev, enum cs_mode mode,
150264 spin_unlock (& drvdata -> spinlock );
151265 return - EBUSY ;
152266 }
153- tgu_write_all_hw_regs (drvdata );
267+ ret = tgu_write_all_hw_regs (drvdata );
268+
269+ if (ret == - EINVAL )
270+ goto exit ;
154271 drvdata -> enable = true;
155272
273+ exit :
156274 spin_unlock (& drvdata -> spinlock );
157- return 0 ;
275+ return ret ;
158276}
159277
160278static int tgu_disable (struct coresight_device * csdev , void * data )
@@ -271,6 +389,14 @@ static const struct attribute_group *tgu_attr_groups[] = {
271389 PRIORITY_ATTRIBUTE_GROUP_INIT (7 , 1 ),
272390 PRIORITY_ATTRIBUTE_GROUP_INIT (7 , 2 ),
273391 PRIORITY_ATTRIBUTE_GROUP_INIT (7 , 3 ),
392+ CONDITION_DECODE_ATTRIBUTE_GROUP_INIT (0 ),
393+ CONDITION_DECODE_ATTRIBUTE_GROUP_INIT (1 ),
394+ CONDITION_DECODE_ATTRIBUTE_GROUP_INIT (2 ),
395+ CONDITION_DECODE_ATTRIBUTE_GROUP_INIT (3 ),
396+ CONDITION_DECODE_ATTRIBUTE_GROUP_INIT (4 ),
397+ CONDITION_DECODE_ATTRIBUTE_GROUP_INIT (5 ),
398+ CONDITION_DECODE_ATTRIBUTE_GROUP_INIT (6 ),
399+ CONDITION_DECODE_ATTRIBUTE_GROUP_INIT (7 ),
274400 NULL ,
275401};
276402
@@ -307,6 +433,7 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id)
307433
308434 tgu_set_reg_number (drvdata );
309435 tgu_set_steps (drvdata );
436+ tgu_set_conditions (drvdata );
310437
311438 drvdata -> value_table =
312439 devm_kzalloc (dev , sizeof (* drvdata -> value_table ), GFP_KERNEL );
@@ -322,6 +449,15 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id)
322449 if (!drvdata -> value_table -> priority )
323450 return - ENOMEM ;
324451
452+ drvdata -> value_table -> condition_decode = devm_kzalloc (
453+ dev ,
454+ drvdata -> max_condition_decode * drvdata -> max_step *
455+ sizeof (* (drvdata -> value_table -> condition_decode )),
456+ GFP_KERNEL );
457+
458+ if (!drvdata -> value_table -> condition_decode )
459+ return - ENOMEM ;
460+
325461 drvdata -> enable = false;
326462 desc .type = CORESIGHT_DEV_TYPE_HELPER ;
327463 desc .pdata = adev -> dev .platform_data ;
0 commit comments