aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwtracing
diff options
context:
space:
mode:
authorSuzuki K Poulose <suzuki.poulose@arm.com>2018-09-20 15:18:04 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-25 14:09:18 -0400
commit6276f9cba50f77c5b51b581c11b74a51a3f9e040 (patch)
tree3f9d35d248d81ab8b630a1595f9510cd967dd429 /drivers/hwtracing
parentb9866bb16882e89b57e2dc826114316357263fb7 (diff)
coresight: tmc-etr: Refactor for handling errors
Refactor the tmc-etr enable operation to make it easier to handle errors in enabling the hardware. We need to make sure that the buffer is compatible with the ETR. This patch re-arranges to make the error handling easier, by deferring the hardware enablement until all the errors are checked. This also avoids turning the CATU on/off during a sysfs read session. Cc: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hwtracing')
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-etr.c67
1 files changed, 43 insertions, 24 deletions
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 56fea4ff947e..c42693542ec8 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -918,21 +918,10 @@ static void tmc_sync_etr_buf(struct tmc_drvdata *drvdata)
918 tmc_etr_buf_insert_barrier_packet(etr_buf, etr_buf->offset); 918 tmc_etr_buf_insert_barrier_packet(etr_buf, etr_buf->offset);
919} 919}
920 920
921static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata, 921static void __tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
922 struct etr_buf *etr_buf)
923{ 922{
924 u32 axictl, sts; 923 u32 axictl, sts;
925 924 struct etr_buf *etr_buf = drvdata->etr_buf;
926 /* Callers should provide an appropriate buffer for use */
927 if (WARN_ON(!etr_buf || drvdata->etr_buf))
928 return;
929 drvdata->etr_buf = etr_buf;
930
931 /*
932 * If this ETR is connected to a CATU, enable it before we turn
933 * this on
934 */
935 tmc_etr_enable_catu(drvdata);
936 925
937 CS_UNLOCK(drvdata->base); 926 CS_UNLOCK(drvdata->base);
938 927
@@ -952,11 +941,8 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata,
952 axictl |= TMC_AXICTL_ARCACHE_OS; 941 axictl |= TMC_AXICTL_ARCACHE_OS;
953 } 942 }
954 943
955 if (etr_buf->mode == ETR_MODE_ETR_SG) { 944 if (etr_buf->mode == ETR_MODE_ETR_SG)
956 if (WARN_ON(!tmc_etr_has_cap(drvdata, TMC_ETR_SG)))
957 return;
958 axictl |= TMC_AXICTL_SCT_GAT_MODE; 945 axictl |= TMC_AXICTL_SCT_GAT_MODE;
959 }
960 946
961 writel_relaxed(axictl, drvdata->base + TMC_AXICTL); 947 writel_relaxed(axictl, drvdata->base + TMC_AXICTL);
962 tmc_write_dba(drvdata, etr_buf->hwaddr); 948 tmc_write_dba(drvdata, etr_buf->hwaddr);
@@ -982,6 +968,32 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata,
982 CS_LOCK(drvdata->base); 968 CS_LOCK(drvdata->base);
983} 969}
984 970
971static int tmc_etr_enable_hw(struct tmc_drvdata *drvdata,
972 struct etr_buf *etr_buf)
973{
974 /* Callers should provide an appropriate buffer for use */
975 if (WARN_ON(!etr_buf))
976 return -EINVAL;
977
978 if ((etr_buf->mode == ETR_MODE_ETR_SG) &&
979 WARN_ON(!tmc_etr_has_cap(drvdata, TMC_ETR_SG)))
980 return -EINVAL;
981
982 if (WARN_ON(drvdata->etr_buf))
983 return -EBUSY;
984
985 /* Set the buffer for the session */
986 drvdata->etr_buf = etr_buf;
987 /*
988 * If this ETR is connected to a CATU, enable it before we turn
989 * this on.
990 */
991 tmc_etr_enable_catu(drvdata);
992
993 __tmc_etr_enable_hw(drvdata);
994 return 0;
995}
996
985/* 997/*
986 * Return the available trace data in the buffer (starts at etr_buf->offset, 998 * Return the available trace data in the buffer (starts at etr_buf->offset,
987 * limited by etr_buf->len) from @pos, with a maximum limit of @len, 999 * limited by etr_buf->len) from @pos, with a maximum limit of @len,
@@ -1037,7 +1049,7 @@ static void tmc_etr_sync_sysfs_buf(struct tmc_drvdata *drvdata)
1037 } 1049 }
1038} 1050}
1039 1051
1040static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata) 1052static void __tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
1041{ 1053{
1042 CS_UNLOCK(drvdata->base); 1054 CS_UNLOCK(drvdata->base);
1043 1055
@@ -1053,6 +1065,11 @@ static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
1053 1065
1054 CS_LOCK(drvdata->base); 1066 CS_LOCK(drvdata->base);
1055 1067
1068}
1069
1070static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
1071{
1072 __tmc_etr_disable_hw(drvdata);
1056 /* Disable CATU device if this ETR is connected to one */ 1073 /* Disable CATU device if this ETR is connected to one */
1057 tmc_etr_disable_catu(drvdata); 1074 tmc_etr_disable_catu(drvdata);
1058 /* Reset the ETR buf used by hardware */ 1075 /* Reset the ETR buf used by hardware */
@@ -1111,8 +1128,9 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
1111 drvdata->sysfs_buf = new_buf; 1128 drvdata->sysfs_buf = new_buf;
1112 } 1129 }
1113 1130
1114 drvdata->mode = CS_MODE_SYSFS; 1131 ret = tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf);
1115 tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf); 1132 if (!ret)
1133 drvdata->mode = CS_MODE_SYSFS;
1116out: 1134out:
1117 spin_unlock_irqrestore(&drvdata->spinlock, flags); 1135 spin_unlock_irqrestore(&drvdata->spinlock, flags);
1118 1136
@@ -1342,8 +1360,9 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
1342 1360
1343 etr_perf->head = PERF_IDX2OFF(handle->head, etr_perf); 1361 etr_perf->head = PERF_IDX2OFF(handle->head, etr_perf);
1344 drvdata->perf_data = etr_perf; 1362 drvdata->perf_data = etr_perf;
1345 drvdata->mode = CS_MODE_PERF; 1363 rc = tmc_etr_enable_hw(drvdata, etr_perf->etr_buf);
1346 tmc_etr_enable_hw(drvdata, etr_perf->etr_buf); 1364 if (!rc)
1365 drvdata->mode = CS_MODE_PERF;
1347 1366
1348unlock_out: 1367unlock_out:
1349 spin_unlock_irqrestore(&drvdata->spinlock, flags); 1368 spin_unlock_irqrestore(&drvdata->spinlock, flags);
@@ -1425,7 +1444,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
1425 1444
1426 /* Disable the TMC if we are trying to read from a running session. */ 1445 /* Disable the TMC if we are trying to read from a running session. */
1427 if (drvdata->mode == CS_MODE_SYSFS) 1446 if (drvdata->mode == CS_MODE_SYSFS)
1428 tmc_etr_disable_hw(drvdata); 1447 __tmc_etr_disable_hw(drvdata);
1429 1448
1430 drvdata->reading = true; 1449 drvdata->reading = true;
1431out: 1450out:
@@ -1452,7 +1471,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
1452 * buffer. Since the tracer is still enabled drvdata::buf can't 1471 * buffer. Since the tracer is still enabled drvdata::buf can't
1453 * be NULL. 1472 * be NULL.
1454 */ 1473 */
1455 tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf); 1474 __tmc_etr_enable_hw(drvdata);
1456 } else { 1475 } else {
1457 /* 1476 /*
1458 * The ETR is not tracing and the buffer was just read. 1477 * The ETR is not tracing and the buffer was just read.