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: Mao Jinlong <jinlmao@codeaurora.org>
This commit is contained in:
Mao Jinlong 2020-07-10 15:37:21 +08:00 • committed by Gerrit - the friendly Code Review server
commit c4acfc2dc9

View file

@ -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
@ -1470,38 +1472,13 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
return -ENOMEM;
coresight_cti_map_trigout(drvdata->cti_flush, 3, 0);
coresight_cti_map_trigin(drvdata->cti_reset, 2, 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(&csdev->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(&csdev->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;
}
/*
@ -1511,7 +1488,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;
}
/*
@ -1527,24 +1504,48 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
(drvdata->out_mode == TMC_ETR_OUT_MODE_USB
&& drvdata->byte_cntr->sw_usb)) {
ret = tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf);
if (ret)
goto unlock_out;
}
if (!ret) {
drvdata->mode = CS_MODE_SYSFS;
atomic_inc(csdev->refcnt);
}
drvdata->mode = CS_MODE_SYSFS;
drvdata->enable = true;
out:
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;
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);
if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM)
tmc_etr_byte_cntr_start(drvdata->byte_cntr);
if (!ret) {
if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM)
tmc_etr_byte_cntr_start(drvdata->byte_cntr);
if (!ret)
dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
dev_info(&csdev->dev, "TMC-ETR enabled\n");
}
return ret;
}