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

Commit 1a59c486 authored by Mulu He's avatar Mulu He Committed by muluhe
Browse files

coresight: csr: Add multiple CSR devices support



Add a CSR device list in CSR driver to support multiple CSR devices. CSR
device structure is initialized in probe and added to the list. Add CSR
device structure as parameter of CSR function. Change the caller of CSR
functions to align with this change.

Change-Id: Id904633510a82fe5fcc574d12e9b15ec5ecdfa05
Signed-off-by: default avatarMulu He <muluhe@codeaurora.org>
parent d0edcda0
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
+6 −4
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-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
@@ -229,7 +229,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);

}
@@ -243,7 +243,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;
@@ -261,7 +261,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;
@@ -364,6 +365,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