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

Commit 5648b38c authored by Mao Jinlong's avatar Mao Jinlong
Browse files

tmc-etr: Call usb_qdss_open after all etr settings are done



As there is etr status check in usb notifier, call usb_qdss_open after
all etr settings are done to avoid the race condition between etr status
and usb notifier call.

Change-Id: Ib4b5ca8001ca135539e0d55cbb86cb061b564e9d
Signed-off-by: default avatarMao Jinlong <jinlmao@codeaurora.org>
parent 55624c7f
Loading
Loading
Loading
Loading
+29 −31
Original line number Diff line number Diff line
@@ -1455,7 +1455,9 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
			|| !drvdata->usbch) {
		spin_unlock_irqrestore(&drvdata->spinlock, flags);

		if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM) {
		if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM ||
			(drvdata->byte_cntr->sw_usb &&
			drvdata->out_mode == TMC_ETR_OUT_MODE_USB)) {
			/*
			 * ETR DDR memory is not allocated until user enables
			 * tmc at least once. If user specifies different ETR
@@ -1471,38 +1473,13 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
			}
			coresight_cti_map_trigout(drvdata->cti_flush, 3, 0);
			coresight_cti_map_trigin(drvdata->cti_reset, 0, 0);
		} else if (drvdata->byte_cntr->sw_usb) {
			if (!drvdata->etr_buf) {
				free_buf = new_buf =
				tmc_etr_setup_sysfs_buf(drvdata);
				if (IS_ERR(new_buf)) {
					return -ENOMEM;
				}
			}
			coresight_cti_map_trigout(drvdata->cti_flush, 3, 0);
			coresight_cti_map_trigin(drvdata->cti_reset, 0, 0);

			drvdata->usbch = usb_qdss_open("qdss_mdm",
						drvdata->byte_cntr,
						usb_bypass_notifier);
			if (IS_ERR_OR_NULL(drvdata->usbch)) {
				dev_err(drvdata->dev, "usb_qdss_open failed\n");
				return -ENODEV;
			}
		} else {
			drvdata->usbch = usb_qdss_open("qdss", drvdata,
							usb_notifier);
			if (IS_ERR_OR_NULL(drvdata->usbch)) {
				dev_err(drvdata->dev, "usb_qdss_open failed\n");
				return -ENODEV;
			}
		}
		spin_lock_irqsave(&drvdata->spinlock, flags);
	}

	if (drvdata->reading || drvdata->mode == CS_MODE_PERF) {
		ret = -EBUSY;
		goto out;
		goto unlock_out;
	}

	/*
@@ -1512,7 +1489,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
	 */
	if (drvdata->mode == CS_MODE_SYSFS) {
		atomic_inc(csdev->refcnt);
		goto out;
		goto unlock_out;
	}

	/*
@@ -1530,16 +1507,37 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
	     && drvdata->byte_cntr->sw_usb)) {
		ret = tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf);
		if (ret)
			goto out;
			goto unlock_out;
	}

	drvdata->mode = CS_MODE_SYSFS;
	drvdata->enable = true;

	spin_unlock_irqrestore(&drvdata->spinlock, flags);
	if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
		if (drvdata->byte_cntr->sw_usb)
			drvdata->usbch = usb_qdss_open("qdss_mdm",
					drvdata->byte_cntr,
					usb_bypass_notifier);
		else
			drvdata->usbch = usb_qdss_open("qdss", drvdata,
						usb_notifier);

		if (IS_ERR_OR_NULL(drvdata->usbch)) {
			dev_err(&csdev->dev, "usb_qdss_open failed\n");
			drvdata->enable = false;
			drvdata->mode = CS_MODE_DISABLED;
			ret = -ENODEV;
		}
	}

	atomic_inc(csdev->refcnt);
	goto out;

	drvdata->enable = true;
out:
unlock_out:
	spin_unlock_irqrestore(&drvdata->spinlock, flags);

out:
	/* Free memory outside the spinlock if need be */
	if (free_buf)
		tmc_etr_free_sysfs_buf(free_buf);