Loading drivers/hwtracing/coresight/coresight-common.h +7 −1 Original line number Diff line number Diff line Loading @@ -44,5 +44,11 @@ static inline struct coresight_csr *coresight_csr_get(const char *name) static inline int of_get_coresight_csr_name(struct device_node *node, const char **csr_name){ return -EINVAL; } #endif #if IS_ENABLED(CONFIG_CORESIGHT_CTI) && IS_ENABLED(CONFIG_OF) extern struct coresight_cti_data *of_get_coresight_cti_data( struct device *dev, struct device_node *node); #else static inline struct coresight_cti_data *of_get_coresight_cti_data( struct device *dev, struct device_node *node) { return NULL; } #endif #endif drivers/hwtracing/coresight/coresight-cti.c +42 −0 Original line number Diff line number Diff line Loading @@ -1466,6 +1466,48 @@ static int cti_init_save(struct cti_drvdata *drvdata, return 0; } struct coresight_cti_data *of_get_coresight_cti_data( struct device *dev, struct device_node *node) { int i, ret; uint32_t ctis_len; struct device_node *child_node; struct coresight_cti_data *ctidata; ctidata = devm_kzalloc(dev, sizeof(*ctidata), GFP_KERNEL); if (!ctidata) return ERR_PTR(-ENOMEM); if (of_get_property(node, "coresight-ctis", &ctis_len)) ctidata->nr_ctis = ctis_len/sizeof(uint32_t); else return ERR_PTR(-EINVAL); if (ctidata->nr_ctis) { ctidata->names = devm_kzalloc(dev, ctidata->nr_ctis * sizeof(*ctidata->names), GFP_KERNEL); if (!ctidata->names) return ERR_PTR(-ENOMEM); for (i = 0; i < ctidata->nr_ctis; i++) { child_node = of_parse_phandle(node, "coresight-ctis", i); if (!child_node) return ERR_PTR(-EINVAL); ret = of_property_read_string(child_node, "coresight-name", &ctidata->names[i]); of_node_put(child_node); if (ret) return ERR_PTR(ret); } } return ctidata; } EXPORT_SYMBOL(of_get_coresight_cti_data); static int cti_probe(struct amba_device *adev, const struct amba_id *id) { int ret; Loading drivers/hwtracing/coresight/coresight-tmc-etf.c +8 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,12 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) if (!used) kfree(buf); if (!ret) { coresight_cti_map_trigin(drvdata->cti_reset, 0, 0); coresight_cti_map_trigout(drvdata->cti_flush, 1, 0); dev_info(&csdev->dev, "TMC-ETB/ETF enabled\n"); } return ret; } Loading Loading @@ -327,6 +333,8 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_cti_unmap_trigin(drvdata->cti_reset, 0, 0); coresight_cti_unmap_trigout(drvdata->cti_flush, 1, 0); dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n"); return 0; } Loading drivers/hwtracing/coresight/coresight-tmc-etr.c +18 −3 Original line number Diff line number Diff line Loading @@ -1135,6 +1135,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) * buffer, provided the size matches. Any allocation has to be done * with the lock released. */ mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); sysfs_buf = READ_ONCE(drvdata->sysfs_buf); if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) { Loading @@ -1142,13 +1143,17 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) /* Allocate memory with the locks released */ free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata); if (IS_ERR(new_buf)) if (IS_ERR(new_buf)) { mutex_unlock(&drvdata->mem_lock); return PTR_ERR(new_buf); } /* Let's try again */ spin_lock_irqsave(&drvdata->spinlock, flags); } coresight_cti_map_trigout(drvdata->cti_flush, 3, 0); coresight_cti_map_trigin(drvdata->cti_reset, 2, 0); if (drvdata->reading || drvdata->mode == CS_MODE_PERF) { ret = -EBUSY; goto out; Loading Loading @@ -1188,6 +1193,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) tmc_etr_free_sysfs_buf(free_buf); tmc_etr_byte_cntr_start(drvdata->byte_cntr); mutex_unlock(&drvdata->mem_lock); if (!ret) dev_dbg(&csdev->dev, "TMC-ETR enabled\n"); Loading Loading @@ -1633,10 +1639,12 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) unsigned long flags; struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { spin_unlock_irqrestore(&drvdata->spinlock, flags); mutex_unlock(&drvdata->mem_lock); return -EBUSY; } Loading @@ -1657,11 +1665,14 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) spin_unlock_irqrestore(&drvdata->spinlock, flags); tmc_etr_byte_cntr_stop(drvdata->byte_cntr); coresight_cti_unmap_trigin(drvdata->cti_reset, 2, 0); coresight_cti_unmap_trigout(drvdata->cti_flush, 3, 0); /* Free memory outside the spinlock if need be */ if (drvdata->etr_buf) { tmc_etr_free_sysfs_buf(drvdata->etr_buf); drvdata->etr_buf = NULL; } mutex_unlock(&drvdata->mem_lock); dev_info(&csdev->dev, "TMC-ETR disabled\n"); return 0; } Loading @@ -1687,6 +1698,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) return -EINVAL; mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { ret = -EBUSY; Loading Loading @@ -1715,6 +1727,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) drvdata->reading = true; out: spin_unlock_irqrestore(&drvdata->spinlock, flags); mutex_unlock(&drvdata->mem_lock); return ret; } Loading @@ -1727,7 +1740,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) /* config types are set a boot time and never change */ if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) return -EINVAL; mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); /* RE-enable the TMC if need be */ Loading @@ -1754,5 +1767,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) if (sysfs_buf) tmc_etr_free_sysfs_buf(sysfs_buf); mutex_unlock(&drvdata->mem_lock); return 0; } drivers/hwtracing/coresight/coresight-tmc.c +25 −1 Original line number Diff line number Diff line Loading @@ -184,19 +184,24 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len, ssize_t actual; struct tmc_drvdata *drvdata = container_of(file->private_data, struct tmc_drvdata, miscdev); mutex_lock(&drvdata->mem_lock); actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp); if (actual <= 0) if (actual <= 0) { mutex_unlock(&drvdata->mem_lock); return 0; } if (copy_to_user(data, bufp, actual)) { dev_dbg(&drvdata->csdev->dev, "%s: copy_to_user failed\n", __func__); mutex_unlock(&drvdata->mem_lock); return -EFAULT; } *ppos += actual; dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual); mutex_unlock(&drvdata->mem_lock); return actual; } Loading Loading @@ -493,6 +498,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; struct coresight_dev_list *dev_list = NULL; struct coresight_cti_data *ctidata; ret = -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); Loading @@ -511,6 +517,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) drvdata->base = base; spin_lock_init(&drvdata->spinlock); mutex_init(&drvdata->mem_lock); devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); drvdata->config_type = BMVAL(devid, 6, 7); Loading @@ -534,6 +541,23 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) } } ctidata = of_get_coresight_cti_data(dev, adev->dev.of_node); if (IS_ERR(ctidata)) { dev_err(dev, "invalid cti data\n"); } else if (ctidata && ctidata->nr_ctis == 2) { drvdata->cti_flush = coresight_cti_get(ctidata->names[0]); if (IS_ERR(drvdata->cti_flush)) { dev_err(dev, "failed to get flush cti, defer probe\n"); return -EPROBE_DEFER; } drvdata->cti_reset = coresight_cti_get(ctidata->names[1]); if (IS_ERR(drvdata->cti_reset)) { dev_err(dev, "failed to get reset cti, defer probe\n"); return -EPROBE_DEFER; } } desc.dev = dev; desc.groups = coresight_tmc_groups; Loading Loading
drivers/hwtracing/coresight/coresight-common.h +7 −1 Original line number Diff line number Diff line Loading @@ -44,5 +44,11 @@ static inline struct coresight_csr *coresight_csr_get(const char *name) static inline int of_get_coresight_csr_name(struct device_node *node, const char **csr_name){ return -EINVAL; } #endif #if IS_ENABLED(CONFIG_CORESIGHT_CTI) && IS_ENABLED(CONFIG_OF) extern struct coresight_cti_data *of_get_coresight_cti_data( struct device *dev, struct device_node *node); #else static inline struct coresight_cti_data *of_get_coresight_cti_data( struct device *dev, struct device_node *node) { return NULL; } #endif #endif
drivers/hwtracing/coresight/coresight-cti.c +42 −0 Original line number Diff line number Diff line Loading @@ -1466,6 +1466,48 @@ static int cti_init_save(struct cti_drvdata *drvdata, return 0; } struct coresight_cti_data *of_get_coresight_cti_data( struct device *dev, struct device_node *node) { int i, ret; uint32_t ctis_len; struct device_node *child_node; struct coresight_cti_data *ctidata; ctidata = devm_kzalloc(dev, sizeof(*ctidata), GFP_KERNEL); if (!ctidata) return ERR_PTR(-ENOMEM); if (of_get_property(node, "coresight-ctis", &ctis_len)) ctidata->nr_ctis = ctis_len/sizeof(uint32_t); else return ERR_PTR(-EINVAL); if (ctidata->nr_ctis) { ctidata->names = devm_kzalloc(dev, ctidata->nr_ctis * sizeof(*ctidata->names), GFP_KERNEL); if (!ctidata->names) return ERR_PTR(-ENOMEM); for (i = 0; i < ctidata->nr_ctis; i++) { child_node = of_parse_phandle(node, "coresight-ctis", i); if (!child_node) return ERR_PTR(-EINVAL); ret = of_property_read_string(child_node, "coresight-name", &ctidata->names[i]); of_node_put(child_node); if (ret) return ERR_PTR(ret); } } return ctidata; } EXPORT_SYMBOL(of_get_coresight_cti_data); static int cti_probe(struct amba_device *adev, const struct amba_id *id) { int ret; Loading
drivers/hwtracing/coresight/coresight-tmc-etf.c +8 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,12 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) if (!used) kfree(buf); if (!ret) { coresight_cti_map_trigin(drvdata->cti_reset, 0, 0); coresight_cti_map_trigout(drvdata->cti_flush, 1, 0); dev_info(&csdev->dev, "TMC-ETB/ETF enabled\n"); } return ret; } Loading Loading @@ -327,6 +333,8 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_cti_unmap_trigin(drvdata->cti_reset, 0, 0); coresight_cti_unmap_trigout(drvdata->cti_flush, 1, 0); dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n"); return 0; } Loading
drivers/hwtracing/coresight/coresight-tmc-etr.c +18 −3 Original line number Diff line number Diff line Loading @@ -1135,6 +1135,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) * buffer, provided the size matches. Any allocation has to be done * with the lock released. */ mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); sysfs_buf = READ_ONCE(drvdata->sysfs_buf); if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) { Loading @@ -1142,13 +1143,17 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) /* Allocate memory with the locks released */ free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata); if (IS_ERR(new_buf)) if (IS_ERR(new_buf)) { mutex_unlock(&drvdata->mem_lock); return PTR_ERR(new_buf); } /* Let's try again */ spin_lock_irqsave(&drvdata->spinlock, flags); } coresight_cti_map_trigout(drvdata->cti_flush, 3, 0); coresight_cti_map_trigin(drvdata->cti_reset, 2, 0); if (drvdata->reading || drvdata->mode == CS_MODE_PERF) { ret = -EBUSY; goto out; Loading Loading @@ -1188,6 +1193,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) tmc_etr_free_sysfs_buf(free_buf); tmc_etr_byte_cntr_start(drvdata->byte_cntr); mutex_unlock(&drvdata->mem_lock); if (!ret) dev_dbg(&csdev->dev, "TMC-ETR enabled\n"); Loading Loading @@ -1633,10 +1639,12 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) unsigned long flags; struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { spin_unlock_irqrestore(&drvdata->spinlock, flags); mutex_unlock(&drvdata->mem_lock); return -EBUSY; } Loading @@ -1657,11 +1665,14 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) spin_unlock_irqrestore(&drvdata->spinlock, flags); tmc_etr_byte_cntr_stop(drvdata->byte_cntr); coresight_cti_unmap_trigin(drvdata->cti_reset, 2, 0); coresight_cti_unmap_trigout(drvdata->cti_flush, 3, 0); /* Free memory outside the spinlock if need be */ if (drvdata->etr_buf) { tmc_etr_free_sysfs_buf(drvdata->etr_buf); drvdata->etr_buf = NULL; } mutex_unlock(&drvdata->mem_lock); dev_info(&csdev->dev, "TMC-ETR disabled\n"); return 0; } Loading @@ -1687,6 +1698,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) return -EINVAL; mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { ret = -EBUSY; Loading Loading @@ -1715,6 +1727,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) drvdata->reading = true; out: spin_unlock_irqrestore(&drvdata->spinlock, flags); mutex_unlock(&drvdata->mem_lock); return ret; } Loading @@ -1727,7 +1740,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) /* config types are set a boot time and never change */ if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) return -EINVAL; mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); /* RE-enable the TMC if need be */ Loading @@ -1754,5 +1767,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) if (sysfs_buf) tmc_etr_free_sysfs_buf(sysfs_buf); mutex_unlock(&drvdata->mem_lock); return 0; }
drivers/hwtracing/coresight/coresight-tmc.c +25 −1 Original line number Diff line number Diff line Loading @@ -184,19 +184,24 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len, ssize_t actual; struct tmc_drvdata *drvdata = container_of(file->private_data, struct tmc_drvdata, miscdev); mutex_lock(&drvdata->mem_lock); actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp); if (actual <= 0) if (actual <= 0) { mutex_unlock(&drvdata->mem_lock); return 0; } if (copy_to_user(data, bufp, actual)) { dev_dbg(&drvdata->csdev->dev, "%s: copy_to_user failed\n", __func__); mutex_unlock(&drvdata->mem_lock); return -EFAULT; } *ppos += actual; dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual); mutex_unlock(&drvdata->mem_lock); return actual; } Loading Loading @@ -493,6 +498,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res = &adev->res; struct coresight_desc desc = { 0 }; struct coresight_dev_list *dev_list = NULL; struct coresight_cti_data *ctidata; ret = -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); Loading @@ -511,6 +517,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) drvdata->base = base; spin_lock_init(&drvdata->spinlock); mutex_init(&drvdata->mem_lock); devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); drvdata->config_type = BMVAL(devid, 6, 7); Loading @@ -534,6 +541,23 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) } } ctidata = of_get_coresight_cti_data(dev, adev->dev.of_node); if (IS_ERR(ctidata)) { dev_err(dev, "invalid cti data\n"); } else if (ctidata && ctidata->nr_ctis == 2) { drvdata->cti_flush = coresight_cti_get(ctidata->names[0]); if (IS_ERR(drvdata->cti_flush)) { dev_err(dev, "failed to get flush cti, defer probe\n"); return -EPROBE_DEFER; } drvdata->cti_reset = coresight_cti_get(ctidata->names[1]); if (IS_ERR(drvdata->cti_reset)) { dev_err(dev, "failed to get reset cti, defer probe\n"); return -EPROBE_DEFER; } } desc.dev = dev; desc.groups = coresight_tmc_groups; Loading