Loading drivers/hwtracing/coresight/coresight-tmc-etf.c +9 −3 Original line number Diff line number Diff line Loading @@ -573,9 +573,12 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) } /* Disable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) if (drvdata->mode == CS_MODE_SYSFS) { spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_disable_all_source_link(); spin_lock_irqsave(&drvdata->spinlock, flags); tmc_etb_disable_hw(drvdata); } drvdata->reading = true; out: spin_unlock_irqrestore(&drvdata->spinlock, flags); Loading Loading @@ -605,6 +608,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) } } drvdata->reading = false; /* Re-enable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) { /* Loading @@ -617,6 +621,9 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) */ memset(drvdata->buf, 0, drvdata->size); tmc_etb_enable_hw(drvdata); spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_enable_all_source_link(); spin_lock_irqsave(&drvdata->spinlock, flags); } else { /* * The ETB/ETF is not tracing and the buffer was just read. Loading @@ -626,7 +633,6 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) drvdata->buf = NULL; } drvdata->reading = false; spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Loading drivers/hwtracing/coresight/coresight-tmc-etr.c +11 −4 Original line number Diff line number Diff line Loading @@ -1617,9 +1617,13 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) } /* Disable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) tmc_etr_disable_hw(drvdata, true); if (drvdata->mode == CS_MODE_SYSFS) { spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_disable_all_source_link(); spin_lock_irqsave(&drvdata->spinlock, flags); tmc_etr_disable_hw(drvdata, true); } drvdata->reading = true; out: spin_unlock_irqrestore(&drvdata->spinlock, flags); Loading @@ -1639,6 +1643,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); drvdata->reading = false; /* RE-enable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) { /* Loading @@ -1647,6 +1652,10 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) * be NULL. */ tmc_etr_enable_hw(drvdata); spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_enable_all_source_link(); spin_lock_irqsave(&drvdata->spinlock, flags); } else { /* * The ETR is not tracing and the buffer was just read. Loading @@ -1656,14 +1665,12 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) drvdata->etr_buf = NULL; } drvdata->reading = false; spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Free allocated memory out side of the spinlock */ if (etr_buf) tmc_free_etr_buf(etr_buf); mutex_unlock(&drvdata->mem_lock); return 0; } drivers/hwtracing/coresight/coresight.c +141 −2 Original line number Diff line number Diff line Loading @@ -62,6 +62,8 @@ static LIST_HEAD(cs_disabled_link); static LIST_HEAD(cs_active_paths); static struct coresight_device *activated_sink; /* * 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 Loading Loading @@ -850,6 +852,129 @@ int coresight_store_path(struct coresight_device *csdev, struct list_head *path) return 0; } static void coresight_enable_source_link(struct list_head *path) { u32 type; int ret; struct coresight_node *nd; struct coresight_device *csdev, *parent, *child; list_for_each_entry_reverse(nd, path, link) { csdev = nd->csdev; type = csdev->type; if (type == CORESIGHT_DEV_TYPE_LINKSINK) type = (csdev == coresight_get_sink(path)) ? CORESIGHT_DEV_TYPE_SINK : CORESIGHT_DEV_TYPE_LINK; switch (type) { case CORESIGHT_DEV_TYPE_SINK: break; case CORESIGHT_DEV_TYPE_SOURCE: if (source_ops(csdev)->enable) { ret = coresight_enable_reg_clk(csdev); if (ret) goto err; ret = source_ops(csdev)->enable(csdev, NULL, CS_MODE_SYSFS); if (ret) { coresight_disable_reg_clk(csdev); goto err; } } csdev->enable = true; break; case CORESIGHT_DEV_TYPE_LINK: parent = list_prev_entry(nd, link)->csdev; child = list_next_entry(nd, link)->csdev; ret = coresight_enable_link(csdev, parent, child, path); if (ret) goto err; break; default: break; } } return; err: coresight_disable_previous_devs(path, nd); coresight_release_path(csdev, path); } static void coresight_disable_source_link(struct list_head *path) { u32 type; struct coresight_node *nd; struct coresight_device *csdev, *parent, *child; list_for_each_entry(nd, path, link) { csdev = nd->csdev; type = csdev->type; if (type == CORESIGHT_DEV_TYPE_LINKSINK) type = (csdev == coresight_get_sink(path)) ? CORESIGHT_DEV_TYPE_SINK : CORESIGHT_DEV_TYPE_LINK; switch (type) { case CORESIGHT_DEV_TYPE_SINK: break; case CORESIGHT_DEV_TYPE_SOURCE: if (source_ops(csdev)->disable) { source_ops(csdev)->disable(csdev, NULL); coresight_disable_reg_clk(csdev); } csdev->enable = false; break; case CORESIGHT_DEV_TYPE_LINK: parent = list_prev_entry(nd, link)->csdev; child = list_next_entry(nd, link)->csdev; coresight_disable_link(csdev, parent, child, path); break; default: break; } } } void coresight_disable_all_source_link(void) { struct coresight_path *cspath = NULL; struct coresight_path *cspath_next = NULL; mutex_lock(&coresight_mutex); list_for_each_entry_safe(cspath, cspath_next, &cs_active_paths, link) { coresight_disable_source_link(cspath->path); } activated_sink = coresight_get_enabled_sink(false); if (activated_sink) activated_sink->activated = false; mutex_unlock(&coresight_mutex); } void coresight_enable_all_source_link(void) { struct coresight_path *cspath = NULL; struct coresight_path *cspath_next = NULL; mutex_lock(&coresight_mutex); list_for_each_entry_safe(cspath, cspath_next, &cs_active_paths, link) { coresight_enable_source_link(cspath->path); } if (activated_sink && activated_sink->enable) activated_sink->activated = true; activated_sink = NULL; mutex_unlock(&coresight_mutex); } int coresight_enable(struct coresight_device *csdev) { int ret = 0; Loading Loading @@ -959,18 +1084,32 @@ static ssize_t enable_sink_store(struct device *dev, int ret; unsigned long val; struct coresight_device *csdev = to_coresight_device(dev); struct coresight_device *sink = NULL; ret = kstrtoul(buf, 10, &val); if (ret) return ret; mutex_lock(&coresight_mutex); if (val) if (val) { sink = activated_sink ? activated_sink : coresight_get_enabled_sink(false); if (sink && strcmp(dev_name(&sink->dev), dev_name(&csdev->dev))) goto err; csdev->activated = true; else } else { if (csdev->enable) goto err; csdev->activated = false; } mutex_unlock(&coresight_mutex); return size; err: mutex_unlock(&coresight_mutex); return -EINVAL; } static DEVICE_ATTR_RW(enable_sink); Loading include/linux/coresight.h +4 −0 Original line number Diff line number Diff line Loading @@ -306,6 +306,8 @@ static inline bool coresight_link_late_disable(void) else return false; } extern void coresight_disable_all_source_link(void); extern void coresight_enable_all_source_link(void); #else static inline struct coresight_device * coresight_register(struct coresight_desc *desc) { return NULL; } Loading @@ -319,6 +321,8 @@ static inline void coresight_abort(void) {} static inline void coresight_disable_reg_clk(struct coresight_device *csdev) {} static inline int coresight_enable_reg_clk(struct coresight_device *csdev) { return -EINVAL; } static void coresight_disable_all_source_link(void) {}; static void coresight_enable_all_source_link(void) {}; #endif #if defined(CONFIG_OF) && defined(CONFIG_CORESIGHT) Loading Loading
drivers/hwtracing/coresight/coresight-tmc-etf.c +9 −3 Original line number Diff line number Diff line Loading @@ -573,9 +573,12 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) } /* Disable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) if (drvdata->mode == CS_MODE_SYSFS) { spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_disable_all_source_link(); spin_lock_irqsave(&drvdata->spinlock, flags); tmc_etb_disable_hw(drvdata); } drvdata->reading = true; out: spin_unlock_irqrestore(&drvdata->spinlock, flags); Loading Loading @@ -605,6 +608,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) } } drvdata->reading = false; /* Re-enable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) { /* Loading @@ -617,6 +621,9 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) */ memset(drvdata->buf, 0, drvdata->size); tmc_etb_enable_hw(drvdata); spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_enable_all_source_link(); spin_lock_irqsave(&drvdata->spinlock, flags); } else { /* * The ETB/ETF is not tracing and the buffer was just read. Loading @@ -626,7 +633,6 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) drvdata->buf = NULL; } drvdata->reading = false; spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Loading
drivers/hwtracing/coresight/coresight-tmc-etr.c +11 −4 Original line number Diff line number Diff line Loading @@ -1617,9 +1617,13 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) } /* Disable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) tmc_etr_disable_hw(drvdata, true); if (drvdata->mode == CS_MODE_SYSFS) { spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_disable_all_source_link(); spin_lock_irqsave(&drvdata->spinlock, flags); tmc_etr_disable_hw(drvdata, true); } drvdata->reading = true; out: spin_unlock_irqrestore(&drvdata->spinlock, flags); Loading @@ -1639,6 +1643,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) mutex_lock(&drvdata->mem_lock); spin_lock_irqsave(&drvdata->spinlock, flags); drvdata->reading = false; /* RE-enable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) { /* Loading @@ -1647,6 +1652,10 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) * be NULL. */ tmc_etr_enable_hw(drvdata); spin_unlock_irqrestore(&drvdata->spinlock, flags); coresight_enable_all_source_link(); spin_lock_irqsave(&drvdata->spinlock, flags); } else { /* * The ETR is not tracing and the buffer was just read. Loading @@ -1656,14 +1665,12 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) drvdata->etr_buf = NULL; } drvdata->reading = false; spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Free allocated memory out side of the spinlock */ if (etr_buf) tmc_free_etr_buf(etr_buf); mutex_unlock(&drvdata->mem_lock); return 0; }
drivers/hwtracing/coresight/coresight.c +141 −2 Original line number Diff line number Diff line Loading @@ -62,6 +62,8 @@ static LIST_HEAD(cs_disabled_link); static LIST_HEAD(cs_active_paths); static struct coresight_device *activated_sink; /* * 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 Loading Loading @@ -850,6 +852,129 @@ int coresight_store_path(struct coresight_device *csdev, struct list_head *path) return 0; } static void coresight_enable_source_link(struct list_head *path) { u32 type; int ret; struct coresight_node *nd; struct coresight_device *csdev, *parent, *child; list_for_each_entry_reverse(nd, path, link) { csdev = nd->csdev; type = csdev->type; if (type == CORESIGHT_DEV_TYPE_LINKSINK) type = (csdev == coresight_get_sink(path)) ? CORESIGHT_DEV_TYPE_SINK : CORESIGHT_DEV_TYPE_LINK; switch (type) { case CORESIGHT_DEV_TYPE_SINK: break; case CORESIGHT_DEV_TYPE_SOURCE: if (source_ops(csdev)->enable) { ret = coresight_enable_reg_clk(csdev); if (ret) goto err; ret = source_ops(csdev)->enable(csdev, NULL, CS_MODE_SYSFS); if (ret) { coresight_disable_reg_clk(csdev); goto err; } } csdev->enable = true; break; case CORESIGHT_DEV_TYPE_LINK: parent = list_prev_entry(nd, link)->csdev; child = list_next_entry(nd, link)->csdev; ret = coresight_enable_link(csdev, parent, child, path); if (ret) goto err; break; default: break; } } return; err: coresight_disable_previous_devs(path, nd); coresight_release_path(csdev, path); } static void coresight_disable_source_link(struct list_head *path) { u32 type; struct coresight_node *nd; struct coresight_device *csdev, *parent, *child; list_for_each_entry(nd, path, link) { csdev = nd->csdev; type = csdev->type; if (type == CORESIGHT_DEV_TYPE_LINKSINK) type = (csdev == coresight_get_sink(path)) ? CORESIGHT_DEV_TYPE_SINK : CORESIGHT_DEV_TYPE_LINK; switch (type) { case CORESIGHT_DEV_TYPE_SINK: break; case CORESIGHT_DEV_TYPE_SOURCE: if (source_ops(csdev)->disable) { source_ops(csdev)->disable(csdev, NULL); coresight_disable_reg_clk(csdev); } csdev->enable = false; break; case CORESIGHT_DEV_TYPE_LINK: parent = list_prev_entry(nd, link)->csdev; child = list_next_entry(nd, link)->csdev; coresight_disable_link(csdev, parent, child, path); break; default: break; } } } void coresight_disable_all_source_link(void) { struct coresight_path *cspath = NULL; struct coresight_path *cspath_next = NULL; mutex_lock(&coresight_mutex); list_for_each_entry_safe(cspath, cspath_next, &cs_active_paths, link) { coresight_disable_source_link(cspath->path); } activated_sink = coresight_get_enabled_sink(false); if (activated_sink) activated_sink->activated = false; mutex_unlock(&coresight_mutex); } void coresight_enable_all_source_link(void) { struct coresight_path *cspath = NULL; struct coresight_path *cspath_next = NULL; mutex_lock(&coresight_mutex); list_for_each_entry_safe(cspath, cspath_next, &cs_active_paths, link) { coresight_enable_source_link(cspath->path); } if (activated_sink && activated_sink->enable) activated_sink->activated = true; activated_sink = NULL; mutex_unlock(&coresight_mutex); } int coresight_enable(struct coresight_device *csdev) { int ret = 0; Loading Loading @@ -959,18 +1084,32 @@ static ssize_t enable_sink_store(struct device *dev, int ret; unsigned long val; struct coresight_device *csdev = to_coresight_device(dev); struct coresight_device *sink = NULL; ret = kstrtoul(buf, 10, &val); if (ret) return ret; mutex_lock(&coresight_mutex); if (val) if (val) { sink = activated_sink ? activated_sink : coresight_get_enabled_sink(false); if (sink && strcmp(dev_name(&sink->dev), dev_name(&csdev->dev))) goto err; csdev->activated = true; else } else { if (csdev->enable) goto err; csdev->activated = false; } mutex_unlock(&coresight_mutex); return size; err: mutex_unlock(&coresight_mutex); return -EINVAL; } static DEVICE_ATTR_RW(enable_sink); Loading
include/linux/coresight.h +4 −0 Original line number Diff line number Diff line Loading @@ -306,6 +306,8 @@ static inline bool coresight_link_late_disable(void) else return false; } extern void coresight_disable_all_source_link(void); extern void coresight_enable_all_source_link(void); #else static inline struct coresight_device * coresight_register(struct coresight_desc *desc) { return NULL; } Loading @@ -319,6 +321,8 @@ static inline void coresight_abort(void) {} static inline void coresight_disable_reg_clk(struct coresight_device *csdev) {} static inline int coresight_enable_reg_clk(struct coresight_device *csdev) { return -EINVAL; } static void coresight_disable_all_source_link(void) {}; static void coresight_enable_all_source_link(void) {}; #endif #if defined(CONFIG_OF) && defined(CONFIG_CORESIGHT) Loading