diff options
Diffstat (limited to 'drivers/hwtracing')
-rw-r--r-- | drivers/hwtracing/coresight/coresight-core.c | 11 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-etm4x-core.c | 5 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc-etf.c | 2 | ||||
-rw-r--r-- | drivers/hwtracing/intel_th/core.c | 29 | ||||
-rw-r--r-- | drivers/hwtracing/intel_th/gth.c | 16 | ||||
-rw-r--r-- | drivers/hwtracing/intel_th/intel_th.h | 3 | ||||
-rw-r--r-- | drivers/hwtracing/intel_th/msu.c | 48 |
7 files changed, 81 insertions, 33 deletions
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 6c68d34d956e..1002605db8ba 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -608,7 +608,7 @@ static struct coresight_device * coresight_find_enabled_sink(struct coresight_device *csdev) { int i; - struct coresight_device *sink; + struct coresight_device *sink = NULL; if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) && @@ -886,7 +886,6 @@ void coresight_release_path(struct list_head *path) } kfree(path); - path = NULL; } /* return true if the device is a suitable type for a default sink */ @@ -1392,7 +1391,7 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev) } } - return 0; + return ret; } static int coresight_remove_match(struct device *dev, void *data) @@ -1730,9 +1729,9 @@ char *coresight_alloc_device_name(struct coresight_dev_list *dict, if (idx < 0) { /* Make space for the new entry */ idx = dict->nr_idx; - list = krealloc(dict->fwnode_list, - (idx + 1) * sizeof(*dict->fwnode_list), - GFP_KERNEL); + list = krealloc_array(dict->fwnode_list, + idx + 1, sizeof(*dict->fwnode_list), + GFP_KERNEL); if (ZERO_OR_NULL_PTR(list)) { idx = -ENOMEM; goto done; diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index db881993c211..da27cd4a3c38 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -568,11 +568,6 @@ static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, struct etmv4_config *config = &drvdata->config; struct perf_event_attr *attr = &event->attr; - if (!attr) { - ret = -EINVAL; - goto out; - } - /* Clear configuration from previous run */ memset(config, 0, sizeof(struct etmv4_config)); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index 45b85edfc690..cd0fb7bfba68 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -530,7 +530,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev, buf_ptr = buf->data_pages[cur] + offset; *buf_ptr = readl_relaxed(drvdata->base + TMC_RRD); - if (lost && *barrier) { + if (lost && i < CORESIGHT_BARRIER_PKT_SIZE) { *buf_ptr = *barrier; barrier++; } diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 24d0c974bfd5..66eed2dff818 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -100,16 +100,18 @@ static int intel_th_remove(struct device *dev) struct intel_th_driver *thdrv = to_intel_th_driver(dev->driver); struct intel_th_device *thdev = to_intel_th_device(dev); struct intel_th_device *hub = to_intel_th_hub(thdev); - int err; if (thdev->type == INTEL_TH_SWITCH) { struct intel_th *th = to_intel_th(hub); int i, lowest; - /* disconnect outputs */ - err = device_for_each_child(dev, thdev, intel_th_child_remove); - if (err) - return err; + /* + * disconnect outputs + * + * intel_th_child_remove returns 0 unconditionally, so there is + * no need to check the return value of device_for_each_child. + */ + device_for_each_child(dev, thdev, intel_th_child_remove); /* * Remove outputs, that is, hub's children: they are created @@ -215,6 +217,22 @@ static ssize_t port_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(port); +static void intel_th_trace_prepare(struct intel_th_device *thdev) +{ + struct intel_th_device *hub = to_intel_th_hub(thdev); + struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); + + if (hub->type != INTEL_TH_SWITCH) + return; + + if (thdev->type != INTEL_TH_OUTPUT) + return; + + pm_runtime_get_sync(&thdev->dev); + hubdrv->prepare(hub, &thdev->output); + pm_runtime_put(&thdev->dev); +} + static int intel_th_output_activate(struct intel_th_device *thdev) { struct intel_th_driver *thdrv = @@ -235,6 +253,7 @@ static int intel_th_output_activate(struct intel_th_device *thdev) if (ret) goto fail_put; + intel_th_trace_prepare(thdev); if (thdrv->activate) ret = thdrv->activate(thdev); else diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c index 28509b02a0b5..b3308934a687 100644 --- a/drivers/hwtracing/intel_th/gth.c +++ b/drivers/hwtracing/intel_th/gth.c @@ -564,6 +564,21 @@ static void gth_tscu_resync(struct gth_device *gth) iowrite32(reg, gth->base + REG_TSCU_TSUCTRL); } +static void intel_th_gth_prepare(struct intel_th_device *thdev, + struct intel_th_output *output) +{ + struct gth_device *gth = dev_get_drvdata(&thdev->dev); + int count; + + /* + * Wait until the output port is in reset before we start + * programming it. + */ + for (count = GTH_PLE_WAITLOOP_DEPTH; + count && !(gth_output_get(gth, output->port) & BIT(5)); count--) + cpu_relax(); +} + /** * intel_th_gth_enable() - enable tracing to an output device * @thdev: GTH device @@ -815,6 +830,7 @@ static struct intel_th_driver intel_th_gth_driver = { .assign = intel_th_gth_assign, .unassign = intel_th_gth_unassign, .set_output = intel_th_gth_set_output, + .prepare = intel_th_gth_prepare, .enable = intel_th_gth_enable, .trig_switch = intel_th_gth_switch, .disable = intel_th_gth_disable, diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index 89c67e0e1d34..0ffb42990175 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -143,6 +143,7 @@ intel_th_output_assigned(struct intel_th_device *thdev) * @remove: remove method * @assign: match a given output type device against available outputs * @unassign: deassociate an output type device from an output port + * @prepare: prepare output port for tracing * @enable: enable tracing for a given output device * @disable: disable tracing for a given output device * @irq: interrupt callback @@ -164,6 +165,8 @@ struct intel_th_driver { struct intel_th_device *othdev); void (*unassign)(struct intel_th_device *thdev, struct intel_th_device *othdev); + void (*prepare)(struct intel_th_device *thdev, + struct intel_th_output *output); void (*enable)(struct intel_th_device *thdev, struct intel_th_output *output); void (*trig_switch)(struct intel_th_device *thdev, diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c index 2edc4666633d..432ade0842f6 100644 --- a/drivers/hwtracing/intel_th/msu.c +++ b/drivers/hwtracing/intel_th/msu.c @@ -1024,33 +1024,49 @@ err_nomem: } #ifdef CONFIG_X86 -static void msc_buffer_set_uc(struct msc_window *win, unsigned int nr_segs) +static void msc_buffer_set_uc(struct msc *msc) { struct scatterlist *sg_ptr; + struct msc_window *win; int i; - for_each_sg(win->sgt->sgl, sg_ptr, nr_segs, i) { - /* Set the page as uncached */ - set_memory_uc((unsigned long)sg_virt(sg_ptr), - PFN_DOWN(sg_ptr->length)); + if (msc->mode == MSC_MODE_SINGLE) { + set_memory_uc((unsigned long)msc->base, msc->nr_pages); + return; + } + + list_for_each_entry(win, &msc->win_list, entry) { + for_each_sg(win->sgt->sgl, sg_ptr, win->nr_segs, i) { + /* Set the page as uncached */ + set_memory_uc((unsigned long)sg_virt(sg_ptr), + PFN_DOWN(sg_ptr->length)); + } } } -static void msc_buffer_set_wb(struct msc_window *win) +static void msc_buffer_set_wb(struct msc *msc) { struct scatterlist *sg_ptr; + struct msc_window *win; int i; - for_each_sg(win->sgt->sgl, sg_ptr, win->nr_segs, i) { - /* Reset the page to write-back */ - set_memory_wb((unsigned long)sg_virt(sg_ptr), - PFN_DOWN(sg_ptr->length)); + if (msc->mode == MSC_MODE_SINGLE) { + set_memory_wb((unsigned long)msc->base, msc->nr_pages); + return; + } + + list_for_each_entry(win, &msc->win_list, entry) { + for_each_sg(win->sgt->sgl, sg_ptr, win->nr_segs, i) { + /* Reset the page to write-back */ + set_memory_wb((unsigned long)sg_virt(sg_ptr), + PFN_DOWN(sg_ptr->length)); + } } } #else /* !X86 */ static inline void -msc_buffer_set_uc(struct msc_window *win, unsigned int nr_segs) {} -static inline void msc_buffer_set_wb(struct msc_window *win) {} +msc_buffer_set_uc(struct msc *msc) {} +static inline void msc_buffer_set_wb(struct msc *msc) {} #endif /* CONFIG_X86 */ /** @@ -1097,8 +1113,6 @@ static int msc_buffer_win_alloc(struct msc *msc, unsigned int nr_blocks) if (ret <= 0) goto err_nomem; - msc_buffer_set_uc(win, ret); - win->nr_segs = ret; win->nr_blocks = nr_blocks; @@ -1152,8 +1166,6 @@ static void msc_buffer_win_free(struct msc *msc, struct msc_window *win) msc->base_addr = 0; } - msc_buffer_set_wb(win); - if (msc->mbuf && msc->mbuf->free_window) msc->mbuf->free_window(msc->mbuf_priv, win->sgt); else @@ -1260,6 +1272,8 @@ static int msc_buffer_multi_alloc(struct msc *msc, unsigned long *nr_pages, */ static void msc_buffer_free(struct msc *msc) { + msc_buffer_set_wb(msc); + if (msc->mode == MSC_MODE_SINGLE) msc_buffer_contig_free(msc); else if (msc->mode == MSC_MODE_MULTI) @@ -1303,6 +1317,8 @@ static int msc_buffer_alloc(struct msc *msc, unsigned long *nr_pages, } if (!ret) { + msc_buffer_set_uc(msc); + /* allocation should be visible before the counter goes to 0 */ smp_mb__before_atomic(); |