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

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

Merge "coresight-tmc: Use sysfs_buf for byte-cntr and sw usb cases"

parents 0f64b0f2 b5b6e583
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ static struct tmc_drvdata *tmcdrvdata;
static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos,
			       size_t bytes, size_t *len, char **bufp)
{
	struct etr_buf *etr_buf = tmcdrvdata->etr_buf;
	struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf;
	size_t actual;

	if (*len >= bytes)
@@ -60,7 +60,7 @@ static irqreturn_t etr_handler(int irq, void *data)
static void tmc_etr_flush_bytes(loff_t *ppos, size_t bytes, size_t *len)
{
	uint32_t rwp = 0;
	dma_addr_t paddr = tmcdrvdata->etr_buf->hwaddr;
	dma_addr_t paddr = tmcdrvdata->sysfs_buf->hwaddr;

	rwp = readl_relaxed(tmcdrvdata->base + TMC_RWP);

@@ -200,7 +200,7 @@ int usb_bypass_start(struct byte_cntr *byte_cntr_data)
	}

	atomic_set(&byte_cntr_data->usb_free_buf, USB_BUF_NUM);
	byte_cntr_data->offset = tmcdrvdata->etr_buf->offset;
	byte_cntr_data->offset = tmc_sg_get_rwp_offset(tmcdrvdata);
	byte_cntr_data->read_active = true;
	/*
	 * IRQ is a '8- byte' counter and to observe interrupt at
@@ -321,7 +321,7 @@ static int usb_transfer_small_packet(struct qdss_request *usb_req,
			struct byte_cntr *drvdata, size_t *small_size)
{
	int ret = 0;
	struct etr_buf *etr_buf = tmcdrvdata->etr_buf;
	struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf;
	size_t req_size, actual;
	long w_offset;

@@ -346,7 +346,8 @@ static int usb_transfer_small_packet(struct qdss_request *usb_req,
		drvdata->usb_req = usb_req;
		req_size -= actual;

		if ((drvdata->offset + actual) >= tmcdrvdata->size)
		if ((drvdata->offset + actual) >=
				tmcdrvdata->sysfs_buf->size)
			drvdata->offset = 0;
		else
			drvdata->offset += actual;
@@ -383,8 +384,9 @@ static void usb_read_work_fn(struct work_struct *work)
{
	int ret, i, seq = 0;
	struct qdss_request *usb_req = NULL;
	struct etr_buf *etr_buf = tmcdrvdata->etr_buf;
	struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf;
	size_t actual, req_size, req_sg_num, small_size = 0;
	size_t actual_total = 0;
	char *buf;
	struct byte_cntr *drvdata =
		container_of(work, struct byte_cntr, read_work);
@@ -415,6 +417,7 @@ static void usb_read_work_fn(struct work_struct *work)

		req_size = USB_BLK_SIZE - small_size;
		small_size = 0;
		actual_total = 0;

		if (req_size > 0) {
			seq++;
@@ -455,13 +458,14 @@ static void usb_read_work_fn(struct work_struct *work)
					sg_mark_end(&usb_req->sg[i]);

				if ((drvdata->offset + actual) >=
					tmcdrvdata->size)
					tmcdrvdata->sysfs_buf->size)
					drvdata->offset = 0;
				else
					drvdata->offset += actual;
				actual_total += actual;
			}

			usb_req->length = req_size;
			usb_req->length = actual_total;
			drvdata->usb_req = usb_req;
			usb_req->num_sgs = i;

+50 −52
Original line number Diff line number Diff line
@@ -45,6 +45,9 @@ struct etr_perf_buffer {
/* Lower limit for ETR hardware buffer */
#define TMC_ETR_PERF_MIN_BUF_SIZE	SZ_1M

/* SW USB reserved memory size */
#define TMC_ETR_SW_USB_BUF_SIZE SZ_32M

/*
 * The TMC ETR SG has a page size of 4K. The SG table contains pointers
 * to 4KB buffers. However, the OS may use a PAGE_SIZE different from
@@ -1088,6 +1091,11 @@ ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata,
static struct etr_buf *
tmc_etr_setup_sysfs_buf(struct tmc_drvdata *drvdata)
{
	if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB
		&& drvdata->byte_cntr->sw_usb)
		return tmc_alloc_etr_buf(drvdata, TMC_ETR_SW_USB_BUF_SIZE,
				 0, cpu_to_node(0), NULL);
	else
		return tmc_alloc_etr_buf(drvdata, drvdata->size,
				 0, cpu_to_node(0), NULL);
}
@@ -1447,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
@@ -1463,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;
	}

	/*
@@ -1504,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;
	}

	/*
@@ -1522,16 +1507,40 @@ 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;
			if (drvdata->byte_cntr->sw_usb)
				tmc_etr_disable_hw(drvdata);
			ret = -ENODEV;
			goto out;
		}
	}

	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);
@@ -2036,29 +2045,18 @@ static int _tmc_disable_etr_sink(struct coresight_device *csdev,

	spin_unlock_irqrestore(&drvdata->spinlock, flags);

	if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB
		&& drvdata->byte_cntr->sw_usb) {
	if ((drvdata->out_mode == TMC_ETR_OUT_MODE_USB
		&& drvdata->byte_cntr->sw_usb)
		|| drvdata->out_mode == TMC_ETR_OUT_MODE_MEM) {
		if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM)
			tmc_etr_byte_cntr_stop(drvdata->byte_cntr);
		else {
			usb_bypass_stop(drvdata->byte_cntr);
			flush_workqueue(drvdata->byte_cntr->usb_wq);
			drvdata->usbch = NULL;
		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;
		}
	}

	if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM) {
		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;
		}
	}
out:
	dev_info(drvdata->dev, "TMC-ETR disabled\n");