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

Commit 0a99e4ce authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "coresight: csr: Add multiple CSR devices support"

parents e41ef00f 1a59c486
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -190,6 +190,20 @@ its hardware characteristcs.
	* reg-names: funnel-base-real: actual register space for the
	  duplicate funnel.

* Optional properties for CSRs:

	* qcom,usb-bam-support: boolean, indicates CSR has the ability to operate on
	  usb bam, include enable,disable and flush.

	* qcom,hwctrl-set-support: boolean, indicates CSR has the ability to operate on
	  to "HWCTRL" register.

	* qcom,set-byte-cntr-support:boolean, indicates CSR has the ability to operate on
	  to "BYTECNT" register.

	* qcom,timestamp-support:boolean, indicates CSR support sys interface to read
	  timestamp value.

Example:

1. Sinks
+5 −3
Original line number Diff line number Diff line
@@ -236,7 +236,7 @@ void tmc_etr_byte_cntr_stop(struct byte_cntr *byte_cntr_data)

	mutex_lock(&byte_cntr_data->byte_cntr_lock);
	byte_cntr_data->enable = false;
	coresight_csr_set_byte_cntr(0);
	coresight_csr_set_byte_cntr(byte_cntr_data->csr, 0);
	mutex_unlock(&byte_cntr_data->byte_cntr_lock);

}
@@ -250,7 +250,7 @@ static int tmc_etr_byte_cntr_release(struct inode *in, struct file *fp)
	mutex_lock(&byte_cntr_data->byte_cntr_lock);
	byte_cntr_data->read_active = false;

	coresight_csr_set_byte_cntr(0);
	coresight_csr_set_byte_cntr(byte_cntr_data->csr, 0);
	mutex_unlock(&byte_cntr_data->byte_cntr_lock);

	return 0;
@@ -268,7 +268,8 @@ static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp)
		return -EINVAL;
	}

	coresight_csr_set_byte_cntr(byte_cntr_data->block_size);
	coresight_csr_set_byte_cntr(byte_cntr_data->csr,
				byte_cntr_data->block_size);
	fp->private_data = byte_cntr_data;
	nonseekable_open(in, fp);
	byte_cntr_data->enable = true;
@@ -371,6 +372,7 @@ struct byte_cntr *byte_cntr_init(struct amba_device *adev,

	tmcdrvdata = drvdata;
	byte_cntr_data->byte_cntr_irq = byte_cntr_irq;
	byte_cntr_data->csr = drvdata->csr;
	atomic_set(&byte_cntr_data->irq_cnt, 0);
	init_waitqueue_head(&byte_cntr_data->wq);
	mutex_init(&byte_cntr_data->byte_cntr_lock);
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ struct byte_cntr {
	atomic_t		irq_cnt;
	wait_queue_head_t	wq;
	struct mutex		byte_cntr_lock;
	struct coresight_csr		*csr;
};

extern void tmc_etr_byte_cntr_start(struct byte_cntr *byte_cntr_data);
+120 −15
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, 2015-2016 The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2013, 2015-2016,2018 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -77,15 +77,31 @@ struct csr_drvdata {
	struct device		*dev;
	struct coresight_device	*csdev;
	uint32_t		blksize;
	struct coresight_csr		csr;
	spinlock_t		spin_lock;
	bool			usb_bam_support;
	bool			hwctrl_set_support;
	bool			set_byte_cntr_support;
	bool			timestamp_support;
};

static struct csr_drvdata *csrdrvdata;
static LIST_HEAD(csr_list);
#define to_csr_drvdata(c) container_of(c, struct csr_drvdata, csr)

void msm_qdss_csr_enable_bam_to_usb(void)
void msm_qdss_csr_enable_bam_to_usb(struct coresight_csr *csr)
{
	struct csr_drvdata *drvdata = csrdrvdata;
	struct csr_drvdata *drvdata;
	uint32_t usbbamctrl, usbflshctrl;
	unsigned long flags;

	if (csr == NULL)
		return;

	drvdata = to_csr_drvdata(csr);
	if (IS_ERR_OR_NULL(drvdata) || !drvdata->usb_bam_support)
		return;

	spin_lock_irqsave(&drvdata->spin_lock, flags);
	CSR_UNLOCK(drvdata);

	usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
@@ -102,14 +118,24 @@ void msm_qdss_csr_enable_bam_to_usb(void)
	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);

	CSR_LOCK(drvdata);
	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
}
EXPORT_SYMBOL(msm_qdss_csr_enable_bam_to_usb);

