@@ -116,17 +116,13 @@ static struct attribute *device_str_attr_create(const char *name, const char *st
116
116
return & attr -> attr .attr ;
117
117
}
118
118
119
- struct imc_events * imc_parse_event (struct device_node * np , const char * scale ,
120
- const char * unit , const char * prefix , u32 base )
119
+ static int imc_parse_event (struct device_node * np , const char * scale ,
120
+ const char * unit , const char * prefix ,
121
+ u32 base , struct imc_events * event )
121
122
{
122
- struct imc_events * event ;
123
123
const char * s ;
124
124
u32 reg ;
125
125
126
- event = kzalloc (sizeof (struct imc_events ), GFP_KERNEL );
127
- if (!event )
128
- return NULL ;
129
-
130
126
if (of_property_read_u32 (np , "reg" , & reg ))
131
127
goto error ;
132
128
/* Add the base_reg value to the "reg" */
@@ -157,14 +153,32 @@ struct imc_events *imc_parse_event(struct device_node *np, const char *scale,
157
153
goto error ;
158
154
}
159
155
160
- return event ;
156
+ return 0 ;
161
157
error :
162
158
kfree (event -> unit );
163
159
kfree (event -> scale );
164
160
kfree (event -> name );
165
- kfree (event );
161
+ return - EINVAL ;
162
+ }
163
+
164
+ /*
165
+ * imc_free_events: Function to cleanup the events list, having
166
+ * "nr_entries".
167
+ */
168
+ static void imc_free_events (struct imc_events * events , int nr_entries )
169
+ {
170
+ int i ;
171
+
172
+ /* Nothing to clean, return */
173
+ if (!events )
174
+ return ;
175
+ for (i = 0 ; i < nr_entries ; i ++ ) {
176
+ kfree (events [i ].unit );
177
+ kfree (events [i ].scale );
178
+ kfree (events [i ].name );
179
+ }
166
180
167
- return NULL ;
181
+ kfree ( events ) ;
168
182
}
169
183
170
184
/*
@@ -176,9 +190,8 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
176
190
struct attribute_group * attr_group ;
177
191
struct attribute * * attrs , * dev_str ;
178
192
struct device_node * np , * pmu_events ;
179
- struct imc_events * ev ;
180
193
u32 handle , base_reg ;
181
- int i = 0 , j = 0 , ct ;
194
+ int i = 0 , j = 0 , ct , ret ;
182
195
const char * prefix , * g_scale , * g_unit ;
183
196
const char * ev_val_str , * ev_scale_str , * ev_unit_str ;
184
197
@@ -216,15 +229,17 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
216
229
ct = 0 ;
217
230
/* Parse the events and update the struct */
218
231
for_each_child_of_node (pmu_events , np ) {
219
- ev = imc_parse_event (np , g_scale , g_unit , prefix , base_reg );
220
- if (ev )
221
- pmu -> events [ ct ++ ] = ev ;
232
+ ret = imc_parse_event (np , g_scale , g_unit , prefix , base_reg , & pmu -> events [ ct ] );
233
+ if (! ret )
234
+ ct ++ ;
222
235
}
223
236
224
237
/* Allocate memory for attribute group */
225
238
attr_group = kzalloc (sizeof (* attr_group ), GFP_KERNEL );
226
- if (!attr_group )
239
+ if (!attr_group ) {
240
+ imc_free_events (pmu -> events , ct );
227
241
return - ENOMEM ;
242
+ }
228
243
229
244
/*
230
245
* Allocate memory for attributes.
@@ -237,31 +252,31 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
237
252
attrs = kcalloc (((ct * 3 ) + 1 ), sizeof (struct attribute * ), GFP_KERNEL );
238
253
if (!attrs ) {
239
254
kfree (attr_group );
240
- kfree (pmu -> events );
255
+ imc_free_events (pmu -> events , ct );
241
256
return - ENOMEM ;
242
257
}
243
258
244
259
attr_group -> name = "events" ;
245
260
attr_group -> attrs = attrs ;
246
261
do {
247
- ev_val_str = kasprintf (GFP_KERNEL , "event=0x%x" , pmu -> events [i ]-> value );
248
- dev_str = device_str_attr_create (pmu -> events [i ]-> name , ev_val_str );
262
+ ev_val_str = kasprintf (GFP_KERNEL , "event=0x%x" , pmu -> events [i ]. value );
263
+ dev_str = device_str_attr_create (pmu -> events [i ]. name , ev_val_str );
249
264
if (!dev_str )
250
265
continue ;
251
266
252
267
attrs [j ++ ] = dev_str ;
253
- if (pmu -> events [i ]-> scale ) {
254
- ev_scale_str = kasprintf (GFP_KERNEL , "%s.scale" ,pmu -> events [i ]-> name );
255
- dev_str = device_str_attr_create (ev_scale_str , pmu -> events [i ]-> scale );
268
+ if (pmu -> events [i ]. scale ) {
269
+ ev_scale_str = kasprintf (GFP_KERNEL , "%s.scale" , pmu -> events [i ]. name );
270
+ dev_str = device_str_attr_create (ev_scale_str , pmu -> events [i ]. scale );
256
271
if (!dev_str )
257
272
continue ;
258
273
259
274
attrs [j ++ ] = dev_str ;
260
275
}
261
276
262
- if (pmu -> events [i ]-> unit ) {
263
- ev_unit_str = kasprintf (GFP_KERNEL , "%s.unit" ,pmu -> events [i ]-> name );
264
- dev_str = device_str_attr_create (ev_unit_str , pmu -> events [i ]-> unit );
277
+ if (pmu -> events [i ]. unit ) {
278
+ ev_unit_str = kasprintf (GFP_KERNEL , "%s.unit" , pmu -> events [i ]. name );
279
+ dev_str = device_str_attr_create (ev_unit_str , pmu -> events [i ]. unit );
265
280
if (!dev_str )
266
281
continue ;
267
282
@@ -272,7 +287,6 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
272
287
/* Save the event attribute */
273
288
pmu -> attr_groups [IMC_EVENT_ATTR ] = attr_group ;
274
289
275
- kfree (pmu -> events );
276
290
return 0 ;
277
291
}
278
292
0 commit comments