33 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
44 */
55
6+ #include <linux/build_bug.h>
67#include <linux/kernel.h>
78#include <linux/init.h>
89#include <linux/types.h>
@@ -236,60 +237,44 @@ void coresight_disclaim_device(struct coresight_device *csdev)
236237}
237238EXPORT_SYMBOL_GPL (coresight_disclaim_device );
238239
239- /* enable or disable an associated CTI device of the supplied CS device */
240- static int
241- coresight_control_assoc_ectdev (struct coresight_device * csdev , bool enable )
240+ /*
241+ * Add a helper as an output device. This function takes the @coresight_mutex
242+ * because it's assumed that it's called from the helper device, outside of the
243+ * core code where the mutex would already be held. Don't add new calls to this
244+ * from inside the core code, instead try to add the new helper to the DT and
245+ * ACPI where it will be picked up and linked automatically.
246+ */
247+ void coresight_add_helper (struct coresight_device * csdev ,
248+ struct coresight_device * helper )
242249{
243- int ect_ret = 0 ;
244- struct coresight_device * ect_csdev = csdev -> ect_dev ;
245- struct module * mod ;
250+ int i ;
251+ struct coresight_connection conn = {} ;
252+ struct coresight_connection * new_conn ;
246253
247- if (!ect_csdev )
248- return 0 ;
249- if ((!ect_ops (ect_csdev )-> enable ) || (!ect_ops (ect_csdev )-> disable ))
250- return 0 ;
254+ mutex_lock (& coresight_mutex );
255+ conn .dest_fwnode = fwnode_handle_get (dev_fwnode (& helper -> dev ));
256+ conn .dest_dev = helper ;
257+ conn .dest_port = conn .src_port = -1 ;
258+ conn .src_dev = csdev ;
251259
252- mod = ect_csdev -> dev .parent -> driver -> owner ;
253- if (enable ) {
254- if (try_module_get (mod )) {
255- ect_ret = ect_ops (ect_csdev )-> enable (ect_csdev );
256- if (ect_ret ) {
257- module_put (mod );
258- } else {
259- get_device (ect_csdev -> dev .parent );
260- csdev -> ect_enabled = true;
261- }
262- } else
263- ect_ret = - ENODEV ;
264- } else {
265- if (csdev -> ect_enabled ) {
266- ect_ret = ect_ops (ect_csdev )-> disable (ect_csdev );
267- put_device (ect_csdev -> dev .parent );
268- module_put (mod );
269- csdev -> ect_enabled = false;
270- }
271- }
260+ /*
261+ * Check for duplicates because this is called every time a helper
262+ * device is re-loaded. Existing connections will get re-linked
263+ * automatically.
264+ */
265+ for (i = 0 ; i < csdev -> pdata -> nr_outconns ; ++ i )
266+ if (csdev -> pdata -> out_conns [i ]-> dest_fwnode == conn .dest_fwnode )
267+ goto unlock ;
272268
273- /* output warning if ECT enable is preventing trace operation */
274- if (ect_ret )
275- dev_info (& csdev -> dev , "Associated ECT device (%s) %s failed\n" ,
276- dev_name (& ect_csdev -> dev ),
277- enable ? "enable" : "disable" );
278- return ect_ret ;
279- }
269+ new_conn = coresight_add_out_conn (csdev -> dev .parent , csdev -> pdata ,
270+ & conn );
271+ if (!IS_ERR (new_conn ))
272+ coresight_add_in_conn (new_conn );
280273
281- /*
282- * Set the associated ect / cti device while holding the coresight_mutex
283- * to avoid a race with coresight_enable that may try to use this value.
284- */
285- void coresight_set_assoc_ectdev_mutex (struct coresight_device * csdev ,
286- struct coresight_device * ect_csdev )
287- {
288- mutex_lock (& coresight_mutex );
289- csdev -> ect_dev = ect_csdev ;
274+ unlock :
290275 mutex_unlock (& coresight_mutex );
291276}
292- EXPORT_SYMBOL_GPL (coresight_set_assoc_ectdev_mutex );
277+ EXPORT_SYMBOL_GPL (coresight_add_helper );
293278
294279static int coresight_enable_sink (struct coresight_device * csdev ,
295280 enum cs_mode mode , void * data )
@@ -303,14 +288,10 @@ static int coresight_enable_sink(struct coresight_device *csdev,
303288 if (!sink_ops (csdev )-> enable )
304289 return - EINVAL ;
305290
306- ret = coresight_control_assoc_ectdev (csdev , true);
307- if (ret )
308- return ret ;
309291 ret = sink_ops (csdev )-> enable (csdev , mode , data );
310- if (ret ) {
311- coresight_control_assoc_ectdev (csdev , false);
292+ if (ret )
312293 return ret ;
313- }
294+
314295 csdev -> enable = true;
315296
316297 return 0 ;
@@ -326,7 +307,6 @@ static void coresight_disable_sink(struct coresight_device *csdev)
326307 ret = sink_ops (csdev )-> disable (csdev );
327308 if (ret )
328309 return ;
329- coresight_control_assoc_ectdev (csdev , false);
330310 csdev -> enable = false;
331311}
332312
@@ -351,17 +331,11 @@ static int coresight_enable_link(struct coresight_device *csdev,
351331 return PTR_ERR (outconn );
352332
353333 if (link_ops (csdev )-> enable ) {
354- ret = coresight_control_assoc_ectdev (csdev , true);
355- if (!ret ) {
356- ret = link_ops (csdev )-> enable (csdev , inconn , outconn );
357- if (ret )
358- coresight_control_assoc_ectdev (csdev , false);
359- }
334+ ret = link_ops (csdev )-> enable (csdev , inconn , outconn );
335+ if (!ret )
336+ csdev -> enable = true;
360337 }
361338
362- if (!ret )
363- csdev -> enable = true;
364-
365339 return ret ;
366340}
367341
@@ -382,7 +356,6 @@ static void coresight_disable_link(struct coresight_device *csdev,
382356
383357 if (link_ops (csdev )-> disable ) {
384358 link_ops (csdev )-> disable (csdev , inconn , outconn );
385- coresight_control_assoc_ectdev (csdev , false);
386359 }
387360
388361 if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG ) {
@@ -410,14 +383,9 @@ int coresight_enable_source(struct coresight_device *csdev, enum cs_mode mode,
410383
411384 if (!csdev -> enable ) {
412385 if (source_ops (csdev )-> enable ) {
413- ret = coresight_control_assoc_ectdev (csdev , true);
414- if (ret )
415- return ret ;
416386 ret = source_ops (csdev )-> enable (csdev , data , mode );
417- if (ret ) {
418- coresight_control_assoc_ectdev (csdev , false);
387+ if (ret )
419388 return ret ;
420- }
421389 }
422390 csdev -> enable = true;
423391 }
@@ -488,7 +456,6 @@ bool coresight_disable_source(struct coresight_device *csdev, void *data)
488456 if (atomic_dec_return (& csdev -> refcnt ) == 0 ) {
489457 if (source_ops (csdev )-> disable )
490458 source_ops (csdev )-> disable (csdev , data );
491- coresight_control_assoc_ectdev (csdev , false);
492459 coresight_disable_helpers (csdev );
493460 csdev -> enable = false;
494461 }
@@ -1360,11 +1327,10 @@ static struct device_type coresight_dev_type[] = {
13601327 },
13611328 {
13621329 .name = "helper" ,
1363- },
1364- {
1365- .name = "ect" ,
1366- },
1330+ }
13671331};
1332+ /* Ensure the enum matches the names and groups */
1333+ static_assert (ARRAY_SIZE (coresight_dev_type ) == CORESIGHT_DEV_TYPE_MAX );
13681334
13691335static void coresight_device_release (struct device * dev )
13701336{
0 commit comments