Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alexander Shishkin and committed by
Greg Kroah-Hartman
8d415512 ba39bd83

+29 -10
+7
drivers/hwtracing/intel_th/gth.c
··· 469 469 struct intel_th_output *output) 470 470 { 471 471 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 472 + struct intel_th_device *outdev = 473 + container_of(output, struct intel_th_device, output); 474 + struct intel_th_driver *outdrv = 475 + to_intel_th_driver(outdev->dev.driver); 472 476 unsigned long count; 473 477 int master; 474 478 u32 reg; ··· 495 491 reg = ioread32(gth->base + REG_GTH_STAT); 496 492 cpu_relax(); 497 493 } 494 + 495 + if (outdrv->wait_empty) 496 + outdrv->wait_empty(outdev); 498 497 499 498 /* clear force capture done for next captures */ 500 499 iowrite32(0xfc, gth->base + REG_GTH_SCR2);
+4
drivers/hwtracing/intel_th/intel_th.h
··· 20 20 INTEL_TH_SWITCH, 21 21 }; 22 22 23 + struct intel_th_device; 24 + 23 25 /** 24 26 * struct intel_th_output - descriptor INTEL_TH_OUTPUT type devices 25 27 * @port: output port number, assigned by the switch ··· 29 27 * @scratchpad: scratchpad bits to flag when this output is enabled 30 28 * @multiblock: true for multiblock output configuration 31 29 * @active: true when this output is enabled 30 + * @wait_empty: wait for device pipeline to be empty 32 31 * 33 32 * Output port descriptor, used by switch driver to tell which output 34 33 * port this output device corresponds to. Filled in at output device's ··· 168 165 struct intel_th_output *output); 169 166 /* output ops */ 170 167 irqreturn_t (*irq)(struct intel_th_device *thdev); 168 + void (*wait_empty)(struct intel_th_device *thdev); 171 169 int (*activate)(struct intel_th_device *thdev); 172 170 void (*deactivate)(struct intel_th_device *thdev); 173 171 /* file_operations for those who want a device node */
+18 -10
drivers/hwtracing/intel_th/msu.c
··· 577 577 */ 578 578 static void msc_disable(struct msc *msc) 579 579 { 580 - unsigned long count; 581 580 u32 reg; 582 581 583 582 lockdep_assert_held(&msc->buf_mutex); 584 583 585 584 intel_th_trace_disable(msc->thdev); 586 585 587 - for (reg = 0, count = MSC_PLE_WAITLOOP_DEPTH; 588 - count && !(reg & MSCSTS_PLE); count--) { 589 - reg = ioread32(msc->reg_base + REG_MSU_MSC0STS); 590 - cpu_relax(); 591 - } 592 - 593 - if (!count) 594 - dev_dbg(msc_dev(msc), "timeout waiting for MSC0 PLE\n"); 595 - 596 586 if (msc->mode == MSC_MODE_SINGLE) { 587 + reg = ioread32(msc->reg_base + REG_MSU_MSC0STS); 597 588 msc->single_wrap = !!(reg & MSCSTS_WRAPSTAT); 598 589 599 590 reg = ioread32(msc->reg_base + REG_MSU_MSC0MWP); ··· 1351 1360 .owner = THIS_MODULE, 1352 1361 }; 1353 1362 1363 + static void intel_th_msc_wait_empty(struct intel_th_device *thdev) 1364 + { 1365 + struct msc *msc = dev_get_drvdata(&thdev->dev); 1366 + unsigned long count; 1367 + u32 reg; 1368 + 1369 + for (reg = 0, count = MSC_PLE_WAITLOOP_DEPTH; 1370 + count && !(reg & MSCSTS_PLE); count--) { 1371 + reg = __raw_readl(msc->reg_base + REG_MSU_MSC0STS); 1372 + cpu_relax(); 1373 + } 1374 + 1375 + if (!count) 1376 + dev_dbg(msc_dev(msc), "timeout waiting for MSC0 PLE\n"); 1377 + } 1378 + 1354 1379 static int intel_th_msc_init(struct msc *msc) 1355 1380 { 1356 1381 atomic_set(&msc->user_count, -1); ··· 1647 1640 .probe = intel_th_msc_probe, 1648 1641 .remove = intel_th_msc_remove, 1649 1642 .irq = intel_th_msc_interrupt, 1643 + .wait_empty = intel_th_msc_wait_empty, 1650 1644 .activate = intel_th_msc_activate, 1651 1645 .deactivate = intel_th_msc_deactivate, 1652 1646 .fops = &intel_th_msc_fops,