Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1275d755 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "tmc-etr: Fix the race condition when switch the out_mode"

parents edf61b7e c9cb22da
Loading
Loading
Loading
Loading
+23 −13
Original line number Diff line number Diff line
@@ -1323,7 +1323,6 @@ 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);
	if (!drvdata->etr_buf || (drvdata->etr_buf->size != drvdata->size)) {
		spin_unlock_irqrestore(&drvdata->spinlock, flags);
@@ -1340,7 +1339,6 @@ 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)) {
				mutex_unlock(&drvdata->mem_lock);
				return -ENOMEM;
			}
			coresight_cti_map_trigout(drvdata->cti_flush, 3, 0);
@@ -1350,7 +1348,6 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
				free_buf = new_buf =
				tmc_etr_setup_sysfs_buf(drvdata);
				if (IS_ERR(new_buf)) {
					mutex_unlock(&drvdata->mem_lock);
					return -ENOMEM;
				}
			}
@@ -1362,7 +1359,6 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
						usb_bypass_notifier);
			if (IS_ERR_OR_NULL(drvdata->usbch)) {
				dev_err(drvdata->dev, "usb_qdss_open failed\n");
				mutex_unlock(&drvdata->mem_lock);
				return -ENODEV;
			}
		} else {
@@ -1370,7 +1366,6 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
							usb_notifier);
			if (IS_ERR_OR_NULL(drvdata->usbch)) {
				dev_err(drvdata->dev, "usb_qdss_open failed\n");
				mutex_unlock(&drvdata->mem_lock);
				return -ENODEV;
			}
		}
@@ -1418,7 +1413,6 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
	if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM)
		tmc_etr_byte_cntr_start(drvdata->byte_cntr);

	mutex_unlock(&drvdata->mem_lock);
	if (!ret)
		dev_info(drvdata->dev, "TMC-ETR enabled\n");

@@ -1433,13 +1427,19 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev)

static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
{
	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
	int ret = 0;

	switch (mode) {
	case CS_MODE_SYSFS:
		return tmc_enable_etr_sink_sysfs(csdev);
		mutex_lock(&drvdata->mem_lock);
		ret = tmc_enable_etr_sink_sysfs(csdev);
		mutex_unlock(&drvdata->mem_lock);
		return ret;

	case CS_MODE_PERF:
		return tmc_enable_etr_sink_perf(csdev);
	}

	/* We shouldn't be here */
	return -EINVAL;
}
@@ -1449,11 +1449,9 @@ static void _tmc_disable_etr_sink(struct coresight_device *csdev, bool flush)
	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;
	}

@@ -1504,31 +1502,40 @@ static void _tmc_disable_etr_sink(struct coresight_device *csdev, bool flush)
		}
	}
out:
	mutex_unlock(&drvdata->mem_lock);
	dev_info(drvdata->dev, "TMC-ETR disabled\n");
}

static void tmc_disable_etr_sink(struct coresight_device *csdev)
{
	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);

	mutex_lock(&drvdata->mem_lock);
	_tmc_disable_etr_sink(csdev, true);
	mutex_unlock(&drvdata->mem_lock);
}

int tmc_etr_switch_mode(struct tmc_drvdata *drvdata, const char *out_mode)
{
	enum tmc_etr_out_mode new_mode, old_mode;

	mutex_lock(&drvdata->mem_lock);
	if (!strcmp(out_mode, str_tmc_etr_out_mode[TMC_ETR_OUT_MODE_MEM]))
		new_mode = TMC_ETR_OUT_MODE_MEM;
	else if (!strcmp(out_mode, str_tmc_etr_out_mode[TMC_ETR_OUT_MODE_USB]))
		new_mode = TMC_ETR_OUT_MODE_USB;
	else
	else {
		mutex_unlock(&drvdata->mem_lock);
		return -EINVAL;
	}

	if (new_mode == drvdata->out_mode)
	if (new_mode == drvdata->out_mode) {
		mutex_unlock(&drvdata->mem_lock);
		return 0;
	}

	if (drvdata->mode == CS_MODE_DISABLED) {
		drvdata->out_mode = new_mode;
		mutex_unlock(&drvdata->mem_lock);
		return 0;
	}

@@ -1541,8 +1548,11 @@ int tmc_etr_switch_mode(struct tmc_drvdata *drvdata, const char *out_mode)
		dev_err(drvdata->dev, "Switch to %s failed. Fall back to %s.\n",
			str_tmc_etr_out_mode[new_mode],
			str_tmc_etr_out_mode[old_mode]);
		mutex_unlock(&drvdata->mem_lock);
		return -EINVAL;
	}

	mutex_unlock(&drvdata->mem_lock);
	return 0;
}