coresight: Add helper for atomically taking the device
authorJames Clark <james.clark@arm.com>
Mon, 29 Jan 2024 15:40:41 +0000 (15:40 +0000)
committerSuzuki K Poulose <suzuki.poulose@arm.com>
Mon, 12 Feb 2024 10:21:38 +0000 (10:21 +0000)
Now that mode is in struct coresight_device, this pattern can be wrapped
in a helper.

Signed-off-by: James Clark <james.clark@arm.com>
Link: https://lore.kernel.org/r/20240129154050.569566-11-james.clark@arm.com
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
drivers/hwtracing/coresight/coresight-etm3x-core.c
drivers/hwtracing/coresight/coresight-etm4x-core.c
drivers/hwtracing/coresight/coresight-stm.c
include/linux/coresight.h

index de53c3e8db2915606909f896af3384db755e36a0..c301f6a5f06585a04758273e433cb54b173d9c06 100644 (file)
@@ -556,14 +556,12 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event,
                      enum cs_mode mode)
 {
        int ret;
-       u32 val;
        struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-       val = local_cmpxchg(&drvdata->csdev->mode, CS_MODE_DISABLED, mode);
-
-       /* Someone is already using the tracer */
-       if (val)
+       if (!coresight_take_mode(csdev, mode)) {
+               /* Someone is already using the tracer */
                return -EBUSY;
+       }
 
        switch (mode) {
        case CS_MODE_SYSFS:
index 1c64b54459d7e2f5d8adce930a4e67e7cced2959..572ac4a5e4ff980d0d41149bb20f2e66ffeab168 100644 (file)
@@ -840,13 +840,11 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event,
                       enum cs_mode mode)
 {
        int ret;
-       u32 val;
 
-       val = local_cmpxchg(&csdev->mode, CS_MODE_DISABLED, mode);
-
-       /* Someone is already using the tracer */
-       if (val)
+       if (!coresight_take_mode(csdev, mode)) {
+               /* Someone is already using the tracer */
                return -EBUSY;
+       }
 
        switch (mode) {
        case CS_MODE_SYSFS:
index b2ccbe989ff81e7c3dcb0fb8c66e83e95b2ea801..ff578762f6bf3e4e64ad348d00840cee3378125c 100644 (file)
@@ -193,17 +193,15 @@ static void stm_enable_hw(struct stm_drvdata *drvdata)
 static int stm_enable(struct coresight_device *csdev, struct perf_event *event,
                      enum cs_mode mode)
 {
-       u32 val;
        struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
        if (mode != CS_MODE_SYSFS)
                return -EINVAL;
 
-       val = local_cmpxchg(&csdev->mode, CS_MODE_DISABLED, mode);
-
-       /* Someone is already using the tracer */
-       if (val)
+       if (!coresight_take_mode(csdev, mode)) {
+               /* Someone is already using the tracer */
                return -EBUSY;
+       }
 
        pm_runtime_get_sync(csdev->dev.parent);
 
index ecf4b8aecca8a375e78e49dad7c3f66a72ededa0..414bcbbdaf62e27f7717f89aa4ed46e64d0d0c05 100644 (file)
@@ -580,6 +580,17 @@ static inline bool coresight_is_percpu_sink(struct coresight_device *csdev)
               (csdev->subtype.sink_subtype == CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM);
 }
 
+/*
+ * Atomically try to take the device and set a new mode. Returns true on
+ * success, false if the device is already taken by someone else.
+ */
+static inline bool coresight_take_mode(struct coresight_device *csdev,
+                                      enum cs_mode new_mode)
+{
+       return local_cmpxchg(&csdev->mode, CS_MODE_DISABLED, new_mode) ==
+              CS_MODE_DISABLED;
+}
+
 extern struct coresight_device *
 coresight_register(struct coresight_desc *desc);
 extern void coresight_unregister(struct coresight_device *csdev);