Commit 1d364034 authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Greg Kroah-Hartman

coresight: tmc-etb/etf: Prepare to handle errors enabling

Prepare to handle errors in enabling the hardware and
report it back to the core driver.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1c7995e1
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
static int tmc_set_etf_buffer(struct coresight_device *csdev, static int tmc_set_etf_buffer(struct coresight_device *csdev,
struct perf_output_handle *handle); struct perf_output_handle *handle);
static void tmc_etb_enable_hw(struct tmc_drvdata *drvdata) static void __tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
{ {
CS_UNLOCK(drvdata->base); CS_UNLOCK(drvdata->base);
...@@ -34,6 +34,12 @@ static void tmc_etb_enable_hw(struct tmc_drvdata *drvdata) ...@@ -34,6 +34,12 @@ static void tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
CS_LOCK(drvdata->base); CS_LOCK(drvdata->base);
} }
static int tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
{
__tmc_etb_enable_hw(drvdata);
return 0;
}
static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata) static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata)
{ {
char *bufp; char *bufp;
...@@ -73,7 +79,7 @@ static void tmc_etb_disable_hw(struct tmc_drvdata *drvdata) ...@@ -73,7 +79,7 @@ static void tmc_etb_disable_hw(struct tmc_drvdata *drvdata)
CS_LOCK(drvdata->base); CS_LOCK(drvdata->base);
} }
static void tmc_etf_enable_hw(struct tmc_drvdata *drvdata) static void __tmc_etf_enable_hw(struct tmc_drvdata *drvdata)
{ {
CS_UNLOCK(drvdata->base); CS_UNLOCK(drvdata->base);
...@@ -89,6 +95,12 @@ static void tmc_etf_enable_hw(struct tmc_drvdata *drvdata) ...@@ -89,6 +95,12 @@ static void tmc_etf_enable_hw(struct tmc_drvdata *drvdata)
CS_LOCK(drvdata->base); CS_LOCK(drvdata->base);
} }
static int tmc_etf_enable_hw(struct tmc_drvdata *drvdata)
{
__tmc_etf_enable_hw(drvdata);
return 0;
}
static void tmc_etf_disable_hw(struct tmc_drvdata *drvdata) static void tmc_etf_disable_hw(struct tmc_drvdata *drvdata)
{ {
CS_UNLOCK(drvdata->base); CS_UNLOCK(drvdata->base);
...@@ -171,8 +183,12 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) ...@@ -171,8 +183,12 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
drvdata->buf = buf; drvdata->buf = buf;
} }
drvdata->mode = CS_MODE_SYSFS; ret = tmc_etb_enable_hw(drvdata);
tmc_etb_enable_hw(drvdata); if (!ret)
drvdata->mode = CS_MODE_SYSFS;
else
/* Free up the buffer if we failed to enable */
used = false;
out: out:
spin_unlock_irqrestore(&drvdata->spinlock, flags); spin_unlock_irqrestore(&drvdata->spinlock, flags);
...@@ -191,27 +207,25 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data) ...@@ -191,27 +207,25 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
struct perf_output_handle *handle = data; struct perf_output_handle *handle = data;
spin_lock_irqsave(&drvdata->spinlock, flags); spin_lock_irqsave(&drvdata->spinlock, flags);
if (drvdata->reading) { do {
ret = -EINVAL;
goto out;
}
/*
* In Perf mode there can be only one writer per sink. There
* is also no need to continue if the ETB/ETR is already operated
* from sysFS.
*/
if (drvdata->mode != CS_MODE_DISABLED) {
ret = -EINVAL; ret = -EINVAL;
goto out; if (drvdata->reading)
} break;
/*
* In Perf mode there can be only one writer per sink. There
* is also no need to continue if the ETB/ETF is already
* operated from sysFS.
*/
if (drvdata->mode != CS_MODE_DISABLED)
break;
ret = tmc_set_etf_buffer(csdev, handle); ret = tmc_set_etf_buffer(csdev, handle);
if (!ret) { if (ret)
drvdata->mode = CS_MODE_PERF; break;
tmc_etb_enable_hw(drvdata); ret = tmc_etb_enable_hw(drvdata);
} if (!ret)
out: drvdata->mode = CS_MODE_PERF;
} while (0);
spin_unlock_irqrestore(&drvdata->spinlock, flags); spin_unlock_irqrestore(&drvdata->spinlock, flags);
return ret; return ret;
...@@ -268,6 +282,7 @@ static void tmc_disable_etf_sink(struct coresight_device *csdev) ...@@ -268,6 +282,7 @@ static void tmc_disable_etf_sink(struct coresight_device *csdev)
static int tmc_enable_etf_link(struct coresight_device *csdev, static int tmc_enable_etf_link(struct coresight_device *csdev,
int inport, int outport) int inport, int outport)
{ {
int ret;
unsigned long flags; unsigned long flags;
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
...@@ -277,12 +292,14 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, ...@@ -277,12 +292,14 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
return -EBUSY; return -EBUSY;
} }
tmc_etf_enable_hw(drvdata); ret = tmc_etf_enable_hw(drvdata);
drvdata->mode = CS_MODE_SYSFS; if (!ret)
drvdata->mode = CS_MODE_SYSFS;
spin_unlock_irqrestore(&drvdata->spinlock, flags); spin_unlock_irqrestore(&drvdata->spinlock, flags);
dev_dbg(drvdata->dev, "TMC-ETF enabled\n"); if (!ret)
return 0; dev_dbg(drvdata->dev, "TMC-ETF enabled\n");
return ret;
} }
static void tmc_disable_etf_link(struct coresight_device *csdev, static void tmc_disable_etf_link(struct coresight_device *csdev,
...@@ -576,7 +593,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) ...@@ -576,7 +593,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
* can't be NULL. * can't be NULL.
*/ */
memset(drvdata->buf, 0, drvdata->size); memset(drvdata->buf, 0, drvdata->size);
tmc_etb_enable_hw(drvdata); __tmc_etb_enable_hw(drvdata);
} else { } else {
/* /*
* The ETB/ETF is not tracing and the buffer was just read. * The ETB/ETF is not tracing and the buffer was just read.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment