From 71c488f32b071bfb5cfe9ddf682cd2e0c310c75d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 10 Aug 2017 15:45:10 +0300 Subject: stm: Potential read overflow in stm_char_policy_set_ioctl() The "size" variable comes from the user so we need to verify that it's large enough to hold an stp_policy_id struct. Fixes: 7bd1d4093c2f ("stm class: Introduce an abstraction for System Trace Module devices") Signed-off-by: Dan Carpenter Signed-off-by: Alexander Shishkin --- drivers/hwtracing/stm/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index 0e731143f6a4..9414900575d8 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -566,7 +566,7 @@ static int stm_char_policy_set_ioctl(struct stm_file *stmf, void __user *arg) if (copy_from_user(&size, arg, sizeof(size))) return -EFAULT; - if (size >= PATH_MAX + sizeof(*id)) + if (size < sizeof(*id) || size >= PATH_MAX + sizeof(*id)) return -EINVAL; /* -- cgit v1.2.3 From e9b2b3e7933529647a5f284136f5a6bfa9c679ae Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Thu, 10 Aug 2017 11:10:58 +0300 Subject: intel_th: pci: Enable bus mastering The driver forgets to enable bus mastering for the PCI device. Fix this. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/pci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 590cf90dd21a..aac7d66d6adf 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -46,6 +46,8 @@ static int intel_th_pci_probe(struct pci_dev *pdev, if (IS_ERR(th)) return PTR_ERR(th); + pci_set_master(pdev); + return 0; } -- cgit v1.2.3 From 5376be63ff4ff357d40dbe75c925d7cd5aef19a9 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 18 Nov 2016 14:51:05 +0200 Subject: intel_th: Output devices without ports don't need assigning Output subdevices that rely on other output subdevices (or otherwise don't directly talk to an output port on the switch) don't need to be assigned an output port either. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/intel_th.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index 3096e7054f6d..c03f28ef6409 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -96,6 +96,16 @@ intel_th_device_get_resource(struct intel_th_device *thdev, unsigned int type, return NULL; } +/* + * GTH, output ports configuration + */ +enum { + GTH_NONE = 0, + GTH_MSU, /* memory/usb */ + GTH_CTP, /* Common Trace Port */ + GTH_PTI = 4, /* MIPI-PTI */ +}; + /** * intel_th_output_assigned() - if an output device is assigned to a switch port * @thdev: the output device @@ -106,7 +116,8 @@ static inline bool intel_th_output_assigned(struct intel_th_device *thdev) { return thdev->type == INTEL_TH_OUTPUT && - thdev->output.port >= 0; + (thdev->output.port >= 0 || + thdev->output.type == GTH_NONE); } /** @@ -249,16 +260,6 @@ enum { REG_DCIH_LENGTH = REG_MSU_LENGTH, }; -/* - * GTH, output ports configuration - */ -enum { - GTH_NONE = 0, - GTH_MSU, /* memory/usb */ - GTH_CTP, /* Common Trace Port */ - GTH_PTI = 4, /* MIPI-PTI */ -}; - /* * Scratchpad bits: tell firmware and external debuggers * what we are up to. -- cgit v1.2.3 From 5e06723af998779210dffe9553b36b28955d5860 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 18 Nov 2016 15:05:01 +0200 Subject: intel_th: Streamline the subdevice tree accessors Make to_intel_th*() accessors available from the main header file. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/core.c | 15 --------------- drivers/hwtracing/intel_th/intel_th.h | 25 ++++++++++++++++++++++++- 2 files changed, 24 insertions(+), 16 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 8da567abc0ce..e6d302ba1707 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -156,21 +156,6 @@ static struct device_type intel_th_source_device_type = { .release = intel_th_device_release, }; -static struct intel_th *to_intel_th(struct intel_th_device *thdev) -{ - /* - * subdevice tree is flat: if this one is not a switch, its - * parent must be - */ - if (thdev->type != INTEL_TH_SWITCH) - thdev = to_intel_th_hub(thdev); - - if (WARN_ON_ONCE(!thdev || thdev->type != INTEL_TH_SWITCH)) - return NULL; - - return dev_get_drvdata(thdev->dev.parent); -} - static char *intel_th_output_devnode(struct device *dev, umode_t *mode, kuid_t *uid, kgid_t *gid) { diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index c03f28ef6409..496286ce79e8 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -173,7 +173,7 @@ struct intel_th_driver { ((_d) ? to_intel_th_driver(_d) : NULL) static inline struct intel_th_device * -to_intel_th_hub(struct intel_th_device *thdev) +to_intel_th_parent(struct intel_th_device *thdev) { struct device *parent = thdev->dev.parent; @@ -183,6 +183,29 @@ to_intel_th_hub(struct intel_th_device *thdev) return to_intel_th_device(parent); } +static inline struct intel_th_device * +to_intel_th_hub(struct intel_th_device *thdev) +{ + /* + * subdevice tree is flat: if this one is not a switch, its + * parent must be + */ + if (thdev->type == INTEL_TH_SWITCH) + return thdev; + + return to_intel_th_parent(thdev); +} + +static inline struct intel_th *to_intel_th(struct intel_th_device *thdev) +{ + thdev = to_intel_th_hub(thdev); + + if (WARN_ON_ONCE(!thdev || thdev->type != INTEL_TH_SWITCH)) + return NULL; + + return dev_get_drvdata(thdev->dev.parent); +} + struct intel_th * intel_th_alloc(struct device *dev, struct resource *devres, unsigned int ndevres, int irq); -- cgit v1.2.3 From 8edc514b01e9cfbc037c708e5260f248cbb4d867 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 18 Nov 2016 15:36:39 +0200 Subject: intel_th: Make SOURCE devices children of the root device The switch (GTH) does not directly interact with SOURCE type devices and may not even be present (in host mode). To reflect this and avoid inconsistencies between target and host mode, make SOURCE devices descendant directly from the root (i.e. PCI) device. Their symlinks will no longer appear under the switch device, but they can still be found under intel_th bus. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/core.c | 6 +++--- drivers/hwtracing/intel_th/intel_th.h | 39 +++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 18 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index e6d302ba1707..323d3ac8d4f7 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -311,10 +311,10 @@ intel_th_device_alloc(struct intel_th *th, unsigned int type, const char *name, struct device *parent; struct intel_th_device *thdev; - if (type == INTEL_TH_SWITCH) - parent = th->dev; - else + if (type == INTEL_TH_OUTPUT) parent = &th->hub->dev; + else + parent = th->dev; thdev = kzalloc(sizeof(*thdev) + strlen(name) + 1, GFP_KERNEL); if (!thdev) diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index 496286ce79e8..6243ac1b8bf1 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -172,6 +172,16 @@ struct intel_th_driver { #define to_intel_th_driver_or_null(_d) \ ((_d) ? to_intel_th_driver(_d) : NULL) +/* + * Subdevice tree structure is as follows: + * + struct intel_th device (pci; dev_{get,set}_drvdata() + * + struct intel_th_device INTEL_TH_SWITCH (GTH) + * + struct intel_th_device INTEL_TH_OUTPUT (MSU, PTI) + * + struct intel_th_device INTEL_TH_SOURCE (STH) + * + * In other words, INTEL_TH_OUTPUT devices are children of INTEL_TH_SWITCH; + * INTEL_TH_SWITCH and INTEL_TH_SOURCE are children of the intel_th device. + */ static inline struct intel_th_device * to_intel_th_parent(struct intel_th_device *thdev) { @@ -183,24 +193,12 @@ to_intel_th_parent(struct intel_th_device *thdev) return to_intel_th_device(parent); } -static inline struct intel_th_device * -to_intel_th_hub(struct intel_th_device *thdev) -{ - /* - * subdevice tree is flat: if this one is not a switch, its - * parent must be - */ - if (thdev->type == INTEL_TH_SWITCH) - return thdev; - - return to_intel_th_parent(thdev); -} - static inline struct intel_th *to_intel_th(struct intel_th_device *thdev) { - thdev = to_intel_th_hub(thdev); + if (thdev->type == INTEL_TH_OUTPUT) + thdev = to_intel_th_parent(thdev); - if (WARN_ON_ONCE(!thdev || thdev->type != INTEL_TH_SWITCH)) + if (WARN_ON_ONCE(!thdev || thdev->type == INTEL_TH_OUTPUT)) return NULL; return dev_get_drvdata(thdev->dev.parent); @@ -254,6 +252,17 @@ struct intel_th { #endif }; +static inline struct intel_th_device * +to_intel_th_hub(struct intel_th_device *thdev) +{ + if (thdev->type == INTEL_TH_SWITCH) + return thdev; + else if (thdev->type == INTEL_TH_OUTPUT) + return to_intel_th_parent(thdev); + + return to_intel_th(thdev)->hub; +} + /* * Register windows */ -- cgit v1.2.3 From a753bfcfdb1f31d74b5ec87faa19f15e8c7b44a2 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Thu, 10 Aug 2017 18:28:38 +0300 Subject: intel_th: Make the switch allocate its subdevices Instead of allocating devices for every possible output subdevice, allow the switch to allocate only the ones that it knows about. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/core.c | 288 ++++++++++++++++++++++++---------- drivers/hwtracing/intel_th/gth.c | 17 +- drivers/hwtracing/intel_th/intel_th.h | 13 +- 3 files changed, 230 insertions(+), 88 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 323d3ac8d4f7..4f569593db01 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -101,17 +101,53 @@ out_pm: return ret; } +static void intel_th_device_remove(struct intel_th_device *thdev); + 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_device(dev->parent); + 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; + + /* + * Remove outputs, that is, hub's children: they are created + * at hub's probe time by having the hub call + * intel_th_output_enable() for each of them. + */ + for (i = 0, lowest = -1; i < th->num_thdevs; i++) { + /* + * Move the non-output devices from higher up the + * th->thdev[] array to lower positions to maintain + * a contiguous array. + */ + if (th->thdev[i]->type != INTEL_TH_OUTPUT) { + if (lowest >= 0) { + th->thdev[lowest] = th->thdev[i]; + th->thdev[i] = NULL; + ++lowest; + } + + continue; + } + + if (lowest == -1) + lowest = i; + + intel_th_device_remove(th->thdev[i]); + th->thdev[i] = NULL; + } + + th->num_thdevs = lowest; } if (thdrv->attr_group) @@ -377,7 +413,7 @@ static const struct intel_th_subdevice { unsigned otype; unsigned scrpd; int id; -} intel_th_subdevices[TH_SUBDEVICE_MAX] = { +} intel_th_subdevices[] = { { .nres = 1, .res = { @@ -511,98 +547,181 @@ static inline void intel_th_request_hub_module_flush(struct intel_th *th) } #endif /* CONFIG_MODULES */ -static int intel_th_populate(struct intel_th *th, struct resource *devres, - unsigned int ndevres, int irq) +static struct intel_th_device * +intel_th_subdevice_alloc(struct intel_th *th, + const struct intel_th_subdevice *subdev) { + struct intel_th_device *thdev; struct resource res[3]; unsigned int req = 0; - int src, dst, err; + int r, err; - /* create devices for each intel_th_subdevice */ - for (src = 0, dst = 0; src < ARRAY_SIZE(intel_th_subdevices); src++) { - const struct intel_th_subdevice *subdev = - &intel_th_subdevices[src]; - struct intel_th_device *thdev; - int r; + thdev = intel_th_device_alloc(th, subdev->type, subdev->name, + subdev->id); + if (!thdev) + return ERR_PTR(-ENOMEM); - /* only allow SOURCE and SWITCH devices in host mode */ - if (host_mode && subdev->type == INTEL_TH_OUTPUT) - continue; - thdev = intel_th_device_alloc(th, subdev->type, subdev->name, - subdev->id); - if (!thdev) { - err = -ENOMEM; - goto kill_subdevs; + memcpy(res, subdev->res, + sizeof(struct resource) * subdev->nres); + + for (r = 0; r < subdev->nres; r++) { + struct resource *devres = th->resource; + int bar = TH_MMIO_CONFIG; + + /* + * Take .end == 0 to mean 'take the whole bar', + * .start then tells us which bar it is. Default to + * TH_MMIO_CONFIG. + */ + if (!res[r].end && res[r].flags == IORESOURCE_MEM) { + bar = res[r].start; + res[r].start = 0; + res[r].end = resource_size(&devres[bar]) - 1; } - memcpy(res, subdev->res, - sizeof(struct resource) * subdev->nres); + if (res[r].flags & IORESOURCE_MEM) { + res[r].start += devres[bar].start; + res[r].end += devres[bar].start; - for (r = 0; r < subdev->nres; r++) { - int bar = TH_MMIO_CONFIG; + dev_dbg(th->dev, "%s:%d @ %pR\n", + subdev->name, r, &res[r]); + } else if (res[r].flags & IORESOURCE_IRQ) { + res[r].start = th->irq; + } + } - /* - * Take .end == 0 to mean 'take the whole bar', - * .start then tells us which bar it is. Default to - * TH_MMIO_CONFIG. - */ - if (!res[r].end && res[r].flags == IORESOURCE_MEM) { - bar = res[r].start; - res[r].start = 0; - res[r].end = resource_size(&devres[bar]) - 1; - } + err = intel_th_device_add_resources(thdev, res, subdev->nres); + if (err) { + put_device(&thdev->dev); + goto fail_put_device; + } - if (res[r].flags & IORESOURCE_MEM) { - res[r].start += devres[bar].start; - res[r].end += devres[bar].start; + if (subdev->type == INTEL_TH_OUTPUT) { + thdev->dev.devt = MKDEV(th->major, th->num_thdevs); + thdev->output.type = subdev->otype; + thdev->output.port = -1; + thdev->output.scratchpad = subdev->scrpd; + } else if (subdev->type == INTEL_TH_SWITCH) { + thdev->host_mode = host_mode; + th->hub = thdev; + } - dev_dbg(th->dev, "%s:%d @ %pR\n", - subdev->name, r, &res[r]); - } else if (res[r].flags & IORESOURCE_IRQ) { - res[r].start = irq; - } - } + err = device_add(&thdev->dev); + if (err) { + put_device(&thdev->dev); + goto fail_free_res; + } - err = intel_th_device_add_resources(thdev, res, subdev->nres); - if (err) { - put_device(&thdev->dev); - goto kill_subdevs; - } + /* need switch driver to be loaded to enumerate the rest */ + if (subdev->type == INTEL_TH_SWITCH && !req) { + err = intel_th_request_hub_module(th); + if (!err) + req++; + } - if (subdev->type == INTEL_TH_OUTPUT) { - thdev->dev.devt = MKDEV(th->major, dst); - thdev->output.type = subdev->otype; - thdev->output.port = -1; - thdev->output.scratchpad = subdev->scrpd; - } else if (subdev->type == INTEL_TH_SWITCH) { - thdev->host_mode = host_mode; - } + return thdev; + +fail_free_res: + kfree(thdev->resource); + +fail_put_device: + put_device(&thdev->dev); + + return ERR_PTR(err); +} - err = device_add(&thdev->dev); - if (err) { - put_device(&thdev->dev); - goto kill_subdevs; +/** + * intel_th_output_enable() - find and enable a device for a given output type + * @th: Intel TH instance + * @otype: output type + * + * Go through the unallocated output devices, find the first one whos type + * matches @otype and instantiate it. These devices are removed when the hub + * device is removed, see intel_th_remove(). + */ +int intel_th_output_enable(struct intel_th *th, unsigned int otype) +{ + struct intel_th_device *thdev; + int src = 0, dst = 0; + + for (src = 0, dst = 0; dst <= th->num_thdevs; src++, dst++) { + for (; src < ARRAY_SIZE(intel_th_subdevices); src++) { + if (intel_th_subdevices[src].type != INTEL_TH_OUTPUT) + continue; + + if (intel_th_subdevices[src].otype != otype) + continue; + + break; } - /* need switch driver to be loaded to enumerate the rest */ - if (subdev->type == INTEL_TH_SWITCH && !req) { - th->hub = thdev; - err = intel_th_request_hub_module(th); - if (!err) - req++; + /* no unallocated matching subdevices */ + if (src == ARRAY_SIZE(intel_th_subdevices)) + return -ENODEV; + + for (; dst < th->num_thdevs; dst++) { + if (th->thdev[dst]->type != INTEL_TH_OUTPUT) + continue; + + if (th->thdev[dst]->output.type != otype) + continue; + + break; } - th->thdev[dst++] = thdev; + /* + * intel_th_subdevices[src] matches our requirements and is + * not matched in th::thdev[] + */ + if (dst == th->num_thdevs) + goto found; } + return -ENODEV; + +found: + thdev = intel_th_subdevice_alloc(th, &intel_th_subdevices[src]); + if (IS_ERR(thdev)) + return PTR_ERR(thdev); + + th->thdev[th->num_thdevs++] = thdev; + return 0; +} +EXPORT_SYMBOL_GPL(intel_th_output_enable); -kill_subdevs: - for (; dst >= 0; dst--) - intel_th_device_remove(th->thdev[dst]); +static int intel_th_populate(struct intel_th *th) +{ + int src; - return err; + /* create devices for each intel_th_subdevice */ + for (src = 0; src < ARRAY_SIZE(intel_th_subdevices); src++) { + const struct intel_th_subdevice *subdev = + &intel_th_subdevices[src]; + struct intel_th_device *thdev; + + /* only allow SOURCE and SWITCH devices in host mode */ + if (host_mode && subdev->type == INTEL_TH_OUTPUT) + continue; + + /* + * don't enable port OUTPUTs in this path; SWITCH enables them + * via intel_th_output_enable() + */ + if (subdev->type == INTEL_TH_OUTPUT && + subdev->otype != GTH_NONE) + continue; + + thdev = intel_th_subdevice_alloc(th, subdev); + /* note: caller should free subdevices from th::thdev[] */ + if (IS_ERR(thdev)) + return PTR_ERR(thdev); + + th->thdev[th->num_thdevs++] = thdev; + } + + return 0; } static int match_devt(struct device *dev, void *data) @@ -679,24 +798,25 @@ intel_th_alloc(struct device *dev, struct resource *devres, } th->dev = dev; + th->resource = devres; + th->num_resources = ndevres; + th->irq = irq; + dev_set_drvdata(dev, th); pm_runtime_no_callbacks(dev); pm_runtime_put(dev); pm_runtime_allow(dev); - err = intel_th_populate(th, devres, ndevres, irq); - if (err) - goto err_chrdev; + err = intel_th_populate(th); + if (err) { + /* free the subdevices and undo everything */ + intel_th_free(th); + return ERR_PTR(err); + } return th; -err_chrdev: - pm_runtime_forbid(dev); - - __unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS, - "intel_th/output"); - err_ida: ida_simple_remove(&intel_th_ida, th->id); @@ -712,11 +832,15 @@ void intel_th_free(struct intel_th *th) int i; intel_th_request_hub_module_flush(th); - for (i = 0; i < TH_SUBDEVICE_MAX; i++) - if (th->thdev[i] && th->thdev[i] != th->hub) - intel_th_device_remove(th->thdev[i]); intel_th_device_remove(th->hub); + for (i = 0; i < th->num_thdevs; i++) { + if (th->thdev[i] != th->hub) + intel_th_device_remove(th->thdev[i]); + th->thdev[i] = NULL; + } + + th->num_thdevs = 0; pm_runtime_get_sync(th->dev); pm_runtime_forbid(th->dev); diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c index dd32d0bad687..7d9d667fe017 100644 --- a/drivers/hwtracing/intel_th/gth.c +++ b/drivers/hwtracing/intel_th/gth.c @@ -639,6 +639,7 @@ intel_th_gth_set_output(struct intel_th_device *thdev, unsigned int master) static int intel_th_gth_probe(struct intel_th_device *thdev) { struct device *dev = &thdev->dev; + struct intel_th *th = dev_get_drvdata(dev->parent); struct gth_device *gth; struct resource *res; void __iomem *base; @@ -660,6 +661,8 @@ static int intel_th_gth_probe(struct intel_th_device *thdev) gth->base = base; spin_lock_init(>h->gth_lock); + dev_set_drvdata(dev, gth); + /* * Host mode can be signalled via SW means or via SCRPD_DEBUGGER_IN_USE * bit. Either way, don't reset HW in this case, and don't export any @@ -667,7 +670,7 @@ static int intel_th_gth_probe(struct intel_th_device *thdev) * drivers to ports, see intel_th_gth_assign(). */ if (thdev->host_mode) - goto done; + return 0; ret = intel_th_gth_reset(gth); if (ret) { @@ -676,7 +679,7 @@ static int intel_th_gth_probe(struct intel_th_device *thdev) thdev->host_mode = true; - goto done; + return 0; } for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++) @@ -687,6 +690,13 @@ static int intel_th_gth_probe(struct intel_th_device *thdev) gth->output[i].index = i; gth->output[i].port_type = gth_output_parm_get(gth, i, TH_OUTPUT_PARM(port)); + if (gth->output[i].port_type == GTH_NONE) + continue; + + ret = intel_th_output_enable(th, gth->output[i].port_type); + /* -ENODEV is ok, we just won't have that device enumerated */ + if (ret && ret != -ENODEV) + return ret; } if (intel_th_output_attributes(gth) || @@ -698,9 +708,6 @@ static int intel_th_gth_probe(struct intel_th_device *thdev) return -ENOMEM; } -done: - dev_set_drvdata(dev, gth); - return 0; } diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index 6243ac1b8bf1..d44da50be3b0 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -216,6 +216,7 @@ int intel_th_trace_enable(struct intel_th_device *thdev); int intel_th_trace_disable(struct intel_th_device *thdev); int intel_th_set_output(struct intel_th_device *thdev, unsigned int master); +int intel_th_output_enable(struct intel_th *th, unsigned int otype); enum { TH_MMIO_CONFIG = 0, @@ -223,8 +224,9 @@ enum { TH_MMIO_END, }; -#define TH_SUBDEVICE_MAX 6 #define TH_POSSIBLE_OUTPUTS 8 +/* Total number of possible subdevices: outputs + GTH + STH */ +#define TH_SUBDEVICE_MAX (TH_POSSIBLE_OUTPUTS + 2) #define TH_CONFIGURABLE_MASTERS 256 #define TH_MSC_MAX 2 @@ -233,6 +235,10 @@ enum { * @dev: driver core's device * @thdev: subdevices * @hub: "switch" subdevice (GTH) + * @resource: resources of the entire controller + * @num_thdevs: number of devices in the @thdev array + * @num_resources: number or resources in the @resource array + * @irq: irq number * @id: this Intel TH controller's device ID in the system * @major: device node major for output devices */ @@ -242,6 +248,11 @@ struct intel_th { struct intel_th_device *thdev[TH_SUBDEVICE_MAX]; struct intel_th_device *hub; + struct resource *resource; + unsigned int num_thdevs; + unsigned int num_resources; + int irq; + int id; int major; #ifdef CONFIG_MODULES -- cgit v1.2.3 From d5c435df4a890be0ef51f3047080756002d140dd Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 24 Feb 2017 16:05:22 +0200 Subject: intel_th: msu: Use the real device in case of IOMMU domain allocation When allocating DMA buffers for the MSU, use the real device instead of GTH. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/msu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c index dbbe31df74df..dfb57eaa9f22 100644 --- a/drivers/hwtracing/intel_th/msu.c +++ b/drivers/hwtracing/intel_th/msu.c @@ -709,17 +709,17 @@ static int msc_buffer_win_alloc(struct msc *msc, unsigned int nr_blocks) } for (i = 0; i < nr_blocks; i++) { - win->block[i].bdesc = dma_alloc_coherent(msc_dev(msc), size, - &win->block[i].addr, - GFP_KERNEL); + win->block[i].bdesc = + dma_alloc_coherent(msc_dev(msc)->parent->parent, size, + &win->block[i].addr, GFP_KERNEL); + + if (!win->block[i].bdesc) + goto err_nomem; #ifdef CONFIG_X86 /* Set the page as uncached */ set_memory_uc((unsigned long)win->block[i].bdesc, 1); #endif - - if (!win->block[i].bdesc) - goto err_nomem; } win->msc = msc; -- cgit v1.2.3 From 92758af39ab73f470f765b7213fb4c88c7e5ca03 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 11 Nov 2016 12:09:11 +0200 Subject: intel_th: Enumerate Low Power Path output port type Trace Hub 2.x adds Low Power Path (LPP) output port type, which provides a low power mode trace path from sources to PTI or BSSB. This adds an output subdevice for the LPP port. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/core.c | 15 +++++++++++++++ drivers/hwtracing/intel_th/intel_th.h | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 4f569593db01..d1760003b4a4 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -500,6 +500,21 @@ static const struct intel_th_subdevice { .otype = GTH_PTI, .scrpd = SCRPD_PTI_IS_PRIM_DEST, }, + { + .nres = 1, + .res = { + { + .start = REG_PTI_OFFSET, + .end = REG_PTI_OFFSET + REG_PTI_LENGTH - 1, + .flags = IORESOURCE_MEM, + }, + }, + .id = -1, + .name = "lpp", + .type = INTEL_TH_OUTPUT, + .otype = GTH_LPP, + .scrpd = SCRPD_PTI_IS_PRIM_DEST, + }, { .nres = 1, .res = { diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index d44da50be3b0..3f4558404dca 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -103,7 +103,8 @@ enum { GTH_NONE = 0, GTH_MSU, /* memory/usb */ GTH_CTP, /* Common Trace Port */ - GTH_PTI = 4, /* MIPI-PTI */ + GTH_LPP, /* Low Power Path */ + GTH_PTI, /* MIPI-PTI */ }; /** -- cgit v1.2.3 From f77d22bc1221409b6c0cb6f32c6241161f5c2bc6 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 11 Nov 2016 12:07:25 +0200 Subject: intel_th: pti: Support Low Power Path output port type The Low Power Path (LPP) output port type, looks mostly like PTI to the software, with a few additional bits in the control register. This extends the PTI driver to support LPP ports as well. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/pti.c | 115 +++++++++++++++++++++++++++++++++++++-- drivers/hwtracing/intel_th/pti.h | 8 +++ 2 files changed, 118 insertions(+), 5 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/pti.c b/drivers/hwtracing/intel_th/pti.c index 35738b5bfccd..e96a1fcb57b2 100644 --- a/drivers/hwtracing/intel_th/pti.c +++ b/drivers/hwtracing/intel_th/pti.c @@ -1,7 +1,7 @@ /* * Intel(R) Trace Hub PTI output driver * - * Copyright (C) 2014-2015 Intel Corporation. + * Copyright (C) 2014-2016 Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -34,6 +34,8 @@ struct pti_device { unsigned int freeclk; unsigned int clkdiv; unsigned int patgen; + unsigned int lpp_dest_mask; + unsigned int lpp_dest; }; /* map PTI widths to MODE settings of PTI_CTL register */ @@ -163,6 +165,7 @@ static int intel_th_pti_activate(struct intel_th_device *thdev) ctl |= PTI_FCEN; ctl |= pti->mode << __ffs(PTI_MODE); ctl |= pti->clkdiv << __ffs(PTI_CLKDIV); + ctl |= pti->lpp_dest << __ffs(LPP_DEST); iowrite32(ctl, pti->base + REG_PTI_CTL); @@ -192,6 +195,15 @@ static void read_hw_config(struct pti_device *pti) pti->mode = pti_width_mode(4); if (!pti->clkdiv) pti->clkdiv = 1; + + if (pti->thdev->output.type == GTH_LPP) { + if (ctl & LPP_PTIPRESENT) + pti->lpp_dest_mask |= LPP_DEST_PTI; + if (ctl & LPP_BSSBPRESENT) + pti->lpp_dest_mask |= LPP_DEST_EXI; + if (ctl & LPP_DEST) + pti->lpp_dest = 1; + } } static int intel_th_pti_probe(struct intel_th_device *thdev) @@ -239,10 +251,103 @@ static struct intel_th_driver intel_th_pti_driver = { }, }; -module_driver(intel_th_pti_driver, - intel_th_driver_register, - intel_th_driver_unregister); +static const char * const lpp_dest_str[] = { "pti", "exi" }; + +static ssize_t lpp_dest_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pti_device *pti = dev_get_drvdata(dev); + ssize_t ret = 0; + int i; + + for (i = ARRAY_SIZE(lpp_dest_str) - 1; i >= 0; i--) { + const char *fmt = pti->lpp_dest == i ? "[%s] " : "%s "; + + if (!(pti->lpp_dest_mask & BIT(i))) + continue; + + ret += scnprintf(buf + ret, PAGE_SIZE - ret, + fmt, lpp_dest_str[i]); + } + + if (ret) + buf[ret - 1] = '\n'; + + return ret; +} + +static ssize_t lpp_dest_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct pti_device *pti = dev_get_drvdata(dev); + ssize_t ret = -EINVAL; + int i; + + for (i = 0; i < ARRAY_SIZE(lpp_dest_str); i++) + if (sysfs_streq(buf, lpp_dest_str[i])) + break; + + if (i < ARRAY_SIZE(lpp_dest_str) && pti->lpp_dest_mask & BIT(i)) { + pti->lpp_dest = i; + ret = size; + } + + return ret; +} + +static DEVICE_ATTR_RW(lpp_dest); + +static struct attribute *lpp_output_attrs[] = { + &dev_attr_mode.attr, + &dev_attr_freerunning_clock.attr, + &dev_attr_clock_divider.attr, + &dev_attr_lpp_dest.attr, + NULL, +}; + +static struct attribute_group lpp_output_group = { + .attrs = lpp_output_attrs, +}; + +static struct intel_th_driver intel_th_lpp_driver = { + .probe = intel_th_pti_probe, + .remove = intel_th_pti_remove, + .activate = intel_th_pti_activate, + .deactivate = intel_th_pti_deactivate, + .attr_group = &lpp_output_group, + .driver = { + .name = "lpp", + .owner = THIS_MODULE, + }, +}; + +static int __init intel_th_pti_lpp_init(void) +{ + int err; + + err = intel_th_driver_register(&intel_th_pti_driver); + if (err) + return err; + + err = intel_th_driver_register(&intel_th_lpp_driver); + if (err) { + intel_th_driver_unregister(&intel_th_pti_driver); + return err; + } + + return 0; +} + +module_init(intel_th_pti_lpp_init); + +static void __exit intel_th_pti_lpp_exit(void) +{ + intel_th_driver_unregister(&intel_th_pti_driver); + intel_th_driver_unregister(&intel_th_lpp_driver); +} + +module_exit(intel_th_pti_lpp_exit); MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Intel(R) Trace Hub PTI output driver"); +MODULE_DESCRIPTION("Intel(R) Trace Hub PTI/LPP output driver"); MODULE_AUTHOR("Alexander Shishkin "); diff --git a/drivers/hwtracing/intel_th/pti.h b/drivers/hwtracing/intel_th/pti.h index 20883f5628cf..30827be67b4c 100644 --- a/drivers/hwtracing/intel_th/pti.h +++ b/drivers/hwtracing/intel_th/pti.h @@ -23,7 +23,15 @@ enum { #define PTI_EN BIT(0) #define PTI_FCEN BIT(1) #define PTI_MODE 0xf0 +#define LPP_PTIPRESENT BIT(8) +#define LPP_BSSBPRESENT BIT(9) #define PTI_CLKDIV 0x000f0000 #define PTI_PATGENMODE 0x00f00000 +#define LPP_DEST BIT(25) +#define LPP_BSSBACT BIT(30) +#define LPP_LPPBUSY BIT(31) + +#define LPP_DEST_PTI BIT(0) +#define LPP_DEST_EXI BIT(1) #endif /* __INTEL_TH_STH_H__ */ -- cgit v1.2.3 From 84331e1390b6378a5129a3678c87a42c6f697d29 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Thu, 30 Jun 2016 16:11:13 +0300 Subject: intel_th: pci: Add Cannon Lake PCH-H support This adds Intel(R) Trace Hub PCI ID for Cannon Lake PCH-H. Signed-off-by: Alexander Shishkin Cc: --- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index aac7d66d6adf..507db476654a 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -97,6 +97,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), .driver_data = (kernel_ulong_t)0, }, + { + /* Cannon Lake H */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326), + .driver_data = (kernel_ulong_t)0, + }, { 0 }, }; -- cgit v1.2.3 From efb3669e14fe17d0ec4ecf57d0365039fe726f59 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Thu, 30 Jun 2016 16:11:31 +0300 Subject: intel_th: pci: Add Cannon Lake PCH-LP support This adds Intel(R) Trace Hub PCI ID for Cannon Lake PCH-LP. Signed-off-by: Alexander Shishkin Cc: --- drivers/hwtracing/intel_th/pci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 507db476654a..5a9a9e8072a9 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -102,6 +102,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326), .driver_data = (kernel_ulong_t)0, }, + { + /* Cannon Lake LP */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), + .driver_data = (kernel_ulong_t)0, + }, { 0 }, }; -- cgit v1.2.3 From 3321371b5d648479058fa6f9441168abbc1467c9 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 18 Aug 2017 17:57:35 +0300 Subject: intel_th: pci: Use drvdata for quirks Allow attaching miscellaneous quirk information to devices as drvdata. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/core.c | 6 ++++-- drivers/hwtracing/intel_th/intel_th.h | 27 ++++++++++++++++++++------- drivers/hwtracing/intel_th/pci.c | 3 ++- 3 files changed, 26 insertions(+), 10 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index d1760003b4a4..e915ab24f434 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -576,6 +576,7 @@ intel_th_subdevice_alloc(struct intel_th *th, if (!thdev) return ERR_PTR(-ENOMEM); + thdev->drvdata = th->drvdata; memcpy(res, subdev->res, sizeof(struct resource) * subdev->nres); @@ -789,8 +790,8 @@ static const struct file_operations intel_th_output_fops = { * @irq: irq number */ struct intel_th * -intel_th_alloc(struct device *dev, struct resource *devres, - unsigned int ndevres, int irq) +intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata, + struct resource *devres, unsigned int ndevres, int irq) { struct intel_th *th; int err; @@ -812,6 +813,7 @@ intel_th_alloc(struct device *dev, struct resource *devres, goto err_ida; } th->dev = dev; + th->drvdata = drvdata; th->resource = devres; th->num_resources = ndevres; diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index 3f4558404dca..68244602ca29 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -47,9 +47,20 @@ struct intel_th_output { bool active; }; +/** + * struct intel_th_drvdata - describes hardware capabilities and quirks + * @tscu_enable: device needs SW to enable time stamping unit + */ +struct intel_th_drvdata { + unsigned int tscu_enable : 1; +}; + +#define INTEL_TH_CAP(_th, _cap) ((_th)->drvdata ? (_th)->drvdata->_cap : 0) + /** * struct intel_th_device - device on the intel_th bus * @dev: device + * @drvdata: hardware capabilities/quirks * @resource: array of resources available to this device * @num_resources: number of resources in @resource array * @type: INTEL_TH_{SOURCE,OUTPUT,SWITCH} @@ -59,11 +70,12 @@ struct intel_th_output { * @name: device name to match the driver */ struct intel_th_device { - struct device dev; - struct resource *resource; - unsigned int num_resources; - unsigned int type; - int id; + struct device dev; + struct intel_th_drvdata *drvdata; + struct resource *resource; + unsigned int num_resources; + unsigned int type; + int id; /* INTEL_TH_SWITCH specific */ bool host_mode; @@ -206,8 +218,8 @@ static inline struct intel_th *to_intel_th(struct intel_th_device *thdev) } struct intel_th * -intel_th_alloc(struct device *dev, struct resource *devres, - unsigned int ndevres, int irq); +intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata, + struct resource *devres, unsigned int ndevres, int irq); void intel_th_free(struct intel_th *th); int intel_th_driver_register(struct intel_th_driver *thdrv); @@ -248,6 +260,7 @@ struct intel_th { struct intel_th_device *thdev[TH_SUBDEVICE_MAX]; struct intel_th_device *hub; + struct intel_th_drvdata *drvdata; struct resource *resource; unsigned int num_thdevs; diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index 5a9a9e8072a9..aed6d594991e 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -30,6 +30,7 @@ static int intel_th_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct intel_th_drvdata *drvdata = (void *)id->driver_data; struct intel_th *th; int err; @@ -41,7 +42,7 @@ static int intel_th_pci_probe(struct pci_dev *pdev, if (err) return err; - th = intel_th_alloc(&pdev->dev, pdev->resource, + th = intel_th_alloc(&pdev->dev, drvdata, pdev->resource, DEVICE_COUNT_RESOURCE, pdev->irq); if (IS_ERR(th)) return PTR_ERR(th); -- cgit v1.2.3 From 29e15e83a99cdc13d0d38de558fbea641f8fdda8 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 25 Aug 2017 15:47:22 +0300 Subject: intel_th: Add global activate/deactivate callbacks for the glue layers A glue layer may want to install its own hooks into trace capture start and stop paths to apply workarounds. This adds optional callbacks. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/core.c | 26 ++++++++++++++++++++++---- drivers/hwtracing/intel_th/intel_th.h | 2 ++ 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index e915ab24f434..998e3e55073a 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -226,6 +226,7 @@ static int intel_th_output_activate(struct intel_th_device *thdev) { struct intel_th_driver *thdrv = to_intel_th_driver_or_null(thdev->dev.driver); + struct intel_th *th = to_intel_th(thdev); int ret = 0; if (!thdrv) @@ -236,15 +237,28 @@ static int intel_th_output_activate(struct intel_th_device *thdev) pm_runtime_get_sync(&thdev->dev); + if (th->activate) + ret = th->activate(th); + if (ret) + goto fail_put; + if (thdrv->activate) ret = thdrv->activate(thdev); else intel_th_trace_enable(thdev); - if (ret) { - pm_runtime_put(&thdev->dev); - module_put(thdrv->driver.owner); - } + if (ret) + goto fail_deactivate; + + return 0; + +fail_deactivate: + if (th->deactivate) + th->deactivate(th); + +fail_put: + pm_runtime_put(&thdev->dev); + module_put(thdrv->driver.owner); return ret; } @@ -253,6 +267,7 @@ static void intel_th_output_deactivate(struct intel_th_device *thdev) { struct intel_th_driver *thdrv = to_intel_th_driver_or_null(thdev->dev.driver); + struct intel_th *th = to_intel_th(thdev); if (!thdrv) return; @@ -262,6 +277,9 @@ static void intel_th_output_deactivate(struct intel_th_device *thdev) else intel_th_trace_disable(thdev); + if (th->deactivate) + th->deactivate(th); + pm_runtime_put(&thdev->dev); module_put(thdrv->driver.owner); } diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index 68244602ca29..78a4fb28b135 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -263,6 +263,8 @@ struct intel_th { struct intel_th_drvdata *drvdata; struct resource *resource; + int (*activate)(struct intel_th *); + void (*deactivate)(struct intel_th *); unsigned int num_thdevs; unsigned int num_resources; int irq; -- cgit v1.2.3 From a0e7df335afd2a8a8a688251ffee375b58b6517c Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 24 Feb 2017 16:09:40 +0200 Subject: intel_th: Perform time resync on capture start On some devices (TH 2.x devices at the moment), the internal time counter is initially not synchronized to the global crystal clock, so the time stamps it produces will not be useful. In this case, the driver needs to force the time counter resync. This applies the workaround to relevant devices. Signed-off-by: Alexander Shishkin --- drivers/hwtracing/intel_th/core.c | 3 +- drivers/hwtracing/intel_th/gth.c | 23 ++++++++++---- drivers/hwtracing/intel_th/gth.h | 5 ++++ drivers/hwtracing/intel_th/intel_th.h | 4 +++ drivers/hwtracing/intel_th/pci.c | 56 +++++++++++++++++++++++++++++++++-- 5 files changed, 82 insertions(+), 9 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 998e3e55073a..1a023e30488c 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -436,8 +436,9 @@ static const struct intel_th_subdevice { .nres = 1, .res = { { + /* Handle TSCU from GTH driver */ .start = REG_GTH_OFFSET, - .end = REG_GTH_OFFSET + REG_GTH_LENGTH - 1, + .end = REG_TSCU_OFFSET + REG_TSCU_LENGTH - 1, .flags = IORESOURCE_MEM, }, }, diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c index 7d9d667fe017..018678ec3c13 100644 --- a/drivers/hwtracing/intel_th/gth.c +++ b/drivers/hwtracing/intel_th/gth.c @@ -285,16 +285,16 @@ gth_output_parm_get(struct gth_device *gth, int port, unsigned int parm) */ static int intel_th_gth_reset(struct gth_device *gth) { - u32 scratchpad; + u32 reg; int port, i; - scratchpad = ioread32(gth->base + REG_GTH_SCRPD0); - if (scratchpad & SCRPD_DEBUGGER_IN_USE) + reg = ioread32(gth->base + REG_GTH_SCRPD0); + if (reg & SCRPD_DEBUGGER_IN_USE) return -EBUSY; /* Always save/restore STH and TU registers in S0ix entry/exit */ - scratchpad |= SCRPD_STH_IS_ENABLED | SCRPD_TRIGGER_IS_ENABLED; - iowrite32(scratchpad, gth->base + REG_GTH_SCRPD0); + reg |= SCRPD_STH_IS_ENABLED | SCRPD_TRIGGER_IS_ENABLED; + iowrite32(reg, gth->base + REG_GTH_SCRPD0); /* output ports */ for (port = 0; port < 8; port++) { @@ -512,6 +512,15 @@ static void intel_th_gth_disable(struct intel_th_device *thdev, iowrite32(reg, gth->base + REG_GTH_SCRPD0); } +static void gth_tscu_resync(struct gth_device *gth) +{ + u32 reg; + + reg = ioread32(gth->base + REG_TSCU_TSUCTRL); + reg &= ~TSUCTRL_CTCRESYNC; + iowrite32(reg, gth->base + REG_TSCU_TSUCTRL); +} + /** * intel_th_gth_enable() - enable tracing to an output device * @thdev: GTH device @@ -524,6 +533,7 @@ static void intel_th_gth_enable(struct intel_th_device *thdev, struct intel_th_output *output) { struct gth_device *gth = dev_get_drvdata(&thdev->dev); + struct intel_th *th = to_intel_th(thdev); u32 scr = 0xfc0000, scrpd; int master; @@ -539,6 +549,9 @@ static void intel_th_gth_enable(struct intel_th_device *thdev, output->active = true; spin_unlock(>h->gth_lock); + if (INTEL_TH_CAP(th, tscu_enable)) + gth_tscu_resync(gth); + scrpd = ioread32(gth->base + REG_GTH_SCRPD0); scrpd |= output->scratchpad; iowrite32(scrpd, gth->base + REG_GTH_SCRPD0); diff --git a/drivers/hwtracing/intel_th/gth.h b/drivers/hwtracing/intel_th/gth.h index 56f0d2620577..f3d234251a12 100644 --- a/drivers/hwtracing/intel_th/gth.h +++ b/drivers/hwtracing/intel_th/gth.h @@ -55,9 +55,14 @@ enum { REG_GTH_SCRPD1 = 0xe4, /* ScratchPad[1] */ REG_GTH_SCRPD2 = 0xe8, /* ScratchPad[2] */ REG_GTH_SCRPD3 = 0xec, /* ScratchPad[3] */ + REG_TSCU_TSUCTRL = 0x2000, /* TSCU control register */ + REG_TSCU_TSCUSTAT = 0x2004, /* TSCU status register */ }; /* waiting for Pipeline Empty bit(s) to assert for GTH */ #define GTH_PLE_WAITLOOP_DEPTH 10000 +#define TSUCTRL_CTCRESYNC BIT(0) +#define TSCUSTAT_CTCSYNCING BIT(1) + #endif /* __INTEL_TH_GTH_H__ */ diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index 78a4fb28b135..99ad563fc40d 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -298,6 +298,10 @@ enum { REG_GTH_OFFSET = 0x0000, REG_GTH_LENGTH = 0x2000, + /* Timestamp counter unit (TSCU) */ + REG_TSCU_OFFSET = 0x2000, + REG_TSCU_LENGTH = 0x1000, + /* Software Trace Hub (STH) [0x4000..0x4fff] */ REG_STH_OFFSET = 0x4000, REG_STH_LENGTH = 0x2000, diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index aed6d594991e..bc9cebc30526 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -27,6 +27,49 @@ #define BAR_MASK (BIT(TH_MMIO_CONFIG) | BIT(TH_MMIO_SW)) +#define PCI_REG_NPKDSC 0x80 +#define NPKDSC_TSACT BIT(5) + +static int intel_th_pci_activate(struct intel_th *th) +{ + struct pci_dev *pdev = to_pci_dev(th->dev); + u32 npkdsc; + int err; + + if (!INTEL_TH_CAP(th, tscu_enable)) + return 0; + + err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc); + if (!err) { + npkdsc |= NPKDSC_TSACT; + err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc); + } + + if (err) + dev_err(&pdev->dev, "failed to read NPKDSC register\n"); + + return err; +} + +static void intel_th_pci_deactivate(struct intel_th *th) +{ + struct pci_dev *pdev = to_pci_dev(th->dev); + u32 npkdsc; + int err; + + if (!INTEL_TH_CAP(th, tscu_enable)) + return; + + err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc); + if (!err) { + npkdsc |= NPKDSC_TSACT; + err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc); + } + + if (err) + dev_err(&pdev->dev, "failed to read NPKDSC register\n"); +} + static int intel_th_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -47,6 +90,9 @@ static int intel_th_pci_probe(struct pci_dev *pdev, if (IS_ERR(th)) return PTR_ERR(th); + th->activate = intel_th_pci_activate; + th->deactivate = intel_th_pci_deactivate; + pci_set_master(pdev); return 0; @@ -59,6 +105,10 @@ static void intel_th_pci_remove(struct pci_dev *pdev) intel_th_free(th); } +static const struct intel_th_drvdata intel_th_2x = { + .tscu_enable = 1, +}; + static const struct pci_device_id intel_th_pci_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26), @@ -96,17 +146,17 @@ static const struct pci_device_id intel_th_pci_id_table[] = { { /* Gemini Lake */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), - .driver_data = (kernel_ulong_t)0, + .driver_data = (kernel_ulong_t)&intel_th_2x, }, { /* Cannon Lake H */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326), - .driver_data = (kernel_ulong_t)0, + .driver_data = (kernel_ulong_t)&intel_th_2x, }, { /* Cannon Lake LP */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), - .driver_data = (kernel_ulong_t)0, + .driver_data = (kernel_ulong_t)&intel_th_2x, }, { 0 }, }; -- cgit v1.2.3 From cfd9f6306f105977bbe8ff793c4a4bc7a912f040 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Wed, 2 Aug 2017 10:21:55 -0600 Subject: coresight: Correct buffer lost increment Many conditions may cause synchronisation to be lost when updating the perf ring buffer but the end result is still the same: synchronisation is lost. As such there is no need to increment the lost count for each condition, just once will suffice. Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etb10.c | 10 +++++++--- drivers/hwtracing/coresight/coresight-tmc-etf.c | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index d5b96423e1a5..d9c233135d6d 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -353,6 +353,7 @@ static void etb_update_buffer(struct coresight_device *csdev, struct perf_output_handle *handle, void *sink_config) { + bool lost = false; int i, cur; u8 *buf_ptr; u32 read_ptr, write_ptr, capacity; @@ -384,7 +385,7 @@ static void etb_update_buffer(struct coresight_device *csdev, (unsigned long)write_ptr); write_ptr &= ~(ETB_FRAME_SIZE_WORDS - 1); - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; } /* @@ -395,7 +396,7 @@ static void etb_update_buffer(struct coresight_device *csdev, */ status = readl_relaxed(drvdata->base + ETB_STATUS_REG); if (status & ETB_STATUS_RAM_FULL) { - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; to_read = capacity; read_ptr = write_ptr; } else { @@ -428,9 +429,12 @@ static void etb_update_buffer(struct coresight_device *csdev, if (read_ptr > (drvdata->buffer_depth - 1)) read_ptr -= drvdata->buffer_depth; /* let the decoder know we've skipped ahead */ - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; } + if (lost) + perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + /* finally tell HW where we want to start reading from */ writel_relaxed(read_ptr, drvdata->base + ETB_RAM_READ_POINTER); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index e3b9fb82eb8d..2e0fb5b9372c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -369,6 +369,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, struct perf_output_handle *handle, void *sink_config) { + bool lost = false; int i, cur; u32 *buf_ptr; u32 read_ptr, write_ptr; @@ -397,7 +398,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, */ status = readl_relaxed(drvdata->base + TMC_STS); if (status & TMC_STS_FULL) { - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; to_read = drvdata->size; } else { to_read = CIRC_CNT(write_ptr, read_ptr, drvdata->size); @@ -442,9 +443,12 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, read_ptr -= drvdata->size; /* Tell the HW */ writel_relaxed(read_ptr, drvdata->base + TMC_RRP); - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; } + if (lost) + perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + cur = buf->cur; offset = buf->offset; -- cgit v1.2.3 From 4f871a9f0f6fbb8ab023cca1f0099bf152a5d618 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Wed, 2 Aug 2017 10:21:56 -0600 Subject: coresight: etb10: Remove useless conversion to LE Internal CoreSight components are rendering trace data in little-endian format. As such there is no need to convert the data once more, hence removing the extra step. Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etb10.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index d9c233135d6d..50f4846e6271 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -233,10 +233,8 @@ static void etb_dump_hw(struct etb_drvdata *drvdata) for (i = 0; i < depth; i++) { read_data = readl_relaxed(drvdata->base + ETB_RAM_READ_DATA_REG); - *buf_ptr++ = read_data >> 0; - *buf_ptr++ = read_data >> 8; - *buf_ptr++ = read_data >> 16; - *buf_ptr++ = read_data >> 24; + *(u32 *)buf_ptr = read_data; + buf_ptr += 4; } if (frame_off) { @@ -444,10 +442,8 @@ static void etb_update_buffer(struct coresight_device *csdev, buf_ptr = buf->data_pages[cur] + offset; read_data = readl_relaxed(drvdata->base + ETB_RAM_READ_DATA_REG); - *buf_ptr++ = read_data >> 0; - *buf_ptr++ = read_data >> 8; - *buf_ptr++ = read_data >> 16; - *buf_ptr++ = read_data >> 24; + *(u32 *)buf_ptr = read_data; + buf_ptr += 4; offset += 4; if (offset >= PAGE_SIZE) { -- cgit v1.2.3 From 0c3fc4d5fa26092853278145aca9b21fa52a3e93 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Wed, 2 Aug 2017 10:21:57 -0600 Subject: coresight: Add barrier packet for synchronisation When a buffer overflow happens the synchronisation patckets usually present at the beginning of the buffer are lost, a situation that prevents the decoder from knowing the context of the traces being decoded. This patch adds a barrier packet to be used by sink IPs when a buffer overflow condition is detected. These barrier packets are then used by the decoding library as markers to force re-synchronisation. Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etb10.c | 22 +++++++++++++++++++-- drivers/hwtracing/coresight/coresight-priv.h | 2 ++ drivers/hwtracing/coresight/coresight-tmc-etf.c | 26 ++++++++++++++++++++++++- drivers/hwtracing/coresight/coresight-tmc-etr.c | 12 ++++++++++++ drivers/hwtracing/coresight/coresight.c | 8 ++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 50f4846e6271..42360306f049 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -200,8 +200,10 @@ static void etb_disable_hw(struct etb_drvdata *drvdata) static void etb_dump_hw(struct etb_drvdata *drvdata) { + bool lost = false; int i; u8 *buf_ptr; + const u32 *barrier; u32 read_data, depth; u32 read_ptr, write_ptr; u32 frame_off, frame_endoff; @@ -223,16 +225,24 @@ static void etb_dump_hw(struct etb_drvdata *drvdata) } if ((readl_relaxed(drvdata->base + ETB_STATUS_REG) - & ETB_STATUS_RAM_FULL) == 0) + & ETB_STATUS_RAM_FULL) == 0) { writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER); - else + } else { writel_relaxed(write_ptr, drvdata->base + ETB_RAM_READ_POINTER); + lost = true; + } depth = drvdata->buffer_depth; buf_ptr = drvdata->buf; + barrier = barrier_pkt; for (i = 0; i < depth; i++) { read_data = readl_relaxed(drvdata->base + ETB_RAM_READ_DATA_REG); + if (lost && *barrier) { + read_data = *barrier; + barrier++; + } + *(u32 *)buf_ptr = read_data; buf_ptr += 4; } @@ -354,6 +364,7 @@ static void etb_update_buffer(struct coresight_device *csdev, bool lost = false; int i, cur; u8 *buf_ptr; + const u32 *barrier; u32 read_ptr, write_ptr, capacity; u32 status, read_data, to_read; unsigned long offset; @@ -438,10 +449,17 @@ static void etb_update_buffer(struct coresight_device *csdev, cur = buf->cur; offset = buf->offset; + barrier = barrier_pkt; + for (i = 0; i < to_read; i += 4) { buf_ptr = buf->data_pages[cur] + offset; read_data = readl_relaxed(drvdata->base + ETB_RAM_READ_DATA_REG); + if (lost && *barrier) { + read_data = *barrier; + barrier++; + } + *(u32 *)buf_ptr = read_data; buf_ptr += 4; diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 5f662d82052c..3e25b1dd1a1a 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -56,6 +56,8 @@ static ssize_t name##_show(struct device *_dev, \ } \ static DEVICE_ATTR_RO(name) +extern const u32 barrier_pkt[5]; + enum etm_addr_type { ETM_ADDR_TYPE_NONE, ETM_ADDR_TYPE_SINGLE, diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index 2e0fb5b9372c..d189b28bd5c4 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -43,17 +43,34 @@ static void tmc_etb_enable_hw(struct tmc_drvdata *drvdata) static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata) { + bool lost = false; char *bufp; - u32 read_data; + const u32 *barrier; + u32 read_data, status; int i; + /* + * Get a hold of the status register and see if a wrap around + * has occurred. + */ + status = readl_relaxed(drvdata->base + TMC_STS); + if (status & TMC_STS_FULL) + lost = true; + bufp = drvdata->buf; drvdata->len = 0; + barrier = barrier_pkt; while (1) { for (i = 0; i < drvdata->memwidth; i++) { read_data = readl_relaxed(drvdata->base + TMC_RRD); if (read_data == 0xFFFFFFFF) return; + + if (lost && *barrier) { + read_data = *barrier; + barrier++; + } + memcpy(bufp, &read_data, 4); bufp += 4; drvdata->len += 4; @@ -371,6 +388,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, { bool lost = false; int i, cur; + const u32 *barrier; u32 *buf_ptr; u32 read_ptr, write_ptr; u32 status, to_read; @@ -451,12 +469,18 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, cur = buf->cur; offset = buf->offset; + barrier = barrier_pkt; /* for every byte to read */ for (i = 0; i < to_read; i += 4) { buf_ptr = buf->data_pages[cur] + offset; *buf_ptr = readl_relaxed(drvdata->base + TMC_RRD); + if (lost && *barrier) { + *buf_ptr = *barrier; + barrier++; + } + offset += 4; if (offset >= PAGE_SIZE) { offset = 0; diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 5d312699b3b9..b8fb981de7b6 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -59,6 +59,8 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata) { + const u32 *barrier; + u32 *temp; u32 rwp, val; rwp = readl_relaxed(drvdata->base + TMC_RWP); @@ -71,6 +73,16 @@ static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata) if (val & TMC_STS_FULL) { drvdata->buf = drvdata->vaddr + rwp - drvdata->paddr; drvdata->len = drvdata->size; + + barrier = barrier_pkt; + temp = (u32 *)drvdata->buf; + + while (*barrier) { + *temp = *barrier; + temp++; + barrier++; + } + } else { drvdata->buf = drvdata->vaddr; drvdata->len = rwp - drvdata->paddr; diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 6a0202b7384f..b8091bef21dc 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -53,6 +53,14 @@ static DEFINE_PER_CPU(struct list_head *, tracer_path); */ static struct list_head *stm_path; +/* + * When losing synchronisation a new barrier packet needs to be inserted at the + * beginning of the data collected in a buffer. That way the decoder knows that + * it needs to look for another sync sequence. + */ +const u32 barrier_pkt[5] = {0x7fffffff, 0x7fffffff, + 0x7fffffff, 0x7fffffff, 0x0}; + static int coresight_id_match(struct device *dev, void *data) { int trace_id, i_trace_id; -- cgit v1.2.3 From 1655a3d6f3174f359bc0bf25312fa4057dc81c72 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Wed, 2 Aug 2017 10:21:58 -0600 Subject: coresight: etb10: Move etb_disable_hw() outside of lock Function etb_disable_hw() is already taking care of unlocking and locking the coresight access register and as such doesn't need to be placed within the unlock/lock of function etb_update_buffer(). Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etb10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 42360306f049..d0d186575c5d 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -376,8 +376,8 @@ static void etb_update_buffer(struct coresight_device *csdev, capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS; - CS_UNLOCK(drvdata->base); etb_disable_hw(drvdata); + CS_UNLOCK(drvdata->base); /* unit is in words, not bytes */ read_ptr = readl_relaxed(drvdata->base + ETB_RAM_READ_POINTER); -- cgit v1.2.3 From af36103e48c0146d9af9403f0d994f30ca17a4d8 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Wed, 2 Aug 2017 10:21:59 -0600 Subject: coresight: etm3x: Set synchronisation frequencty to TRM default Register ETMSYNCFR holds the number of by that need to be generated before periodic synchronisation packets are inserted in the trace stream. By zeroing out the config structure, the current code effectively disable periodic synchronization. This patch simply initialise the recommended value for this register as specified in the technical reference manual. Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm3x.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 93ee8fc539be..9d8bd4e36b32 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -243,6 +243,8 @@ void etm_set_default(struct etm_config *config) } config->ctxid_mask = 0x0; + /* Setting default to 1024 as per TRM recommendation */ + config->sync_freq = 0x400; } void etm_config_trace_mode(struct etm_config *config) -- cgit v1.2.3 From 89f00a1ae596876412c9b74e1c96453e9702a0cc Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 2 Aug 2017 10:22:00 -0600 Subject: hwtracing: coresight: constify attribute_group structures. attribute_groups are not supposed to change at runtime. All functions working with attribute_groups provided by work with const attribute_group. So mark the non-const structs as const. File size before: text data bss dec hex filename 2573 288 296 3157 c55 coresight-etm-perf.o File size After adding 'const': text data bss dec hex filename 2613 224 296 3133 c3d coresight-etm-perf.o Signed-off-by: Arvind Yadav Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm-perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 8f546f59a3fd..ad01dfeb2d68 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -60,7 +60,7 @@ static struct attribute *etm_config_formats_attr[] = { NULL, }; -static struct attribute_group etm_pmu_format_group = { +static const struct attribute_group etm_pmu_format_group = { .name = "format", .attrs = etm_config_formats_attr, }; -- cgit v1.2.3 From b97971bee55dc45420e0fe352d0b4df6e74716d4 Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Wed, 2 Aug 2017 10:22:01 -0600 Subject: coresight: pmu: Adds return stack option to perf coresight pmu Return stack is a programmable option on some ETM and PTM hardware. Adds the option flags to enable this from the perf event command line. Signed-off-by: Mike Leach Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm-perf.c | 2 ++ include/linux/coresight-pmu.h | 1 + tools/include/linux/coresight-pmu.h | 1 + 3 files changed, 4 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index ad01dfeb2d68..8a0ad77574e7 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -53,10 +53,12 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_src); /* ETMv3.5/PTM's ETMCR is 'config' */ PMU_FORMAT_ATTR(cycacc, "config:" __stringify(ETM_OPT_CYCACC)); PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS)); +PMU_FORMAT_ATTR(retstack, "config:" __stringify(ETM_OPT_RETSTK)); static struct attribute *etm_config_formats_attr[] = { &format_attr_cycacc.attr, &format_attr_timestamp.attr, + &format_attr_retstack.attr, NULL, }; diff --git a/include/linux/coresight-pmu.h b/include/linux/coresight-pmu.h index 7d410260661b..45852c2cd096 100644 --- a/include/linux/coresight-pmu.h +++ b/include/linux/coresight-pmu.h @@ -24,6 +24,7 @@ /* ETMv3.5/PTM's ETMCR config bit */ #define ETM_OPT_CYCACC 12 #define ETM_OPT_TS 28 +#define ETM_OPT_RETSTK 29 static inline int coresight_get_trace_id(int cpu) { diff --git a/tools/include/linux/coresight-pmu.h b/tools/include/linux/coresight-pmu.h index 7d410260661b..45852c2cd096 100644 --- a/tools/include/linux/coresight-pmu.h +++ b/tools/include/linux/coresight-pmu.h @@ -24,6 +24,7 @@ /* ETMv3.5/PTM's ETMCR config bit */ #define ETM_OPT_CYCACC 12 #define ETM_OPT_TS 28 +#define ETM_OPT_RETSTK 29 static inline int coresight_get_trace_id(int cpu) { -- cgit v1.2.3 From 557587bede858929eef14c6c2447fe140161bf5a Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Wed, 2 Aug 2017 10:22:02 -0600 Subject: coresight: ptm: Adds trace return stack option programming for PTM. Adds handling to program the return stack option into PTM hardware if specified in the perf command line. If option is not supported by the hardware then it will be ignored. This allows capture to move between core/ETM combinations that have the hardware support to those that do not. Signed-off-by: Mike Leach Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm.h | 1 + drivers/hwtracing/coresight/coresight-etm3x.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h index ad063d7444e1..70b0a248c321 100644 --- a/drivers/hwtracing/coresight/coresight-etm.h +++ b/drivers/hwtracing/coresight/coresight-etm.h @@ -106,6 +106,7 @@ #define ETMTECR1_START_STOP BIT(25) /* ETMCCER - 0x1E8 */ #define ETMCCER_TIMESTAMP BIT(22) +#define ETMCCER_RETSTACK BIT(23) #define ETM_MODE_EXCLUDE BIT(0) #define ETM_MODE_CYCACC BIT(1) diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 9d8bd4e36b32..9c010eb9497f 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -310,7 +310,9 @@ void etm_config_trace_mode(struct etm_config *config) config->addr_type[1] = ETM_ADDR_TYPE_RANGE; } -#define ETM3X_SUPPORTED_OPTIONS (ETMCR_CYC_ACC | ETMCR_TIMESTAMP_EN) +#define ETM3X_SUPPORTED_OPTIONS (ETMCR_CYC_ACC | \ + ETMCR_TIMESTAMP_EN | \ + ETMCR_RETURN_STACK) static int etm_parse_event_config(struct etm_drvdata *drvdata, struct perf_event *event) @@ -341,14 +343,24 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata, etm_config_trace_mode(config); /* - * At this time only cycle accurate and timestamp options are - * available. + * At this time only cycle accurate, return stack and timestamp + * options are available. */ if (attr->config & ~ETM3X_SUPPORTED_OPTIONS) return -EINVAL; config->ctrl = attr->config; + /* + * Possible to have cores with PTM (supports ret stack) and ETM + * (never has ret stack) on the same SoC. So if we have a request + * for return stack that can't be honoured on this core then + * clear the bit - trace will still continue normally + */ + if ((config->ctrl & ETMCR_RETURN_STACK) && + !(drvdata->etmccer & ETMCCER_RETSTACK)) + config->ctrl &= ~ETMCR_RETURN_STACK; + return 0; } -- cgit v1.2.3 From 27b8f6673a53a63531922bd4c96623c2b8299cc2 Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Wed, 2 Aug 2017 10:22:03 -0600 Subject: coresight: etm4x: Adds trace return stack option programming for ETMv4. Adds handling to program the return stack option into ETMv4 hardware if specified in the perf command line. If option is not supported by the hardware then it will be ignored. This allows capture to move between core/ETM combinations that have the hardware support to those that do not. Signed-off-by: Mike Leach Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm4x.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 532adc9dd32a..ac77b4c973d8 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -224,6 +224,10 @@ static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, if (attr->config & BIT(ETM_OPT_TS)) /* bit[11], Global timestamp tracing bit */ config->cfg |= BIT(11); + /* return stack - enable if selected and supported */ + if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack) + /* bit[12], Return stack enable bit */ + config->cfg |= BIT(12); out: return ret; -- cgit v1.2.3 From 1c8859848dbb07c96a0d31bbbf55b2d0b86e7a3b Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:04 -0600 Subject: coresight replicator: Cleanup programmable replicator naming The Linux coresight drivers define the programmable ATB replicator as Qualcomm replicator, while this is designed by ARM. This can cause confusion to a user selecting the driver. Cleanup all references to make it explicitly clear. This patch : 1) Replace the compatible string for the replicator : qcom,coresight-replicator1x => arm,coresight-dynamic-replicator 2) Changes the Kconfig symbol (since this is not part of any defconfigs) CORESIGHT_QCOM_REPLICATOR => CORESIGHT_DYNAMIC_REPLICATOR 3) Improves the help message in the Kconfig. 4) Changes the name of the driver and the file : coresight-replicator-qcom => coresight-dynamic-replicator Cc: Pratik Patel Cc: Ivan T. Ivanov Cc: Mathieu Poirier Cc: devicetree@vger.kernel.org Cc: Mark Rutland Acked-by: Rob Herring Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/arm/coresight.txt | 4 +- drivers/hwtracing/coresight/Kconfig | 10 +- drivers/hwtracing/coresight/Makefile | 2 +- .../coresight/coresight-dynamic-replicator.c | 194 ++++++++++++++++++++ .../coresight/coresight-replicator-qcom.c | 196 --------------------- 5 files changed, 202 insertions(+), 204 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-dynamic-replicator.c delete mode 100644 drivers/hwtracing/coresight/coresight-replicator-qcom.c (limited to 'drivers/hwtracing') diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index fcbae6a5e6c1..15ac8e8dcfdf 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -34,8 +34,8 @@ its hardware characteristcs. - Embedded Trace Macrocell (version 4.x): "arm,coresight-etm4x", "arm,primecell"; - - Qualcomm Configurable Replicator (version 1.x): - "qcom,coresight-replicator1x", "arm,primecell"; + - Coresight programmable Replicator : + "arm,coresight-dynamic-replicator", "arm,primecell"; - System Trace Macrocell: "arm,coresight-stm", "arm,primecell"; [1] diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig index 8d55d6d79015..ef9cb3c164e1 100644 --- a/drivers/hwtracing/coresight/Kconfig +++ b/drivers/hwtracing/coresight/Kconfig @@ -70,13 +70,13 @@ config CORESIGHT_SOURCE_ETM4X for instruction level tracing. Depending on the implemented version data tracing may also be available. -config CORESIGHT_QCOM_REPLICATOR - bool "Qualcomm CoreSight Replicator driver" +config CORESIGHT_DYNAMIC_REPLICATOR + bool "CoreSight Programmable Replicator driver" depends on CORESIGHT_LINKS_AND_SINKS help - This enables support for Qualcomm CoreSight link driver. The - programmable ATB replicator sends the ATB trace stream from the - ETB/ETF to the TPIUi and ETR. + This enables support for dynamic CoreSight replicator link driver. + The programmable ATB replicator allows independent filtering of the + trace data based on the traceid. config CORESIGHT_STM bool "CoreSight System Trace Macrocell driver" diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index 433d59025eb6..5bae90ce794d 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -14,6 +14,6 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o \ coresight-etm3x-sysfs.o obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \ coresight-etm4x-sysfs.o -obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o +obj-$(CONFIG_CORESIGHT_DYNAMIC_REPLICATOR) += coresight-dynamic-replicator.o obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o diff --git a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c new file mode 100644 index 000000000000..c6900f2301de --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-priv.h" + +#define REPLICATOR_IDFILTER0 0x000 +#define REPLICATOR_IDFILTER1 0x004 + +/** + * struct replicator_state - specifics associated to a replicator component + * @base: memory mapped base address for this component. + * @dev: the device entity associated with this component + * @atclk: optional clock for the core parts of the replicator. + * @csdev: component vitals needed by the framework + */ +struct replicator_state { + void __iomem *base; + struct device *dev; + struct clk *atclk; + struct coresight_device *csdev; +}; + +static int replicator_enable(struct coresight_device *csdev, int inport, + int outport) +{ + struct replicator_state *drvdata = dev_get_drvdata(csdev->dev.parent); + + CS_UNLOCK(drvdata->base); + + /* + * Ensure that the other port is disabled + * 0x00 - passing through the replicator unimpeded + * 0xff - disable (or impede) the flow of ATB data + */ + if (outport == 0) { + writel_relaxed(0x00, drvdata->base + REPLICATOR_IDFILTER0); + writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER1); + } else { + writel_relaxed(0x00, drvdata->base + REPLICATOR_IDFILTER1); + writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER0); + } + + CS_LOCK(drvdata->base); + + dev_info(drvdata->dev, "REPLICATOR enabled\n"); + return 0; +} + +static void replicator_disable(struct coresight_device *csdev, int inport, + int outport) +{ + struct replicator_state *drvdata = dev_get_drvdata(csdev->dev.parent); + + CS_UNLOCK(drvdata->base); + + /* disable the flow of ATB data through port */ + if (outport == 0) + writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER0); + else + writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER1); + + CS_LOCK(drvdata->base); + + dev_info(drvdata->dev, "REPLICATOR disabled\n"); +} + +static const struct coresight_ops_link replicator_link_ops = { + .enable = replicator_enable, + .disable = replicator_disable, +}; + +static const struct coresight_ops replicator_cs_ops = { + .link_ops = &replicator_link_ops, +}; + +static int replicator_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret; + struct device *dev = &adev->dev; + struct resource *res = &adev->res; + struct coresight_platform_data *pdata = NULL; + struct replicator_state *drvdata; + struct coresight_desc desc = { 0 }; + struct device_node *np = adev->dev.of_node; + void __iomem *base; + + if (np) { + pdata = of_get_coresight_platform_data(dev, np); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + adev->dev.platform_data = pdata; + } + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &adev->dev; + drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ + if (!IS_ERR(drvdata->atclk)) { + ret = clk_prepare_enable(drvdata->atclk); + if (ret) + return ret; + } + + /* Validity for the resource is already checked by the AMBA core */ + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + drvdata->base = base; + dev_set_drvdata(dev, drvdata); + pm_runtime_put(&adev->dev); + + desc.type = CORESIGHT_DEV_TYPE_LINK; + desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT; + desc.ops = &replicator_cs_ops; + desc.pdata = adev->dev.platform_data; + desc.dev = &adev->dev; + drvdata->csdev = coresight_register(&desc); + if (IS_ERR(drvdata->csdev)) + return PTR_ERR(drvdata->csdev); + + return 0; +} + +#ifdef CONFIG_PM +static int replicator_runtime_suspend(struct device *dev) +{ + struct replicator_state *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR(drvdata->atclk)) + clk_disable_unprepare(drvdata->atclk); + + return 0; +} + +static int replicator_runtime_resume(struct device *dev) +{ + struct replicator_state *drvdata = dev_get_drvdata(dev); + + if (drvdata && !IS_ERR(drvdata->atclk)) + clk_prepare_enable(drvdata->atclk); + + return 0; +} +#endif + +static const struct dev_pm_ops replicator_dev_pm_ops = { + SET_RUNTIME_PM_OPS(replicator_runtime_suspend, + replicator_runtime_resume, + NULL) +}; + +static struct amba_id replicator_ids[] = { + { + .id = 0x0003b909, + .mask = 0x0003ffff, + }, + { 0, 0 }, +}; + +static struct amba_driver replicator_driver = { + .drv = { + .name = "coresight-dynamic-replicator", + .pm = &replicator_dev_pm_ops, + .suppress_bind_attrs = true, + }, + .probe = replicator_probe, + .id_table = replicator_ids, +}; +builtin_amba_driver(replicator_driver); diff --git a/drivers/hwtracing/coresight/coresight-replicator-qcom.c b/drivers/hwtracing/coresight/coresight-replicator-qcom.c deleted file mode 100644 index 0a3d15f0b009..000000000000 --- a/drivers/hwtracing/coresight/coresight-replicator-qcom.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "coresight-priv.h" - -#define REPLICATOR_IDFILTER0 0x000 -#define REPLICATOR_IDFILTER1 0x004 - -/** - * struct replicator_state - specifics associated to a replicator component - * @base: memory mapped base address for this component. - * @dev: the device entity associated with this component - * @atclk: optional clock for the core parts of the replicator. - * @csdev: component vitals needed by the framework - */ -struct replicator_state { - void __iomem *base; - struct device *dev; - struct clk *atclk; - struct coresight_device *csdev; -}; - -static int replicator_enable(struct coresight_device *csdev, int inport, - int outport) -{ - struct replicator_state *drvdata = dev_get_drvdata(csdev->dev.parent); - - CS_UNLOCK(drvdata->base); - - /* - * Ensure that the other port is disabled - * 0x00 - passing through the replicator unimpeded - * 0xff - disable (or impede) the flow of ATB data - */ - if (outport == 0) { - writel_relaxed(0x00, drvdata->base + REPLICATOR_IDFILTER0); - writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER1); - } else { - writel_relaxed(0x00, drvdata->base + REPLICATOR_IDFILTER1); - writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER0); - } - - CS_LOCK(drvdata->base); - - dev_info(drvdata->dev, "REPLICATOR enabled\n"); - return 0; -} - -static void replicator_disable(struct coresight_device *csdev, int inport, - int outport) -{ - struct replicator_state *drvdata = dev_get_drvdata(csdev->dev.parent); - - CS_UNLOCK(drvdata->base); - - /* disable the flow of ATB data through port */ - if (outport == 0) - writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER0); - else - writel_relaxed(0xff, drvdata->base + REPLICATOR_IDFILTER1); - - CS_LOCK(drvdata->base); - - dev_info(drvdata->dev, "REPLICATOR disabled\n"); -} - -static const struct coresight_ops_link replicator_link_ops = { - .enable = replicator_enable, - .disable = replicator_disable, -}; - -static const struct coresight_ops replicator_cs_ops = { - .link_ops = &replicator_link_ops, -}; - -static int replicator_probe(struct amba_device *adev, const struct amba_id *id) -{ - int ret; - struct device *dev = &adev->dev; - struct resource *res = &adev->res; - struct coresight_platform_data *pdata = NULL; - struct replicator_state *drvdata; - struct coresight_desc desc = { 0 }; - struct device_node *np = adev->dev.of_node; - void __iomem *base; - - if (np) { - pdata = of_get_coresight_platform_data(dev, np); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - adev->dev.platform_data = pdata; - } - - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; - - drvdata->dev = &adev->dev; - drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ - if (!IS_ERR(drvdata->atclk)) { - ret = clk_prepare_enable(drvdata->atclk); - if (ret) - return ret; - } - - /* Validity for the resource is already checked by the AMBA core */ - base = devm_ioremap_resource(dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - drvdata->base = base; - dev_set_drvdata(dev, drvdata); - pm_runtime_put(&adev->dev); - - desc.type = CORESIGHT_DEV_TYPE_LINK; - desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT; - desc.ops = &replicator_cs_ops; - desc.pdata = adev->dev.platform_data; - desc.dev = &adev->dev; - drvdata->csdev = coresight_register(&desc); - if (IS_ERR(drvdata->csdev)) - return PTR_ERR(drvdata->csdev); - - dev_info(dev, "%s initialized\n", (char *)id->data); - return 0; -} - -#ifdef CONFIG_PM -static int replicator_runtime_suspend(struct device *dev) -{ - struct replicator_state *drvdata = dev_get_drvdata(dev); - - if (drvdata && !IS_ERR(drvdata->atclk)) - clk_disable_unprepare(drvdata->atclk); - - return 0; -} - -static int replicator_runtime_resume(struct device *dev) -{ - struct replicator_state *drvdata = dev_get_drvdata(dev); - - if (drvdata && !IS_ERR(drvdata->atclk)) - clk_prepare_enable(drvdata->atclk); - - return 0; -} -#endif - -static const struct dev_pm_ops replicator_dev_pm_ops = { - SET_RUNTIME_PM_OPS(replicator_runtime_suspend, - replicator_runtime_resume, - NULL) -}; - -static struct amba_id replicator_ids[] = { - { - .id = 0x0003b909, - .mask = 0x0003ffff, - .data = "REPLICATOR 1.0", - }, - { 0, 0 }, -}; - -static struct amba_driver replicator_driver = { - .drv = { - .name = "coresight-replicator-qcom", - .pm = &replicator_dev_pm_ops, - .suppress_bind_attrs = true, - }, - .probe = replicator_probe, - .id_table = replicator_ids, -}; -builtin_amba_driver(replicator_driver); -- cgit v1.2.3 From b4523c87c09eb6e4fd56ba876ee956e6330cf9fe Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:05 -0600 Subject: coresight: Add support for reading 64bit registers Add support for reading a lower and upper 32bits of a register as a single 64bit register. Also add simplified macros for direct register accesses. Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-priv.h | 29 +++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 3e25b1dd1a1a..9fdebb773e71 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -39,23 +39,31 @@ #define ETM_MODE_EXCL_USER BIT(31) typedef u32 (*coresight_read_fn)(const struct device *, u32 offset); -#define coresight_simple_func(type, func, name, offset) \ +#define __coresight_simple_func(type, func, name, lo_off, hi_off) \ static ssize_t name##_show(struct device *_dev, \ struct device_attribute *attr, char *buf) \ { \ type *drvdata = dev_get_drvdata(_dev->parent); \ coresight_read_fn fn = func; \ - u32 val; \ + u64 val; \ pm_runtime_get_sync(_dev->parent); \ if (fn) \ - val = fn(_dev->parent, offset); \ + val = (u64)fn(_dev->parent, lo_off); \ else \ - val = readl_relaxed(drvdata->base + offset); \ + val = coresight_read_reg_pair(drvdata->base, \ + lo_off, hi_off); \ pm_runtime_put_sync(_dev->parent); \ - return scnprintf(buf, PAGE_SIZE, "0x%x\n", val); \ + return scnprintf(buf, PAGE_SIZE, "0x%llx\n", val); \ } \ static DEVICE_ATTR_RO(name) +#define coresight_simple_func(type, func, name, offset) \ + __coresight_simple_func(type, func, name, offset, -1) +#define coresight_simple_reg32(type, name, offset) \ + __coresight_simple_func(type, NULL, name, offset, -1) +#define coresight_simple_reg64(type, name, lo_off, hi_off) \ + __coresight_simple_func(type, NULL, name, lo_off, hi_off) + extern const u32 barrier_pkt[5]; enum etm_addr_type { @@ -108,6 +116,17 @@ static inline void CS_UNLOCK(void __iomem *addr) } while (0); } +static inline u64 +coresight_read_reg_pair(void __iomem *addr, s32 lo_offset, s32 hi_offset) +{ + u64 val; + + val = readl_relaxed(addr + lo_offset); + val |= (hi_offset < 0) ? 0 : + (u64)readl_relaxed(addr + hi_offset) << 32; + return val; +} + void coresight_disable_path(struct list_head *path); int coresight_enable_path(struct list_head *path, u32 mode); struct coresight_device *coresight_get_sink(struct list_head *path); -- cgit v1.2.3 From 47675f6a46ff3106f86f97907f59542e3c5aa289 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:06 -0600 Subject: coresight: Use the new helper for defining registers Use the new helpers for exposing coresight component registers, choosing the 64bit variants for appropriate registers. Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etb10.c | 22 ++++++++-------- .../hwtracing/coresight/coresight-etm3x-sysfs.c | 26 +++++++++---------- .../hwtracing/coresight/coresight-etm4x-sysfs.c | 24 ++++++++--------- drivers/hwtracing/coresight/coresight-stm.c | 30 +++++++++++----------- drivers/hwtracing/coresight/coresight-tmc.c | 30 ++++++++++++---------- 5 files changed, 67 insertions(+), 65 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index d0d186575c5d..05625e3a584e 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -575,17 +575,17 @@ static const struct file_operations etb_fops = { .llseek = no_llseek, }; -#define coresight_etb10_simple_func(name, offset) \ - coresight_simple_func(struct etb_drvdata, NULL, name, offset) - -coresight_etb10_simple_func(rdp, ETB_RAM_DEPTH_REG); -coresight_etb10_simple_func(sts, ETB_STATUS_REG); -coresight_etb10_simple_func(rrp, ETB_RAM_READ_POINTER); -coresight_etb10_simple_func(rwp, ETB_RAM_WRITE_POINTER); -coresight_etb10_simple_func(trg, ETB_TRG); -coresight_etb10_simple_func(ctl, ETB_CTL_REG); -coresight_etb10_simple_func(ffsr, ETB_FFSR); -coresight_etb10_simple_func(ffcr, ETB_FFCR); +#define coresight_etb10_reg(name, offset) \ + coresight_simple_reg32(struct etb_drvdata, name, offset) + +coresight_etb10_reg(rdp, ETB_RAM_DEPTH_REG); +coresight_etb10_reg(sts, ETB_STATUS_REG); +coresight_etb10_reg(rrp, ETB_RAM_READ_POINTER); +coresight_etb10_reg(rwp, ETB_RAM_WRITE_POINTER); +coresight_etb10_reg(trg, ETB_TRG); +coresight_etb10_reg(ctl, ETB_CTL_REG); +coresight_etb10_reg(ffsr, ETB_FFSR); +coresight_etb10_reg(ffcr, ETB_FFCR); static struct attribute *coresight_etb_mgmt_attrs[] = { &dev_attr_rdp.attr, diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c index ca98ad13bb8c..6e547ec6fead 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c @@ -1232,19 +1232,19 @@ static struct attribute *coresight_etm_attrs[] = { NULL, }; -#define coresight_etm3x_simple_func(name, offset) \ - coresight_simple_func(struct etm_drvdata, NULL, name, offset) - -coresight_etm3x_simple_func(etmccr, ETMCCR); -coresight_etm3x_simple_func(etmccer, ETMCCER); -coresight_etm3x_simple_func(etmscr, ETMSCR); -coresight_etm3x_simple_func(etmidr, ETMIDR); -coresight_etm3x_simple_func(etmcr, ETMCR); -coresight_etm3x_simple_func(etmtraceidr, ETMTRACEIDR); -coresight_etm3x_simple_func(etmteevr, ETMTEEVR); -coresight_etm3x_simple_func(etmtssvr, ETMTSSCR); -coresight_etm3x_simple_func(etmtecr1, ETMTECR1); -coresight_etm3x_simple_func(etmtecr2, ETMTECR2); +#define coresight_etm3x_reg(name, offset) \ + coresight_simple_reg32(struct etm_drvdata, name, offset) + +coresight_etm3x_reg(etmccr, ETMCCR); +coresight_etm3x_reg(etmccer, ETMCCER); +coresight_etm3x_reg(etmscr, ETMSCR); +coresight_etm3x_reg(etmidr, ETMIDR); +coresight_etm3x_reg(etmcr, ETMCR); +coresight_etm3x_reg(etmtraceidr, ETMTRACEIDR); +coresight_etm3x_reg(etmteevr, ETMTEEVR); +coresight_etm3x_reg(etmtssvr, ETMTSSCR); +coresight_etm3x_reg(etmtecr1, ETMTECR1); +coresight_etm3x_reg(etmtecr2, ETMTECR2); static struct attribute *coresight_etm_mgmt_attrs[] = { &dev_attr_etmccr.attr, diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index b9b1e9c8f4c4..4e6eab53e34e 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -2066,23 +2066,23 @@ static u32 etmv4_cross_read(const struct device *dev, u32 offset) return reg.data; } -#define coresight_etm4x_simple_func(name, offset) \ - coresight_simple_func(struct etmv4_drvdata, NULL, name, offset) +#define coresight_etm4x_reg(name, offset) \ + coresight_simple_reg32(struct etmv4_drvdata, name, offset) #define coresight_etm4x_cross_read(name, offset) \ coresight_simple_func(struct etmv4_drvdata, etmv4_cross_read, \ name, offset) -coresight_etm4x_simple_func(trcpdcr, TRCPDCR); -coresight_etm4x_simple_func(trcpdsr, TRCPDSR); -coresight_etm4x_simple_func(trclsr, TRCLSR); -coresight_etm4x_simple_func(trcauthstatus, TRCAUTHSTATUS); -coresight_etm4x_simple_func(trcdevid, TRCDEVID); -coresight_etm4x_simple_func(trcdevtype, TRCDEVTYPE); -coresight_etm4x_simple_func(trcpidr0, TRCPIDR0); -coresight_etm4x_simple_func(trcpidr1, TRCPIDR1); -coresight_etm4x_simple_func(trcpidr2, TRCPIDR2); -coresight_etm4x_simple_func(trcpidr3, TRCPIDR3); +coresight_etm4x_reg(trcpdcr, TRCPDCR); +coresight_etm4x_reg(trcpdsr, TRCPDSR); +coresight_etm4x_reg(trclsr, TRCLSR); +coresight_etm4x_reg(trcauthstatus, TRCAUTHSTATUS); +coresight_etm4x_reg(trcdevid, TRCDEVID); +coresight_etm4x_reg(trcdevtype, TRCDEVTYPE); +coresight_etm4x_reg(trcpidr0, TRCPIDR0); +coresight_etm4x_reg(trcpidr1, TRCPIDR1); +coresight_etm4x_reg(trcpidr2, TRCPIDR2); +coresight_etm4x_reg(trcpidr3, TRCPIDR3); coresight_etm4x_cross_read(trcoslsr, TRCOSLSR); coresight_etm4x_cross_read(trcconfig, TRCCONFIGR); coresight_etm4x_cross_read(trctraceid, TRCTRACEIDR); diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 93fc26f01bab..202ed7a909e1 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -635,21 +635,21 @@ static ssize_t traceid_store(struct device *dev, } static DEVICE_ATTR_RW(traceid); -#define coresight_stm_simple_func(name, offset) \ - coresight_simple_func(struct stm_drvdata, NULL, name, offset) - -coresight_stm_simple_func(tcsr, STMTCSR); -coresight_stm_simple_func(tsfreqr, STMTSFREQR); -coresight_stm_simple_func(syncr, STMSYNCR); -coresight_stm_simple_func(sper, STMSPER); -coresight_stm_simple_func(spter, STMSPTER); -coresight_stm_simple_func(privmaskr, STMPRIVMASKR); -coresight_stm_simple_func(spscr, STMSPSCR); -coresight_stm_simple_func(spmscr, STMSPMSCR); -coresight_stm_simple_func(spfeat1r, STMSPFEAT1R); -coresight_stm_simple_func(spfeat2r, STMSPFEAT2R); -coresight_stm_simple_func(spfeat3r, STMSPFEAT3R); -coresight_stm_simple_func(devid, CORESIGHT_DEVID); +#define coresight_stm_reg(name, offset) \ + coresight_simple_reg32(struct stm_drvdata, name, offset) + +coresight_stm_reg(tcsr, STMTCSR); +coresight_stm_reg(tsfreqr, STMTSFREQR); +coresight_stm_reg(syncr, STMSYNCR); +coresight_stm_reg(sper, STMSPER); +coresight_stm_reg(spter, STMSPTER); +coresight_stm_reg(privmaskr, STMPRIVMASKR); +coresight_stm_reg(spscr, STMSPSCR); +coresight_stm_reg(spmscr, STMSPMSCR); +coresight_stm_reg(spfeat1r, STMSPFEAT1R); +coresight_stm_reg(spfeat2r, STMSPFEAT2R); +coresight_stm_reg(spfeat3r, STMSPFEAT3R); +coresight_stm_reg(devid, CORESIGHT_DEVID); static struct attribute *coresight_stm_attrs[] = { &dev_attr_hwevent_enable.attr, diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 864488793f09..5abf711320f6 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -217,20 +217,22 @@ static enum tmc_mem_intf_width tmc_get_memwidth(u32 devid) return memwidth; } -#define coresight_tmc_simple_func(name, offset) \ - coresight_simple_func(struct tmc_drvdata, NULL, name, offset) - -coresight_tmc_simple_func(rsz, TMC_RSZ); -coresight_tmc_simple_func(sts, TMC_STS); -coresight_tmc_simple_func(rrp, TMC_RRP); -coresight_tmc_simple_func(rwp, TMC_RWP); -coresight_tmc_simple_func(trg, TMC_TRG); -coresight_tmc_simple_func(ctl, TMC_CTL); -coresight_tmc_simple_func(ffsr, TMC_FFSR); -coresight_tmc_simple_func(ffcr, TMC_FFCR); -coresight_tmc_simple_func(mode, TMC_MODE); -coresight_tmc_simple_func(pscr, TMC_PSCR); -coresight_tmc_simple_func(devid, CORESIGHT_DEVID); +#define coresight_tmc_reg(name, offset) \ + coresight_simple_reg32(struct tmc_drvdata, name, offset) +#define coresight_tmc_reg64(name, lo_off, hi_off) \ + coresight_simple_reg64(struct tmc_drvdata, name, lo_off, hi_off) + +coresight_tmc_reg(rsz, TMC_RSZ); +coresight_tmc_reg(sts, TMC_STS); +coresight_tmc_reg(trg, TMC_TRG); +coresight_tmc_reg(ctl, TMC_CTL); +coresight_tmc_reg(ffsr, TMC_FFSR); +coresight_tmc_reg(ffcr, TMC_FFCR); +coresight_tmc_reg(mode, TMC_MODE); +coresight_tmc_reg(pscr, TMC_PSCR); +coresight_tmc_reg(devid, CORESIGHT_DEVID); +coresight_tmc_reg64(rrp, TMC_RRP, TMC_RRPHI); +coresight_tmc_reg64(rwp, TMC_RWP, TMC_RWPHI); static struct attribute *coresight_tmc_mgmt_attrs[] = { &dev_attr_rsz.attr, -- cgit v1.2.3 From 6f6ab4fce56bbb0385d3d2d62d8c9f688618d5ac Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:07 -0600 Subject: coresight tmc: Add helpers for accessing 64bit registers Coresight TMC splits 64bit registers into a pair of 32bit registers (e.g DBA, RRP, RWP). Provide helpers to read/write to these registers. Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-priv.h | 8 ++++++++ drivers/hwtracing/coresight/coresight-tmc-etf.c | 8 ++++---- drivers/hwtracing/coresight/coresight-tmc-etr.c | 8 ++++---- drivers/hwtracing/coresight/coresight-tmc.h | 18 ++++++++++++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 9fdebb773e71..f1d0e21d8cab 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -127,6 +127,14 @@ coresight_read_reg_pair(void __iomem *addr, s32 lo_offset, s32 hi_offset) return val; } +static inline void coresight_write_reg_pair(void __iomem *addr, u64 val, + s32 lo_offset, s32 hi_offset) +{ + writel_relaxed((u32)val, addr + lo_offset); + if (hi_offset >= 0) + writel_relaxed((u32)(val >> 32), addr + hi_offset); +} + void coresight_disable_path(struct list_head *path); int coresight_enable_path(struct list_head *path, u32 mode); struct coresight_device *coresight_get_sink(struct list_head *path); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index d189b28bd5c4..e2513b786242 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -390,7 +390,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, int i, cur; const u32 *barrier; u32 *buf_ptr; - u32 read_ptr, write_ptr; + u64 read_ptr, write_ptr; u32 status, to_read; unsigned long offset; struct cs_buffers *buf = sink_config; @@ -407,8 +407,8 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, tmc_flush_and_stop(drvdata); - read_ptr = readl_relaxed(drvdata->base + TMC_RRP); - write_ptr = readl_relaxed(drvdata->base + TMC_RWP); + read_ptr = tmc_read_rrp(drvdata); + write_ptr = tmc_read_rwp(drvdata); /* * Get a hold of the status register and see if a wrap around @@ -460,7 +460,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, if (read_ptr > (drvdata->size - 1)) read_ptr -= drvdata->size; /* Tell the HW */ - writel_relaxed(read_ptr, drvdata->base + TMC_RRP); + tmc_write_rrp(drvdata, read_ptr); lost = true; } diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index b8fb981de7b6..9c39c899ebd5 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -44,9 +44,8 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) ~(TMC_AXICTL_PROT_CTL_B0 | TMC_AXICTL_PROT_CTL_B1)) | TMC_AXICTL_PROT_CTL_B1; writel_relaxed(axictl, drvdata->base + TMC_AXICTL); + tmc_write_dba(drvdata, drvdata->paddr); - writel_relaxed(drvdata->paddr, drvdata->base + TMC_DBALO); - writel_relaxed(0x0, drvdata->base + TMC_DBAHI); writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI | TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT | TMC_FFCR_TRIGON_TRIGIN, @@ -60,10 +59,11 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata) { const u32 *barrier; + u32 val; u32 *temp; - u32 rwp, val; + u64 rwp; - rwp = readl_relaxed(drvdata->base + TMC_RWP); + rwp = tmc_read_rwp(drvdata); val = readl_relaxed(drvdata->base + TMC_STS); /* diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 51c01851533e..c4ff23336e76 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -139,4 +139,22 @@ extern const struct coresight_ops tmc_etf_cs_ops; int tmc_read_prepare_etr(struct tmc_drvdata *drvdata); int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata); extern const struct coresight_ops tmc_etr_cs_ops; + + +#define TMC_REG_PAIR(name, lo_off, hi_off) \ +static inline u64 \ +tmc_read_##name(struct tmc_drvdata *drvdata) \ +{ \ + return coresight_read_reg_pair(drvdata->base, lo_off, hi_off); \ +} \ +static inline void \ +tmc_write_##name(struct tmc_drvdata *drvdata, u64 val) \ +{ \ + coresight_write_reg_pair(drvdata->base, val, lo_off, hi_off); \ +} + +TMC_REG_PAIR(rrp, TMC_RRP, TMC_RRPHI) +TMC_REG_PAIR(rwp, TMC_RWP, TMC_RWPHI) +TMC_REG_PAIR(dba, TMC_DBALO, TMC_DBAHI) + #endif -- cgit v1.2.3 From 2b4553399b5fee1306817284b54ea22b108ba9cf Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:08 -0600 Subject: coresight tmc: Expose DBA and AXICTL Expose DBALO,DBAHI and AXICTL registers Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 5abf711320f6..bd98b5101528 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -230,9 +230,11 @@ coresight_tmc_reg(ffsr, TMC_FFSR); coresight_tmc_reg(ffcr, TMC_FFCR); coresight_tmc_reg(mode, TMC_MODE); coresight_tmc_reg(pscr, TMC_PSCR); +coresight_tmc_reg(axictl, TMC_AXICTL); coresight_tmc_reg(devid, CORESIGHT_DEVID); coresight_tmc_reg64(rrp, TMC_RRP, TMC_RRPHI); coresight_tmc_reg64(rwp, TMC_RWP, TMC_RWPHI); +coresight_tmc_reg64(dba, TMC_DBALO, TMC_DBAHI); static struct attribute *coresight_tmc_mgmt_attrs[] = { &dev_attr_rsz.attr, @@ -246,6 +248,8 @@ static struct attribute *coresight_tmc_mgmt_attrs[] = { &dev_attr_mode.attr, &dev_attr_pscr.attr, &dev_attr_devid.attr, + &dev_attr_dba.attr, + &dev_attr_axictl.attr, NULL, }; -- cgit v1.2.3 From 79d29bb93bd846f71f617bc06a80444ba6ba08b5 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:09 -0600 Subject: coresight replicator: Expose replicator management registers Expose the idfilter* registers of the programmable replicator. Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- .../coresight/coresight-dynamic-replicator.c | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c index c6900f2301de..b00ea2d7d13f 100644 --- a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c +++ b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c @@ -95,6 +95,28 @@ static const struct coresight_ops replicator_cs_ops = { .link_ops = &replicator_link_ops, }; +#define coresight_replicator_reg(name, offset) \ + coresight_simple_reg32(struct replicator_state, name, offset) + +coresight_replicator_reg(idfilter0, REPLICATOR_IDFILTER0); +coresight_replicator_reg(idfilter1, REPLICATOR_IDFILTER1); + +static struct attribute *replicator_mgmt_attrs[] = { + &dev_attr_idfilter0.attr, + &dev_attr_idfilter1.attr, + NULL, +}; + +static const struct attribute_group replicator_mgmt_group = { + .attrs = replicator_mgmt_attrs, + .name = "mgmt", +}; + +static const struct attribute_group *replicator_groups[] = { + &replicator_mgmt_group, + NULL, +}; + static int replicator_probe(struct amba_device *adev, const struct amba_id *id) { int ret; @@ -139,6 +161,7 @@ static int replicator_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &replicator_cs_ops; desc.pdata = adev->dev.platform_data; desc.dev = &adev->dev; + desc.groups = replicator_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) return PTR_ERR(drvdata->csdev); -- cgit v1.2.3 From 99ac6f120986430993285e3e3f8ecf590d04ba2c Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:10 -0600 Subject: coresight tmc: Handle configuration types properly Coresight SoC 600 defines a new configuration for TMC, Embedded Trace Streamer (ETS), indicated by 0x3 in MODE:CONFIG_TYPE. This would break the existing driver which will treat anything other than ETR/ETB as an ETF. Fix the driver to check the configuration type properly and also add a warning if we encounter an unsupported configuration (ETS). Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index bd98b5101528..6adf74689a85 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -360,11 +360,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) desc.dev = dev; desc.groups = coresight_tmc_groups; - if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) { + switch (drvdata->config_type) { + case TMC_CONFIG_TYPE_ETB: desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &tmc_etb_cs_ops; - } else if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { + break; + case TMC_CONFIG_TYPE_ETR: desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &tmc_etr_cs_ops; @@ -375,10 +377,16 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); if (ret) goto out; - } else { + break; + case TMC_CONFIG_TYPE_ETF: desc.type = CORESIGHT_DEV_TYPE_LINKSINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO; desc.ops = &tmc_etf_cs_ops; + break; + default: + pr_err("%s: Unsupported TMC config\n", pdata->name); + ret = -EINVAL; + goto out; } drvdata->csdev = coresight_register(&desc); -- cgit v1.2.3 From 2884132ae8e4424c2d025deef48d937337e97db7 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:11 -0600 Subject: coresight tmc etr: Add capabilitiy information With new version of TMC ETR, there are differing set of features supported by the TMC. Add the capability of a given TMC ETR for making safer decisions at runtime. The device configuration register of the TMC (DEVID) lists some of the capabilities. So, we can detect some of them at probe. However, some of the features (or changes in behavior) are not advertised and we have to depend on the PID to infer the features. So we use a static description of the "unadvertised" capabilities attached to the PID. Combining both, the static and the dynamic capabilities, we maintain a bitmask of the available features which can be later checked to take appropriate actions. Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc.c | 20 +++++++++++++++----- drivers/hwtracing/coresight/coresight-tmc.h | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 6adf74689a85..0c99ef7b9b2b 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -299,6 +299,20 @@ const struct attribute_group *coresight_tmc_groups[] = { NULL, }; +/* Detect and initialise the capabilities of a TMC ETR */ +static int tmc_etr_setup_caps(struct tmc_drvdata *drvdata, + u32 devid, void *dev_caps) +{ + /* Set the unadvertised capabilities */ + tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps); + + /* + * ETR configuration uses a 40-bit AXI master in place of + * the embedded SRAM of ETB/ETF. + */ + return dma_set_mask_and_coherent(drvdata->dev, DMA_BIT_MASK(40)); +} + static int tmc_probe(struct amba_device *adev, const struct amba_id *id) { int ret = 0; @@ -370,11 +384,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) desc.type = CORESIGHT_DEV_TYPE_SINK; desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER; desc.ops = &tmc_etr_cs_ops; - /* - * ETR configuration uses a 40-bit AXI master in place of - * the embedded SRAM of ETB/ETF. - */ - ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); + ret = tmc_etr_setup_caps(drvdata, devid, id->data); if (ret) goto out; break; diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index c4ff23336e76..13ab1008f110 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -104,6 +104,8 @@ enum tmc_mem_intf_width { * @config_type: TMC variant, must be of type @tmc_config_type. * @memwidth: width of the memory interface databus, in bytes. * @trigger_cntr: amount of words to store after a trigger. + * @etr_caps: Bitmask of capabilities of the TMC ETR, inferred from the + * device configuration register (DEVID) */ struct tmc_drvdata { void __iomem *base; @@ -121,6 +123,7 @@ struct tmc_drvdata { enum tmc_config_type config_type; enum tmc_mem_intf_width memwidth; u32 trigger_cntr; + u32 etr_caps; }; /* Generic functions */ @@ -157,4 +160,21 @@ TMC_REG_PAIR(rrp, TMC_RRP, TMC_RRPHI) TMC_REG_PAIR(rwp, TMC_RWP, TMC_RWPHI) TMC_REG_PAIR(dba, TMC_DBALO, TMC_DBAHI) +/* Initialise the caps from unadvertised static capabilities of the device */ +static inline void tmc_etr_init_caps(struct tmc_drvdata *drvdata, u32 dev_caps) +{ + WARN_ON(drvdata->etr_caps); + drvdata->etr_caps = dev_caps; +} + +static inline void tmc_etr_set_cap(struct tmc_drvdata *drvdata, u32 cap) +{ + drvdata->etr_caps |= cap; +} + +static inline bool tmc_etr_has_cap(struct tmc_drvdata *drvdata, u32 cap) +{ + return !!(drvdata->etr_caps & cap); +} + #endif -- cgit v1.2.3 From 2e21934568c0f9fcd2e01060007506a74d49152b Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:12 -0600 Subject: coresight tmc: Detect support for scatter gather The SG unit in the TMC has been removed in Coresight SoC-600. This is however advertised by DEVID:Bit 24 = 0b1. On the previous generation, the bit is RES0, hence we can rely on the DEVID to detect the support. Cc: Mathieu Poirier Cc: Mike Leach Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc.c | 2 ++ drivers/hwtracing/coresight/coresight-tmc.h | 5 +++++ 2 files changed, 7 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 0c99ef7b9b2b..bb409c485d05 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -306,6 +306,8 @@ static int tmc_etr_setup_caps(struct tmc_drvdata *drvdata, /* Set the unadvertised capabilities */ tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps); + if (!(devid & TMC_DEVID_NOSCAT)) + tmc_etr_set_cap(drvdata, TMC_ETR_SG); /* * ETR configuration uses a 40-bit AXI master in place of * the embedded SRAM of ETB/ETF. diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 13ab1008f110..bb6a3e3314b8 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -69,6 +69,8 @@ #define TMC_FFCR_STOP_ON_FLUSH BIT(12) +#define TMC_DEVID_NOSCAT BIT(24) + enum tmc_config_type { TMC_CONFIG_TYPE_ETB, TMC_CONFIG_TYPE_ETR, @@ -88,6 +90,9 @@ enum tmc_mem_intf_width { TMC_MEM_INTF_WIDTH_256BITS = 8, }; +/* TMC ETR Capability bit definitions */ +#define TMC_ETR_SG (0x1U << 0) + /** * struct tmc_drvdata - specifics associated to an TMC component * @base: memory mapped base address for this component. -- cgit v1.2.3 From ff11f5bc5a42f2cfc9705481eedf1b4d470ade2c Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:13 -0600 Subject: coresight tmc etr: Detect address width at runtime TMC in Coresight SoC-600 advertises the AXI address width in the device configuration register. Bit 16 - AXIAW_VALID 0 - AXI Address Width not valid 1 - Valid AXI Address width in Bits[23-17] Bits [23-17] - AXIAW. If AXIAW_VALID = b01 then 0x20 - 32bit AXI address bus 0x28 - 40bit AXI address bus 0x2c - 44bit AXI address bus 0x30 - 48bit AXI address bus 0x34 - 52bit AXI address bus Use the address bits from the device configuration register, if available. Otherwise, default to 40bit. Cc: Mathieu Poirier Cc: Robin Murphy Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc.c | 26 +++++++++++++++++++++++--- drivers/hwtracing/coresight/coresight-tmc.h | 4 ++++ 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index bb409c485d05..5bfc1b3ab80c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -303,16 +303,36 @@ const struct attribute_group *coresight_tmc_groups[] = { static int tmc_etr_setup_caps(struct tmc_drvdata *drvdata, u32 devid, void *dev_caps) { + u32 dma_mask = 0; + /* Set the unadvertised capabilities */ tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps); if (!(devid & TMC_DEVID_NOSCAT)) tmc_etr_set_cap(drvdata, TMC_ETR_SG); + + /* Check if the AXI address width is available */ + if (devid & TMC_DEVID_AXIAW_VALID) + dma_mask = ((devid >> TMC_DEVID_AXIAW_SHIFT) & + TMC_DEVID_AXIAW_MASK); + /* - * ETR configuration uses a 40-bit AXI master in place of - * the embedded SRAM of ETB/ETF. + * Unless specified in the device configuration, ETR uses a 40-bit + * AXI master in place of the embedded SRAM of ETB/ETF. */ - return dma_set_mask_and_coherent(drvdata->dev, DMA_BIT_MASK(40)); + switch (dma_mask) { + case 32: + case 40: + case 44: + case 48: + case 52: + dev_info(drvdata->dev, "Detected dma mask %dbits\n", dma_mask); + break; + default: + dma_mask = 40; + } + + return dma_set_mask_and_coherent(drvdata->dev, DMA_BIT_MASK(dma_mask)); } static int tmc_probe(struct amba_device *adev, const struct amba_id *id) diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index bb6a3e3314b8..f55203d48673 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -71,6 +71,10 @@ #define TMC_DEVID_NOSCAT BIT(24) +#define TMC_DEVID_AXIAW_VALID BIT(16) +#define TMC_DEVID_AXIAW_SHIFT 17 +#define TMC_DEVID_AXIAW_MASK 0x7f + enum tmc_config_type { TMC_CONFIG_TYPE_ETB, TMC_CONFIG_TYPE_ETR, -- cgit v1.2.3 From cd407abd5efd6f36b6372d615fbab486936e90f4 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:14 -0600 Subject: coresight tmc etr: Cleanup AXICTL register handling This patch cleans up how we setup the AXICTL register on TMC ETR. At the moment we don't set the CacheCtrl bits, which drives the arcache and awcache bits on AXI bus specifying the cacheablitiy. Set this to Write-back Read and Write-allocate. Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc-etr.c | 10 +++------- drivers/hwtracing/coresight/coresight-tmc.h | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 9c39c899ebd5..880b53527599 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -36,13 +36,9 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE); axictl = readl_relaxed(drvdata->base + TMC_AXICTL); - axictl |= TMC_AXICTL_WR_BURST_16; - writel_relaxed(axictl, drvdata->base + TMC_AXICTL); - axictl &= ~TMC_AXICTL_SCT_GAT_MODE; - writel_relaxed(axictl, drvdata->base + TMC_AXICTL); - axictl = (axictl & - ~(TMC_AXICTL_PROT_CTL_B0 | TMC_AXICTL_PROT_CTL_B1)) | - TMC_AXICTL_PROT_CTL_B1; + axictl &= ~TMC_AXICTL_CLEAR_MASK; + axictl |= (TMC_AXICTL_PROT_CTL_B1 | TMC_AXICTL_WR_BURST_16); + axictl |= TMC_AXICTL_AXCACHE_OS; writel_relaxed(axictl, drvdata->base + TMC_AXICTL); tmc_write_dba(drvdata, drvdata->paddr); diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index f55203d48673..07c0bf1d9269 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -54,11 +54,26 @@ #define TMC_STS_TMCREADY_BIT 2 #define TMC_STS_FULL BIT(0) #define TMC_STS_TRIGGERED BIT(1) -/* TMC_AXICTL - 0x110 */ +/* + * TMC_AXICTL - 0x110 + * + * TMC AXICTL format for SoC-400 + * Bits [0-1] : ProtCtrlBit0-1 + * Bits [2-5] : CacheCtrlBits 0-3 (AxCACHE) + * Bit 6 : Reserved + * Bit 7 : ScatterGatherMode + * Bits [8-11] : WrBurstLen + * Bits [12-31] : Reserved. + */ +#define TMC_AXICTL_CLEAR_MASK 0xfbf + #define TMC_AXICTL_PROT_CTL_B0 BIT(0) #define TMC_AXICTL_PROT_CTL_B1 BIT(1) #define TMC_AXICTL_SCT_GAT_MODE BIT(7) #define TMC_AXICTL_WR_BURST_16 0xF00 +/* Write-back Read and Write-allocate */ +#define TMC_AXICTL_AXCACHE_OS (0xf << 2) + /* TMC_FFCR - 0x304 */ #define TMC_FFCR_FLUSHMAN_BIT 6 #define TMC_FFCR_EN_FMT BIT(0) -- cgit v1.2.3 From ebab6a7db2c599b5c29d033f3a20f86016d9a9b8 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:15 -0600 Subject: coresight tmc etr: Setup AXI cache encoding for read transfers If the ETR supports split cache encoding (i.e, separate bits for read and write transfers) unlike the older version (where read and write transfers use the same encoding in AXICTL[2-5]). This feature is not advertised and has to be described by the static mask associated with the device id. Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc-etr.c | 6 ++++++ drivers/hwtracing/coresight/coresight-tmc.h | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 880b53527599..40ddcf11ae4c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -39,6 +39,12 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) axictl &= ~TMC_AXICTL_CLEAR_MASK; axictl |= (TMC_AXICTL_PROT_CTL_B1 | TMC_AXICTL_WR_BURST_16); axictl |= TMC_AXICTL_AXCACHE_OS; + + if (tmc_etr_has_cap(drvdata, TMC_ETR_AXI_ARCACHE)) { + axictl &= ~TMC_AXICTL_ARCACHE_MASK; + axictl |= TMC_AXICTL_ARCACHE_OS; + } + writel_relaxed(axictl, drvdata->base + TMC_AXICTL); tmc_write_dba(drvdata, drvdata->paddr); diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 07c0bf1d9269..f39caa6a45c3 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -59,13 +59,18 @@ * * TMC AXICTL format for SoC-400 * Bits [0-1] : ProtCtrlBit0-1 - * Bits [2-5] : CacheCtrlBits 0-3 (AxCACHE) + * Bits [2-5] : CacheCtrlBits 0-3 (AXCACHE) * Bit 6 : Reserved * Bit 7 : ScatterGatherMode * Bits [8-11] : WrBurstLen * Bits [12-31] : Reserved. + * TMC AXICTL format for SoC-600, as above except: + * Bits [2-5] : AXI WCACHE + * Bits [16-19] : AXI RCACHE + * Bits [20-31] : Reserved */ #define TMC_AXICTL_CLEAR_MASK 0xfbf +#define TMC_AXICTL_ARCACHE_MASK (0xf << 16) #define TMC_AXICTL_PROT_CTL_B0 BIT(0) #define TMC_AXICTL_PROT_CTL_B1 BIT(1) @@ -73,6 +78,7 @@ #define TMC_AXICTL_WR_BURST_16 0xF00 /* Write-back Read and Write-allocate */ #define TMC_AXICTL_AXCACHE_OS (0xf << 2) +#define TMC_AXICTL_ARCACHE_OS (0xf << 16) /* TMC_FFCR - 0x304 */ #define TMC_FFCR_FLUSHMAN_BIT 6 @@ -111,6 +117,8 @@ enum tmc_mem_intf_width { /* TMC ETR Capability bit definitions */ #define TMC_ETR_SG (0x1U << 0) +/* ETR has separate read/write cache encodings */ +#define TMC_ETR_AXI_ARCACHE (0x1U << 1) /** * struct tmc_drvdata - specifics associated to an TMC component -- cgit v1.2.3 From f2e931a2deab1ab426085f0357285410644f2945 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:16 -0600 Subject: coresight tmc: Support for save-restore in ETR The Coresight SoC 600 TMC ETR supports save-restore feature, where the values of the RRP/RWP and STS.Full are retained when it leaves the Disabled state. Hence, we must program the RRP/RWP and STS.Full to a proper value. For now, set the RRP/RWP to the base address of the buffer and clear the STS.Full register. This can be later exploited for proper save-restore of ETR trace contexts (e.g, perf). Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc-etr.c | 13 ++++++++++++- drivers/hwtracing/coresight/coresight-tmc.h | 9 +++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 40ddcf11ae4c..68fbc8f7450e 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -22,7 +22,7 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) { - u32 axictl; + u32 axictl, sts; /* Zero out the memory to help with debug */ memset(drvdata->vaddr, 0, drvdata->size); @@ -47,6 +47,17 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) writel_relaxed(axictl, drvdata->base + TMC_AXICTL); tmc_write_dba(drvdata, drvdata->paddr); + /* + * If the TMC pointers must be programmed before the session, + * we have to set it properly (i.e, RRP/RWP to base address and + * STS to "not full"). + */ + if (tmc_etr_has_cap(drvdata, TMC_ETR_SAVE_RESTORE)) { + tmc_write_rrp(drvdata, drvdata->paddr); + tmc_write_rwp(drvdata, drvdata->paddr); + sts = readl_relaxed(drvdata->base + TMC_STS) & ~TMC_STS_FULL; + writel_relaxed(sts, drvdata->base + TMC_STS); + } writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI | TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT | diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index f39caa6a45c3..d0da43a14246 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -119,6 +119,15 @@ enum tmc_mem_intf_width { #define TMC_ETR_SG (0x1U << 0) /* ETR has separate read/write cache encodings */ #define TMC_ETR_AXI_ARCACHE (0x1U << 1) +/* + * TMC_ETR_SAVE_RESTORE - Values of RRP/RWP/STS.Full are + * retained when TMC leaves Disabled state, allowing us to continue + * the tracing from a point where we stopped. This also implies that + * the RRP/RWP/STS.Full should always be programmed to the correct + * value. Unfortunately this is not advertised by the hardware, + * so we have to rely on PID of the IP to detect the functionality. + */ +#define TMC_ETR_SAVE_RESTORE (0x1U << 2) /** * struct tmc_drvdata - specifics associated to an TMC component -- cgit v1.2.3 From 6495892c9194001936a9ef0d30638c36f431636f Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:17 -0600 Subject: coresight tmc: Add support for Coresight SoC 600 TMC The coresight SoC 600 supports ETR save-restore which allows us to restore a trace session by retaining the RRP/RWP/STS.Full values when the TMC leaves the Disabled state. However, the TMC doesn't have a scatter-gather unit in built. Also, TMCs have different PIDs in different configurations (ETF, ETB & ETR), unlike the previous generation. While the DEVID exposes some of the features/changes in the TMC, it doesn't explicitly advertises the new save-restore feature as described above. Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc.c | 16 ++++++++++++++++ drivers/hwtracing/coresight/coresight-tmc.h | 4 ++++ 2 files changed, 20 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 5bfc1b3ab80c..4fd112f11096 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -442,6 +442,22 @@ static struct amba_id tmc_ids[] = { .id = 0x0003b961, .mask = 0x0003ffff, }, + { + /* Coresight SoC 600 TMC-ETR/ETS */ + .id = 0x000bb9e8, + .mask = 0x000fffff, + .data = (void *)(unsigned long)CORESIGHT_SOC_600_ETR_CAPS, + }, + { + /* Coresight SoC 600 TMC-ETB */ + .id = 0x000bb9e9, + .mask = 0x000fffff, + }, + { + /* Coresight SoC 600 TMC-ETF */ + .id = 0x000bb9ea, + .mask = 0x000fffff, + }, { 0, 0}, }; diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index d0da43a14246..8df7a813f537 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -129,6 +129,10 @@ enum tmc_mem_intf_width { */ #define TMC_ETR_SAVE_RESTORE (0x1U << 2) +/* Coresight SoC-600 TMC-ETR unadvertised capabilities */ +#define CORESIGHT_SOC_600_ETR_CAPS \ + (TMC_ETR_SAVE_RESTORE | TMC_ETR_AXI_ARCACHE) + /** * struct tmc_drvdata - specifics associated to an TMC component * @base: memory mapped base address for this component. -- cgit v1.2.3 From 3d1afa08d2a25386ed0fdb538910586eb4b17f1f Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Wed, 2 Aug 2017 10:22:18 -0600 Subject: coresight: Add support for Coresight SoC 600 components Add the peripheral ids for the Coresight SoC 600 TPIU, replicator and funnel. Cc: Mathieu Poirier Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-dynamic-replicator.c | 5 +++++ drivers/hwtracing/coresight/coresight-funnel.c | 5 +++++ drivers/hwtracing/coresight/coresight-tpiu.c | 5 +++++ 3 files changed, 15 insertions(+) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c index b00ea2d7d13f..87bcf2123e66 100644 --- a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c +++ b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c @@ -202,6 +202,11 @@ static struct amba_id replicator_ids[] = { .id = 0x0003b909, .mask = 0x0003ffff, }, + { + /* Coresight SoC-600 */ + .id = 0x000bb9ec, + .mask = 0x000fffff, + }, { 0, 0 }, }; diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index 860fe6ef5632..e55851564273 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -251,6 +251,11 @@ static struct amba_id funnel_ids[] = { .id = 0x0003b908, .mask = 0x0003ffff, }, + { + /* Coresight SoC-600 */ + .id = 0x000bb9eb, + .mask = 0x000fffff, + }, { 0, 0}, }; diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 0673baf0f2f5..0e9d57e372bd 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -201,6 +201,11 @@ static struct amba_id tpiu_ids[] = { .id = 0x0004b912, .mask = 0x0007ffff, }, + { + /* Coresight SoC-600 */ + .id = 0x000bb9e7, + .mask = 0x000fffff, + }, { 0, 0}, }; -- cgit v1.2.3 From e3b786843589be374c1ba617be9f2d44429584e8 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 2 Aug 2017 10:22:20 -0600 Subject: coresight: STM: Clean up __iomem type usage The casting and other things here is odd, and causes sparse to complain: drivers/hwtracing/coresight/coresight-stm.c:279:35: warning: incorrect type in argument 1 (different address spaces) drivers/hwtracing/coresight/coresight-stm.c:279:35: expected void [noderef] *addr drivers/hwtracing/coresight/coresight-stm.c:279:35: got struct stm_drvdata *drvdata drivers/hwtracing/coresight/coresight-stm.c:327:17: warning: incorrect type in argument 2 (different address spaces) drivers/hwtracing/coresight/coresight-stm.c:327:17: expected void volatile [noderef] *addr drivers/hwtracing/coresight/coresight-stm.c:327:17: got void *addr drivers/hwtracing/coresight/coresight-stm.c:330:17: warning: incorrect type in argument 2 (different address spaces) drivers/hwtracing/coresight/coresight-stm.c:330:17: expected void volatile [noderef] *addr drivers/hwtracing/coresight/coresight-stm.c:330:17: got void *addr drivers/hwtracing/coresight/coresight-stm.c:333:17: warning: incorrect type in argument 2 (different address spaces) drivers/hwtracing/coresight/coresight-stm.c:333:17: expected void volatile [noderef] *addr drivers/hwtracing/coresight/coresight-stm.c:333:17: got void *addr >From what I can tell, we don't really need to treat ch_addr as anything besides a pointer, and we can just do pointer math instead of ORing in the bits of the offset and achieve the same thing. Also, we were passing a drvdata pointer to the coresight_timeout() function, but we really wanted to pass the address of the register base. Luckily the base is the first member of the structure, so everything works out, but this is quite unsafe if we ever change the structure layout. Clean this all up so sparse stops complaining on this code. Reported-by: Satyajit Desai Signed-off-by: Stephen Boyd Signed-off-by: Mathieu Poirier Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-stm.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 202ed7a909e1..8ec4c4f8a2f2 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -276,7 +276,7 @@ static void stm_disable(struct coresight_device *csdev, spin_unlock(&drvdata->spinlock); /* Wait until the engine has completely stopped */ - coresight_timeout(drvdata, STMTCSR, STMTCSR_BUSY_BIT, 0); + coresight_timeout(drvdata->base, STMTCSR, STMTCSR_BUSY_BIT, 0); pm_runtime_put(drvdata->dev); @@ -307,7 +307,8 @@ static inline bool stm_addr_unaligned(const void *addr, u8 write_bytes) return ((unsigned long)addr & (write_bytes - 1)); } -static void stm_send(void *addr, const void *data, u32 size, u8 write_bytes) +static void stm_send(void __iomem *addr, const void *data, + u32 size, u8 write_bytes) { u8 paload[8]; @@ -414,7 +415,7 @@ static ssize_t notrace stm_generic_packet(struct stm_data *stm_data, unsigned int size, const unsigned char *payload) { - unsigned long ch_addr; + void __iomem *ch_addr; struct stm_drvdata *drvdata = container_of(stm_data, struct stm_drvdata, stm); @@ -424,7 +425,7 @@ static ssize_t notrace stm_generic_packet(struct stm_data *stm_data, if (channel >= drvdata->numsp) return -EINVAL; - ch_addr = (unsigned long)stm_channel_addr(drvdata, channel); + ch_addr = stm_channel_addr(drvdata, channel); flags = (flags == STP_PACKET_TIMESTAMPED) ? STM_FLAG_TIMESTAMPED : 0; flags |= test_bit(channel, drvdata->chs.guaranteed) ? @@ -437,20 +438,20 @@ static ssize_t notrace stm_generic_packet(struct stm_data *stm_data, switch (packet) { case STP_PACKET_FLAG: - ch_addr |= stm_channel_off(STM_PKT_TYPE_FLAG, flags); + ch_addr += stm_channel_off(STM_PKT_TYPE_FLAG, flags); /* * The generic STM core sets a size of '0' on flag packets. * As such send a flag packet of size '1' and tell the * core we did so. */ - stm_send((void *)ch_addr, payload, 1, drvdata->write_bytes); + stm_send(ch_addr, payload, 1, drvdata->write_bytes); size = 1; break; case STP_PACKET_DATA: - ch_addr |= stm_channel_off(STM_PKT_TYPE_DATA, flags); - stm_send((void *)ch_addr, payload, size, + ch_addr += stm_channel_off(STM_PKT_TYPE_DATA, flags); + stm_send(ch_addr, payload, size, drvdata->write_bytes); break; -- cgit v1.2.3 From 74bf16d0ded97fd6c52a69cfbfd868e9fae0a0bd Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 24 Aug 2017 22:06:05 +0530 Subject: coresight: tpiu: constify amba_id amba_id are not supposed to change at runtime. All functions working with const amba_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tpiu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c index 0e9d57e372bd..d7a3e453016d 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -192,7 +192,7 @@ static const struct dev_pm_ops tpiu_dev_pm_ops = { SET_RUNTIME_PM_OPS(tpiu_runtime_suspend, tpiu_runtime_resume, NULL) }; -static struct amba_id tpiu_ids[] = { +static const struct amba_id tpiu_ids[] = { { .id = 0x0003b912, .mask = 0x0003ffff, -- cgit v1.2.3 From 6f964e7c175cafa65862f7a884cea49c023a0e90 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 24 Aug 2017 22:06:04 +0530 Subject: coresight: tmc: constify amba_id amba_id are not supposed to change at runtime. All functions working with const amba_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-tmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 4fd112f11096..2ff4a66a3caa 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -437,7 +437,7 @@ out: return ret; } -static struct amba_id tmc_ids[] = { +static const struct amba_id tmc_ids[] = { { .id = 0x0003b961, .mask = 0x0003ffff, -- cgit v1.2.3 From 44d5af088b2e454ede49bc77eeec2ce5d0b9f079 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 24 Aug 2017 22:06:03 +0530 Subject: coresight: stm: constify amba_id amba_id are not supposed to change at runtime. All functions working with const amba_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-stm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c index 8ec4c4f8a2f2..92a780a6df1d 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -915,7 +915,7 @@ static const struct dev_pm_ops stm_dev_pm_ops = { SET_RUNTIME_PM_OPS(stm_runtime_suspend, stm_runtime_resume, NULL) }; -static struct amba_id stm_ids[] = { +static const struct amba_id stm_ids[] = { { .id = 0x0003b962, .mask = 0x0003ffff, -- cgit v1.2.3 From c214f76213f9112c04077bc22c659dc2781d4029 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 24 Aug 2017 22:06:02 +0530 Subject: coresight: replicator: constify amba_id amba_id are not supposed to change at runtime. All functions working with const amba_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-dynamic-replicator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c index 87bcf2123e66..accc2056f7c6 100644 --- a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c +++ b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c @@ -197,7 +197,7 @@ static const struct dev_pm_ops replicator_dev_pm_ops = { NULL) }; -static struct amba_id replicator_ids[] = { +static const struct amba_id replicator_ids[] = { { .id = 0x0003b909, .mask = 0x0003ffff, -- cgit v1.2.3 From 87c89af76397b86ecd8250f6c9ce3d0d0e220763 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 24 Aug 2017 22:06:01 +0530 Subject: coresight: funnel: constify amba_id amba_id are not supposed to change at runtime. All functions working with const amba_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-funnel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c index e55851564273..77642e0e955b 100644 --- a/drivers/hwtracing/coresight/coresight-funnel.c +++ b/drivers/hwtracing/coresight/coresight-funnel.c @@ -246,7 +246,7 @@ static const struct dev_pm_ops funnel_dev_pm_ops = { SET_RUNTIME_PM_OPS(funnel_runtime_suspend, funnel_runtime_resume, NULL) }; -static struct amba_id funnel_ids[] = { +static const struct amba_id funnel_ids[] = { { .id = 0x0003b908, .mask = 0x0003ffff, -- cgit v1.2.3 From c5520c93c78ff30903422e9a8be8ef297bc6496f Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 24 Aug 2017 22:06:00 +0530 Subject: coresight: etm4x: constify amba_id amba_id are not supposed to change at runtime. All functions working with const amba_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm4x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index ac77b4c973d8..cf364a514c12 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -1052,7 +1052,7 @@ err_arch_supported: return ret; } -static struct amba_id etm4_ids[] = { +static const struct amba_id etm4_ids[] = { { /* ETM 4.0 - Cortex-A53 */ .id = 0x000bb95d, .mask = 0x000fffff, -- cgit v1.2.3 From a13f6f917600985264ff3ef2bf75a14cf353b52f Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 24 Aug 2017 22:05:59 +0530 Subject: coresight: etm3x: constify amba_id amba_id are not supposed to change at runtime. All functions working with const amba_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etm3x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 9c010eb9497f..e5b1ec57dbde 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -899,7 +899,7 @@ static const struct dev_pm_ops etm_dev_pm_ops = { SET_RUNTIME_PM_OPS(etm_runtime_suspend, etm_runtime_resume, NULL) }; -static struct amba_id etm_ids[] = { +static const struct amba_id etm_ids[] = { { /* ETM 3.3 */ .id = 0x0003b921, .mask = 0x0003ffff, -- cgit v1.2.3 From 5959f3d7973c41a9f82e2477e8c6e881db7ad967 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 24 Aug 2017 22:05:58 +0530 Subject: coresight: etb10: constify amba_id amba_id are not supposed to change at runtime. All functions working with const amba_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-etb10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 05625e3a584e..56ecd7aff5eb 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -746,7 +746,7 @@ static const struct dev_pm_ops etb_dev_pm_ops = { SET_RUNTIME_PM_OPS(etb_runtime_suspend, etb_runtime_resume, NULL) }; -static struct amba_id etb_ids[] = { +static const struct amba_id etb_ids[] = { { .id = 0x0003b907, .mask = 0x0003ffff, -- cgit v1.2.3 From 0875957e4bdd61d7969c47e29dab8769c9ab2cf9 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Thu, 24 Aug 2017 22:05:57 +0530 Subject: coresight: constify amba_id amba_id are not supposed to change at runtime. All functions working with const amba_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/hwtracing/coresight/coresight-cpu-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hwtracing') diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c index 64a77e00eaa6..6ea62c62ff27 100644 --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -667,7 +667,7 @@ static int debug_remove(struct amba_device *adev) return 0; } -static struct amba_id debug_ids[] = { +static const struct amba_id debug_ids[] = { { /* Debug for Cortex-A53 */ .id = 0x000bbd03, .mask = 0x000fffff, -- cgit v1.2.3