void msm_qdss_csr_disable_bam_to_usb(void)
void msm_qdss_csr_disable_bam_to_usb(struct coresight_csr *csr)
{
	struct csr_drvdata *drvdata = csrdrvdata;
	struct csr_drvdata *drvdata;
	uint32_t usbbamctrl;
	unsigned long flags;

	if (csr == NULL)
		return;

	drvdata = to_csr_drvdata(csr);
	if (IS_ERR_OR_NULL(drvdata) || !drvdata->usb_bam_support)
		return;

	spin_lock_irqsave(&drvdata->spin_lock, flags);
	CSR_UNLOCK(drvdata);

	usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
@@ -117,14 +143,24 @@ void msm_qdss_csr_disable_bam_to_usb(void)
	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);

	CSR_LOCK(drvdata);
	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
}
EXPORT_SYMBOL(msm_qdss_csr_disable_bam_to_usb);

void msm_qdss_csr_disable_flush(void)
void msm_qdss_csr_disable_flush(struct coresight_csr *csr)
{
	struct csr_drvdata *drvdata = csrdrvdata;
	struct csr_drvdata *drvdata;
	uint32_t usbflshctrl;
	unsigned long flags;

	if (csr == NULL)
		return;

	drvdata = to_csr_drvdata(csr);
	if (IS_ERR_OR_NULL(drvdata) || !drvdata->usb_bam_support)
		return;

	spin_lock_irqsave(&drvdata->spin_lock, flags);
	CSR_UNLOCK(drvdata);

	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
@@ -132,14 +168,25 @@ void msm_qdss_csr_disable_flush(void)
	csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL);

	CSR_LOCK(drvdata);
	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
}
EXPORT_SYMBOL(msm_qdss_csr_disable_flush);

int coresight_csr_hwctrl_set(uint64_t addr, uint32_t val)
int coresight_csr_hwctrl_set(struct coresight_csr *csr, uint64_t addr,
			 uint32_t val)
{
	struct csr_drvdata *drvdata = csrdrvdata;
	struct csr_drvdata *drvdata;
	int ret = 0;
	unsigned long flags;

	if (csr == NULL)
		return -EINVAL;

	drvdata = to_csr_drvdata(csr);
	if (IS_ERR_OR_NULL(drvdata) || !drvdata->hwctrl_set_support)
		return -EINVAL;

	spin_lock_irqsave(&drvdata->spin_lock, flags);
	CSR_UNLOCK(drvdata);

	if (addr == (drvdata->pbase + CSR_STMEXTHWCTRL0))
@@ -154,15 +201,24 @@ int coresight_csr_hwctrl_set(uint64_t addr, uint32_t val)
		ret = -EINVAL;

	CSR_LOCK(drvdata);

	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
	return ret;
}
EXPORT_SYMBOL(coresight_csr_hwctrl_set);

void coresight_csr_set_byte_cntr(uint32_t count)
void coresight_csr_set_byte_cntr(struct coresight_csr *csr, uint32_t count)
{
	struct csr_drvdata *drvdata = csrdrvdata;
	struct csr_drvdata *drvdata;
	unsigned long flags;

	if (csr == NULL)
		return;

	drvdata = to_csr_drvdata(csr);
	if (IS_ERR_OR_NULL(drvdata) || !drvdata->set_byte_cntr_support)
		return;

	spin_lock_irqsave(&drvdata->spin_lock, flags);
	CSR_UNLOCK(drvdata);

	csr_writel(drvdata, count, CSR_BYTECNTVAL);
@@ -171,9 +227,23 @@ void coresight_csr_set_byte_cntr(uint32_t count)
	mb();

	CSR_LOCK(drvdata);
	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
}
EXPORT_SYMBOL(coresight_csr_set_byte_cntr);

struct coresight_csr *coresight_csr_get(const char *name)
{
	struct coresight_csr *csr;

