Commit 8d415512 authored by Alexander Shishkin's avatar Alexander Shishkin Committed by Greg Kroah-Hartman

intel_th: msu: Factor out pipeline draining

The code that waits for the pipeline empty condition of the MSU is
currently called in the path that disables the trace. We will also
need this in the window switch trigger sequence. Therefore, factor
out this code and make it accessible to the GTH device.
Signed-off-by: default avatarAlexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ba39bd83
......@@ -469,6 +469,10 @@ static void intel_th_gth_disable(struct intel_th_device *thdev,
struct intel_th_output *output)
{
struct gth_device *gth = dev_get_drvdata(&thdev->dev);
struct intel_th_device *outdev =
container_of(output, struct intel_th_device, output);
struct intel_th_driver *outdrv =
to_intel_th_driver(outdev->dev.driver);
unsigned long count;
int master;
u32 reg;
......@@ -492,6 +496,9 @@ static void intel_th_gth_disable(struct intel_th_device *thdev,
cpu_relax();
}
if (outdrv->wait_empty)
outdrv->wait_empty(outdev);
/* clear force capture done for next captures */
iowrite32(0xfc, gth->base + REG_GTH_SCR2);
......
......@@ -20,6 +20,8 @@ enum {
INTEL_TH_SWITCH,
};
struct intel_th_device;
/**
* struct intel_th_output - descriptor INTEL_TH_OUTPUT type devices
* @port: output port number, assigned by the switch
......@@ -27,6 +29,7 @@ enum {
* @scratchpad: scratchpad bits to flag when this output is enabled
* @multiblock: true for multiblock output configuration
* @active: true when this output is enabled
* @wait_empty: wait for device pipeline to be empty
*
* Output port descriptor, used by switch driver to tell which output
* port this output device corresponds to. Filled in at output device's
......@@ -165,6 +168,7 @@ struct intel_th_driver {
struct intel_th_output *output);
/* output ops */
irqreturn_t (*irq)(struct intel_th_device *thdev);
void (*wait_empty)(struct intel_th_device *thdev);
int (*activate)(struct intel_th_device *thdev);
void (*deactivate)(struct intel_th_device *thdev);
/* file_operations for those who want a device node */
......
......@@ -577,23 +577,14 @@ static int msc_configure(struct msc *msc)
*/
static void msc_disable(struct msc *msc)
{
unsigned long count;
u32 reg;
lockdep_assert_held(&msc->buf_mutex);
intel_th_trace_disable(msc->thdev);
for (reg = 0, count = MSC_PLE_WAITLOOP_DEPTH;
count && !(reg & MSCSTS_PLE); count--) {
reg = ioread32(msc->reg_base + REG_MSU_MSC0STS);
cpu_relax();
}
if (!count)
dev_dbg(msc_dev(msc), "timeout waiting for MSC0 PLE\n");
if (msc->mode == MSC_MODE_SINGLE) {
reg = ioread32(msc->reg_base + REG_MSU_MSC0STS);
msc->single_wrap = !!(reg & MSCSTS_WRAPSTAT);
reg = ioread32(msc->reg_base + REG_MSU_MSC0MWP);
......@@ -1360,6 +1351,22 @@ static const struct file_operations intel_th_msc_fops = {
.owner = THIS_MODULE,
};
static void intel_th_msc_wait_empty(struct intel_th_device *thdev)
{
struct msc *msc = dev_get_drvdata(&thdev->dev);
unsigned long count;
u32 reg;
for (reg = 0, count = MSC_PLE_WAITLOOP_DEPTH;
count && !(reg & MSCSTS_PLE); count--) {
reg = __raw_readl(msc->reg_base + REG_MSU_MSC0STS);
cpu_relax();
}
if (!count)
dev_dbg(msc_dev(msc), "timeout waiting for MSC0 PLE\n");
}
static int intel_th_msc_init(struct msc *msc)
{
atomic_set(&msc->user_count, -1);
......@@ -1640,6 +1647,7 @@ static struct intel_th_driver intel_th_msc_driver = {
.probe = intel_th_msc_probe,
.remove = intel_th_msc_remove,
.irq = intel_th_msc_interrupt,
.wait_empty = intel_th_msc_wait_empty,
.activate = intel_th_msc_activate,
.deactivate = intel_th_msc_deactivate,
.fops = &intel_th_msc_fops,
......
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