forked from Minki/linux
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: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
6c6ed1e244
commit
4525412a50
@ -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 = {
|
|||||||
.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)
|
|||||||
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 = {
|
|||||||
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)
|
|||||||
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);
|
|||||||
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
|
||||||
|
Loading…
Reference in New Issue
Block a user