	list_for_each_entry(csr, &csr_list, link) {
		if (!strcmp(csr->name, name))
			return csr;
	}

	return ERR_PTR(-EINVAL);
}
EXPORT_SYMBOL(coresight_csr_get);

static int csr_probe(struct platform_device *pdev)
{
	int ret;
@@ -208,6 +278,34 @@ static int csr_probe(struct platform_device *pdev)
	if (ret)
		drvdata->blksize = BLKSIZE_256;

	drvdata->usb_bam_support = of_property_read_bool(pdev->dev.of_node,
						"qcom,usb-bam-support");
	if (!drvdata->usb_bam_support)
		dev_dbg(dev, "usb_bam support handled by other subsystem\n");
	else
		dev_dbg(dev, "usb_bam operation supported\n");

	drvdata->hwctrl_set_support = of_property_read_bool(pdev->dev.of_node,
						"qcom,hwctrl-set-support");
	if (!drvdata->hwctrl_set_support)
		dev_dbg(dev, "hwctrl_set_support handled by other subsystem\n");
	else
		dev_dbg(dev, "hwctrl_set_support operation supported\n");

	drvdata->set_byte_cntr_support = of_property_read_bool(
			pdev->dev.of_node, "qcom,set-byte-cntr-support");
	if (!drvdata->set_byte_cntr_support)
		dev_dbg(dev, "set byte_cntr_support handled by other subsystem\n");
	else
		dev_dbg(dev, "set_byte_cntr_support operation supported\n");

	drvdata->timestamp_support = of_property_read_bool(pdev->dev.of_node,
						"qcom,timestamp-support");
	if (!drvdata->timestamp_support)
		dev_dbg(dev, "timestamp_support handled by other subsystem\n");
	else
		dev_dbg(dev, "timestamp_support operation supported\n");

	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
	if (!desc)
		return -ENOMEM;
@@ -219,16 +317,23 @@ static int csr_probe(struct platform_device *pdev)
		return PTR_ERR(drvdata->csdev);

	/* Store the driver data pointer for use in exported functions */
	csrdrvdata = drvdata;
	dev_info(dev, "CSR initialized\n");
	spin_lock_init(&drvdata->spin_lock);
	drvdata->csr.name = ((struct coresight_platform_data *)
					 (pdev->dev.platform_data))->name;
	list_add_tail(&drvdata->csr.link, &csr_list);

	dev_info(dev, "CSR initialized: %s\n", drvdata->csr.name);
	return 0;
}

static int csr_remove(struct platform_device *pdev)
{
	unsigned long flags;
	struct csr_drvdata *drvdata = platform_get_drvdata(pdev);

	spin_lock_irqsave(&drvdata->spin_lock, flags);
	coresight_unregister(drvdata->csdev);
	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
	return 0;
}

+15 −2
Original line number Diff line number Diff line
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -42,6 +42,8 @@ struct hwevent_drvdata {
	struct regulator			**hreg;
	int					nr_hmux;
	struct hwevent_mux			*hmux;
	struct coresight_csr			*csr;
	const char				*csr_name;
};

static int hwevent_enable(struct hwevent_drvdata *drvdata)
@@ -132,7 +134,7 @@ static ssize_t hwevent_store_setreg(struct device *dev,
	}

	if (i == drvdata->nr_hmux) {
		ret = coresight_csr_hwctrl_set(addr, val);
		ret = coresight_csr_hwctrl_set(drvdata->csr, addr,  val);
		if (ret) {
			dev_err(dev, "invalid mux control register address\n");
			ret = -EINVAL;
@@ -185,6 +187,17 @@ static int hwevent_probe(struct platform_device *pdev)
	drvdata->dev = &pdev->dev;
	platform_set_drvdata(pdev, drvdata);

	ret = of_get_coresight_csr_name(dev->of_node, &drvdata->csr_name);
	if (ret) {
		dev_err(dev, "No csr data\n");
	} else{
		drvdata->csr = coresight_csr_get(drvdata->csr_name);
		if (IS_ERR(drvdata->csr)) {
			dev_err(dev, "failed to get csr, defer probe\n");
			return -EPROBE_DEFER;
		}
	}

	drvdata->nr_hmux = of_property_count_strings(pdev->dev.of_node,
						     "reg-names");

Loading