Commit 4525412a authored by Mathieu Poirier's avatar Mathieu Poirier Committed by Greg Kroah-Hartman

coresight: tmc: making prepare/unprepare functions generic

Dealing with HW related matters in tmc_read_prepare/unprepare
becomes convoluted when many cases need to be handled distinctively.

As such moving processing related to HW setup to individual driver
files and keep the core driver generic.
Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6c6ed1e2
...@@ -71,7 +71,7 @@ static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata) ...@@ -71,7 +71,7 @@ static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata)
} }
} }
void tmc_etb_disable_hw(struct tmc_drvdata *drvdata) static void tmc_etb_disable_hw(struct tmc_drvdata *drvdata)
{ {
CS_UNLOCK(drvdata->base); CS_UNLOCK(drvdata->base);
...@@ -202,3 +202,63 @@ const struct coresight_ops tmc_etf_cs_ops = { ...@@ -202,3 +202,63 @@ const struct coresight_ops tmc_etf_cs_ops = {
.sink_ops = &tmc_etf_sink_ops, .sink_ops = &tmc_etf_sink_ops,
.link_ops = &tmc_etf_link_ops, .link_ops = &tmc_etf_link_ops,
}; };
int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
{
enum tmc_mode mode;
int ret = 0;
unsigned long flags;
/* config types are set a boot time and never change */
if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB &&
drvdata->config_type != TMC_CONFIG_TYPE_ETF))
return -EINVAL;
spin_lock_irqsave(&drvdata->spinlock, flags);
/* There is no point in reading a TMC in HW FIFO mode */
mode = readl_relaxed(drvdata->base + TMC_MODE);
if (mode != TMC_MODE_CIRCULAR_BUFFER) {
ret = -EINVAL;
goto out;
}
/* Disable the TMC if need be */
if (drvdata->enable)
tmc_etb_disable_hw(drvdata);
drvdata->reading = true;
out:
spin_unlock_irqrestore(&drvdata->spinlock, flags);
return ret;
}
int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
{
enum tmc_mode mode;
unsigned long flags;
/* config types are set a boot time and never change */
if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB &&
drvdata->config_type != TMC_CONFIG_TYPE_ETF))
return -EINVAL;
spin_lock_irqsave(&drvdata->spinlock, flags);
/* There is no point in reading a TMC in HW FIFO mode */
mode = readl_relaxed(drvdata->base + TMC_MODE);
if (mode != TMC_MODE_CIRCULAR_BUFFER) {
spin_unlock_irqrestore(&drvdata->spinlock, flags);
return -EINVAL;
}
/* Re-enable the TMC if need be */
if (drvdata->enable)
tmc_etb_enable_hw(drvdata);
drvdata->reading = false;
spin_unlock_irqrestore(&drvdata->spinlock, flags);
return 0;
}
...@@ -70,7 +70,7 @@ static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata) ...@@ -70,7 +70,7 @@ static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata)
drvdata->buf = drvdata->vaddr; drvdata->buf = drvdata->vaddr;
} }
void tmc_etr_disable_hw(struct tmc_drvdata *drvdata) static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
{ {
CS_UNLOCK(drvdata->base); CS_UNLOCK(drvdata->base);
...@@ -126,3 +126,43 @@ static const struct coresight_ops_sink tmc_etr_sink_ops = { ...@@ -126,3 +126,43 @@ static const struct coresight_ops_sink tmc_etr_sink_ops = {
const struct coresight_ops tmc_etr_cs_ops = { const struct coresight_ops tmc_etr_cs_ops = {
.sink_ops = &tmc_etr_sink_ops, .sink_ops = &tmc_etr_sink_ops,
}; };
int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
{
unsigned long flags;
/* config types are set a boot time and never change */
if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
return -EINVAL;
spin_lock_irqsave(&drvdata->spinlock, flags);
/* Disable the TMC if need be */
if (drvdata->enable)
tmc_etr_disable_hw(drvdata);
drvdata->reading = true;
spin_unlock_irqrestore(&drvdata->spinlock, flags);
return 0;
}
int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
{
unsigned long flags;
/* config types are set a boot time and never change */
if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
return -EINVAL;
spin_lock_irqsave(&drvdata->spinlock, flags);
/* RE-enable the TMC if need be */
if (drvdata->enable)
tmc_etr_enable_hw(drvdata);
drvdata->reading = false;
spin_unlock_irqrestore(&drvdata->spinlock, flags);
return 0;
}
...@@ -76,76 +76,43 @@ void tmc_disable_hw(struct tmc_drvdata *drvdata) ...@@ -76,76 +76,43 @@ void tmc_disable_hw(struct tmc_drvdata *drvdata)
static int tmc_read_prepare(struct tmc_drvdata *drvdata) static int tmc_read_prepare(struct tmc_drvdata *drvdata)
{ {
int ret = 0; int ret = 0;
unsigned long flags;
enum tmc_mode mode;
spin_lock_irqsave(&drvdata->spinlock, flags);
if (!drvdata->enable)
goto out;
switch (drvdata->config_type) { switch (drvdata->config_type) {
case TMC_CONFIG_TYPE_ETB: case TMC_CONFIG_TYPE_ETB:
tmc_etb_disable_hw(drvdata);
break;
case TMC_CONFIG_TYPE_ETF: case TMC_CONFIG_TYPE_ETF:
/* There is no point in reading a TMC in HW FIFO mode */ ret = tmc_read_prepare_etb(drvdata);
mode = readl_relaxed(drvdata->base + TMC_MODE);
if (mode != TMC_MODE_CIRCULAR_BUFFER) {
ret = -EINVAL;
goto err;
}
tmc_etb_disable_hw(drvdata);
break; break;
case TMC_CONFIG_TYPE_ETR: case TMC_CONFIG_TYPE_ETR:
tmc_etr_disable_hw(drvdata); ret = tmc_read_prepare_etr(drvdata);
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
goto err;
} }
out: if (!ret)
drvdata->reading = true; dev_info(drvdata->dev, "TMC read start\n");
dev_info(drvdata->dev, "TMC read start\n");
err:
spin_unlock_irqrestore(&drvdata->spinlock, flags);
return ret; return ret;
} }
static void tmc_read_unprepare(struct tmc_drvdata *drvdata) static void tmc_read_unprepare(struct tmc_drvdata *drvdata)
{ {
unsigned long flags; int ret = 0;
enum tmc_mode mode;
spin_lock_irqsave(&drvdata->spinlock, flags);
if (!drvdata->enable)
goto out;
switch (drvdata->config_type) { switch (drvdata->config_type) {
case TMC_CONFIG_TYPE_ETB: case TMC_CONFIG_TYPE_ETB:
tmc_etb_enable_hw(drvdata);
break;
case TMC_CONFIG_TYPE_ETF: case TMC_CONFIG_TYPE_ETF:
/* Make sure we don't re-enable a TMC in HW FIFO mode */ ret = tmc_read_unprepare_etb(drvdata);
mode = readl_relaxed(drvdata->base + TMC_MODE);
if (mode != TMC_MODE_CIRCULAR_BUFFER)
goto err;
tmc_etb_enable_hw(drvdata);
break; break;
case TMC_CONFIG_TYPE_ETR: case TMC_CONFIG_TYPE_ETR:
tmc_etr_disable_hw(drvdata); ret = tmc_read_unprepare_etr(drvdata);
break; break;
default: default:
goto err; ret = -EINVAL;
} }
out: if (!ret)
drvdata->reading = false; dev_info(drvdata->dev, "TMC read end\n");
dev_info(drvdata->dev, "TMC read end\n");
err:
spin_unlock_irqrestore(&drvdata->spinlock, flags);
} }
static int tmc_open(struct inode *inode, struct file *file) static int tmc_open(struct inode *inode, struct file *file)
......
...@@ -127,13 +127,13 @@ void tmc_enable_hw(struct tmc_drvdata *drvdata); ...@@ -127,13 +127,13 @@ void tmc_enable_hw(struct tmc_drvdata *drvdata);
void tmc_disable_hw(struct tmc_drvdata *drvdata); void tmc_disable_hw(struct tmc_drvdata *drvdata);
/* ETB/ETF functions */ /* ETB/ETF functions */
void tmc_etb_enable_hw(struct tmc_drvdata *drvdata); int tmc_read_prepare_etb(struct tmc_drvdata *drvdata);
void tmc_etb_disable_hw(struct tmc_drvdata *drvdata); int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata);
extern const struct coresight_ops tmc_etb_cs_ops; extern const struct coresight_ops tmc_etb_cs_ops;
extern const struct coresight_ops tmc_etf_cs_ops; extern const struct coresight_ops tmc_etf_cs_ops;
/* ETR functions */ /* ETR functions */
void tmc_etr_enable_hw(struct tmc_drvdata *drvdata); int tmc_read_prepare_etr(struct tmc_drvdata *drvdata);
void tmc_etr_disable_hw(struct tmc_drvdata *drvdata); int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata);
extern const struct coresight_ops tmc_etr_cs_ops; extern const struct coresight_ops tmc_etr_cs_ops;
#endif #endif
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