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

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

Merge changes...

Merge changes Ie7467048,I4fcb42f2,Ide3da745,I18e8688c,I0c225538,Id005089c,I0fc7b3ca,I340ebf20,Iec8df425,Ib83e1bd5,Ia1396b08,Id35f625f,Ib0a8b14a,Idd3dcfd0,Ie4c87252,I0e145d65,I5f034574,Ia5bf274e,Ie1b98c15,I6c0d9368 into msm-next

* changes:
  soc: qcom: Add a snapshot of Remote QDSS driver
  coresight: enable stm logging for trace events, marker and printk
  Coresight: add support for device names
  coresight: tmc: add support to configure etr memory size
  coresight: tmc: Change ETR DDR transaction configuration
  coresight: funnel: add support for duplicating funnel devices
  coresight: etm4x: Fix ETM probe when booting without all cores
  coresight-etm4x: enable ETM driver on SDM845
  coresight: stm: Fix missing disable flag when disabling STM
  coresight: Set clk rate for all coresight devices
  coresight: Remove recursive mutex usage
  coresight: add node to reset all coresight devices
  driver core: device.h: Add WO attribute macro
  coresight: add support to enable multiple coresight paths
  coresight: csr: Add snapshot of Coresight CSR driver
  coresight: Remote-etm: Add snapshot of Remote ETM driver
  coresight: dummy: Add snapshot of Coresight Dummy driver
  coresight: hwevent: Add snapshot of Coresight HWEVENT driver
  coresight: Add snapshot of Coresight TPDM and TPDA driver
  coresight: ost: Add snapshot of Coresight OST driver
parents f3f86a58 3b444595
Loading
Loading
Loading
Loading
+107 −0
Original line number Diff line number Diff line
@@ -73,6 +73,12 @@ its hardware characteristcs.
	  AMBA markee):
		- "arm,coresight-replicator"
		- "arm,coresight-cti"
		- "qcom,coresight-tpda"
		- "qcom,coresight-tpdm"
		- "qcom,coresight-hwevent"
		- "qcom,coresight-dummy"
		- "qcom,coresight-remote-etm"
		- "qcom,coresight-csr"

	* port or ports: same as above.

@@ -101,6 +107,57 @@ its hardware characteristcs.
	* arm,sg-enable : indicates whether scatter gather feature is enabled
	  by default for TMC ETR configuration.

* Required property for TPDAs:

	* qcom,tpda-atid: must be present. Specifies the ATID for TPDA.

* Optional properties for TPDAs:

	* qcom,bc-elem-size: specifies the BC element size supported by each
	  monitor connected to the aggregator on each port. Should be specified
	  in pairs (port, bc element size).

	* qcom,tc-elem-size: specifies the TC element size supported by each
	  monitor connected to the aggregator on each port. Should be specified
	  in pairs (port, tc element size).

	* qcom,dsb-elem-size: specifies the DSB element size supported by each
	  monitor connected to the aggregator on each port. Should be specified
	  in pairs (port, dsb element size).

	* qcom,cmb-elem-size: specifies the CMB element size supported by each
	  monitor connected to the aggregator on each port. Should be specified
	  in pairs (port, cmb element size).

* Optional properties for TPDM:

	* qcom,clk-enable: specifies whether additional clock bit needs to be
	  set for M4M TPDM.

	* qcom,msr-fix-req: boolean, indicating if MSRs need to be programmed
	  after enabling the subunit.

* Required property for Remote ETMs:

	* qcom,inst-id: must be present. QMI instance id for remote ETMs.

* Optional properties for funnels:

	* qcom,duplicate-funnel: boolean, indicates its a duplicate of an
	  existing funnel. Funnel devices are now capable of supporting
	  multiple-input and multiple-output configuration with in built
	  hardware filtering for TPDM devices. Each set of input-output
	  combination is treated as independent funnel device.
	  funnel-base-dummy and funnel-base-real reg-names must be specified
	  when this property is enabled.

	* reg-names: funnel-base-dummy: dummy register space used by a
	  duplicate funnel. Should be a valid register address space that
	  no other device is using.

	* reg-names: funnel-base-real: actual register space for the
	  duplicate funnel.

Example:

1. Sinks
@@ -216,6 +273,40 @@ Example:
		};
	};

	tpda_mss: tpda@7043000 {
		compatible = "qcom,coresight-tpda", "arm,primecell";
		reg = <0x7043000 0x1000>;
		reg-names = "tpda-base";

		coresight-name = "coresight-tpda-mss";

		qcom,tpda-atid = <67>;
		qcom,dsb-elem-size = <0 32>;
		qcom,cmb-elem-size = <0 32>;

		clocks = <&clock_aop qdss_clk>;
		clock-names = "apb_pclk";

		ports {
			#address-cells = <1>;
			#size-cells = <0>;
			port@0 {
				reg = <0>;
				tpda_mss_out_funnel_in1: endpoint {
				remote-endpoint =
					<&funnel_in1_in_tpda_mss>;
				};
			};
			port@1 {
				reg = <0>;
				tpda_mss_in_tpdm_mss: endpoint {
				slave-mode;
				remote-endpoint =
					<&tpdm_mss_out_tpda_mss>;
				};
			};
		};
	};
3. Sources
	ptm@2201c000 {
		compatible = "arm,coresight-etm3x", "arm,primecell";
@@ -261,5 +352,21 @@ Example:
		};
	};

	tpdm_mss: tpdm@7042000 {
		compatible = "qcom,coresight-tpdm", "arm,primecell";
		reg = <0x7042000 0x1000>;
		reg-names = "tpdm-base";

		coresight-name = "coresight-tpdm-mss";

		clocks = <&clock_aop qdss_clk>;
		clock-names = "apb_pclk";

		port{
			tpdm_mss_out_tpda_mss: endpoint {
				remote-endpoint = <&tpda_mss_in_tpdm_mss>;
		};
	};
};
[1]. There is currently two version of STM: STM32 and STM500.  Both
have the same HW interface and as such don't need an explicit binding name.
+78 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ config CORESIGHT_LINKS_AND_SINKS
config CORESIGHT_LINK_AND_SINK_TMC
	bool "Coresight generic TMC driver"
	depends on CORESIGHT_LINKS_AND_SINKS
	select CORESIGHT_CSR
	help
	  This enables support for the Trace Memory Controller driver.
	  Depending on its configuration the device can act as a link (embedded
@@ -83,6 +84,7 @@ config CORESIGHT_STM
	depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
	select CORESIGHT_LINKS_AND_SINKS
	select STM
	select CORESIGHT_OST
	help
	  This driver provides support for hardware assisted software
	  instrumentation based tracing. This is primarily used for
@@ -110,4 +112,80 @@ config CORESIGHT_CTI
	  used to input or output i.e. pass cross trigger events from one
	  hardware component to another. It can also be used to pass
	  software generated events.

config CORESIGHT_OST
	bool "CoreSight OST framework"
	depends on CORESIGHT_STM
	help
	  This driver enables the support for Open System Trace packets in STM.
	  This is primarily intended to be used as a layer on top of underlying
	  physical byte transport mechanisms.

config CORESIGHT_TPDA
	bool "CoreSight Trace, Profiling & Diagnostics Aggregator driver"
	help
	  This driver provides support for configuring aggregator. This is
	  primarily useful for pulling the data sets from one or more
	  attached monitors and pushing the resultant data out. Multiple
	  monitors are connected on different input ports of TPDA.

config CORESIGHT_TPDM
	bool "CoreSight Trace, Profiling & Diagnostics Monitor driver"
	help
	  This driver provides support for configuring monitor. Monitors are
	  primarily responsible for data set collection and support the
	  ability to collect any permutation of data set types. Monitors are
	  also responsible for interaction with system cross triggering.

config CORESIGHT_TPDM_DEFAULT_ENABLE
	bool "Turn on TPDM tracing by default"
	depends on CORESIGHT_TPDM
	help
	  Turns on CoreSight TPDM tracing for different data set types by
	  default. Otherwise, tracing is disabled by default but can be
	  enabled via sysfs.

	  If unsure, say 'N' here to avoid potential power and performance
	  penalty.

config CORESIGHT_HWEVENT
	bool "CoreSight Hardware Event driver"
	depends on CORESIGHT_STM
	select CORESIGHT_CSR
	help
	  This driver provides support for monitoring and tracing CoreSight
	  Hardware Event across STM interface. It configures Coresight
	  Hardware Event mux control registers to select hardware events
	  based on user input.

config CORESIGHT_DUMMY
	bool "Dummy driver support"
	help
	  Enables support for dummy driver. Dummy driver can be
	  used for CoreSight sources/sinks that are owned and configured by some other
	  subsystem and use Linux drivers to configure rest of trace path.

config CORESIGHT_REMOTE_ETM
	bool "Remote processor ETM trace support"
	depends on MSM_QMI_INTERFACE
	help
	  Enables support for ETM trace collection on remote processor using
	  CoreSight framework. Enabling this will allow turning on ETM
	  tracing on remote processor via sysfs by configuring the required
	  CoreSight components.

config CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE
	int "default enable ETM for Remote processor based on instance id"
	depends on CORESIGHT_REMOTE_ETM
	help
	  Support for enabling separated Remote processor ETM tracing. Depends
	  on if instance id bit is set.

config CORESIGHT_CSR
	bool "CoreSight Slave Register driver"
	help
	  This driver provides support for CoreSight Slave Register block
	  that hosts miscellaneous configuration registers.
	  Those configuration registers can be used to control, various
	  coresight configurations.
endif
+7 −0
Original line number Diff line number Diff line
@@ -18,3 +18,10 @@ obj-$(CONFIG_CORESIGHT_DYNAMIC_REPLICATOR) += coresight-dynamic-replicator.o
obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
obj-$(CONFIG_CORESIGHT_OST) += coresight-ost.o
obj-$(CONFIG_CORESIGHT_TPDA) += coresight-tpda.o
obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o
obj-$(CONFIG_CORESIGHT_HWEVENT) += coresight-hwevent.o
obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o
obj-$(CONFIG_CORESIGHT_REMOTE_ETM) += coresight-remote-etm.o
obj-$(CONFIG_CORESIGHT_CSR) += coresight-csr.o
+263 −0
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, 2015-2017 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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/coresight.h>

#include "coresight-priv.h"

#define csr_writel(drvdata, val, off)	__raw_writel((val), drvdata->base + off)
#define csr_readl(drvdata, off)		__raw_readl(drvdata->base + off)

#define CSR_LOCK(drvdata)						\
do {									\
	mb(); /* ensure configuration take effect before we lock it */	\
	csr_writel(drvdata, 0x0, CORESIGHT_LAR);			\
} while (0)
#define CSR_UNLOCK(drvdata)						\
do {									\
	csr_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
	mb(); /* ensure unlock take effect before we configure */	\
} while (0)

#define CSR_SWDBGPWRCTRL	(0x000)
#define CSR_SWDBGPWRACK		(0x004)
#define CSR_SWSPADREG0		(0x008)
#define CSR_SWSPADREG1		(0x00C)
#define CSR_STMTRANSCTRL	(0x010)
#define CSR_STMAWIDCTRL		(0x014)
#define CSR_STMCHNOFST0		(0x018)
#define CSR_STMCHNOFST1		(0x01C)
#define CSR_STMEXTHWCTRL0	(0x020)
#define CSR_STMEXTHWCTRL1	(0x024)
#define CSR_STMEXTHWCTRL2	(0x028)
#define CSR_STMEXTHWCTRL3	(0x02C)
#define CSR_USBBAMCTRL		(0x030)
#define CSR_USBFLSHCTRL		(0x034)
#define CSR_TIMESTAMPCTRL	(0x038)
#define CSR_AOTIMEVAL0		(0x03C)
#define CSR_AOTIMEVAL1		(0x040)
#define CSR_QDSSTIMEVAL0	(0x044)
#define CSR_QDSSTIMEVAL1	(0x048)
#define CSR_QDSSTIMELOAD0	(0x04C)
#define CSR_QDSSTIMELOAD1	(0x050)
#define CSR_DAPMSAVAL		(0x054)
#define CSR_QDSSCLKVOTE		(0x058)
#define CSR_QDSSCLKIPI		(0x05C)
#define CSR_QDSSPWRREQIGNORE	(0x060)
#define CSR_QDSSSPARE		(0x064)
#define CSR_IPCAT		(0x068)
#define CSR_BYTECNTVAL		(0x06C)

#define BLKSIZE_256		0
#define BLKSIZE_512		1
#define BLKSIZE_1024		2
#define BLKSIZE_2048		3

struct csr_drvdata {
	void __iomem		*base;
	phys_addr_t		pbase;
	struct device		*dev;
	struct coresight_device	*csdev;
	uint32_t		blksize;
};

static struct csr_drvdata *csrdrvdata;

void msm_qdss_csr_enable_bam_to_usb(void)
{
	struct csr_drvdata *drvdata = csrdrvdata;
	uint32_t usbbamctrl, usbflshctrl;

	CSR_UNLOCK(drvdata);

	usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
	usbbamctrl = (usbbamctrl & ~0x3) | drvdata->blksize;
	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);

	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
	usbflshctrl = (usbflshctrl & ~0x3FFFC) | (0xFFFF << 2);
	csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL);
	usbflshctrl |= 0x2;
	csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL);

	usbbamctrl |= 0x4;
	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);

	CSR_LOCK(drvdata);
}
EXPORT_SYMBOL(msm_qdss_csr_enable_bam_to_usb);

void msm_qdss_csr_disable_bam_to_usb(void)
{
	struct csr_drvdata *drvdata = csrdrvdata;
	uint32_t usbbamctrl;

	CSR_UNLOCK(drvdata);

	usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
	usbbamctrl &= (~0x4);
	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);

	CSR_LOCK(drvdata);
}
EXPORT_SYMBOL(msm_qdss_csr_disable_bam_to_usb);

void msm_qdss_csr_disable_flush(void)
{
	struct csr_drvdata *drvdata = csrdrvdata;
	uint32_t usbflshctrl;

	CSR_UNLOCK(drvdata);

	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
	usbflshctrl &= ~0x2;
	csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL);

	CSR_LOCK(drvdata);
}
EXPORT_SYMBOL(msm_qdss_csr_disable_flush);

int coresight_csr_hwctrl_set(uint64_t addr, uint32_t val)
{
	struct csr_drvdata *drvdata = csrdrvdata;
	int ret = 0;

	CSR_UNLOCK(drvdata);

	if (addr == (drvdata->pbase + CSR_STMEXTHWCTRL0))
		csr_writel(drvdata, val, CSR_STMEXTHWCTRL0);
	else if (addr == (drvdata->pbase + CSR_STMEXTHWCTRL1))
		csr_writel(drvdata, val, CSR_STMEXTHWCTRL1);
	else if (addr == (drvdata->pbase + CSR_STMEXTHWCTRL2))
		csr_writel(drvdata, val, CSR_STMEXTHWCTRL2);
	else if (addr == (drvdata->pbase + CSR_STMEXTHWCTRL3))
		csr_writel(drvdata, val, CSR_STMEXTHWCTRL3);
	else
		ret = -EINVAL;

	CSR_LOCK(drvdata);

	return ret;
}
EXPORT_SYMBOL(coresight_csr_hwctrl_set);

void coresight_csr_set_byte_cntr(uint32_t count)
{
	struct csr_drvdata *drvdata = csrdrvdata;

	CSR_UNLOCK(drvdata);

	csr_writel(drvdata, count, CSR_BYTECNTVAL);

	/* make sure byte count value is written */
	mb();

	CSR_LOCK(drvdata);
}
EXPORT_SYMBOL(coresight_csr_set_byte_cntr);

static int csr_probe(struct platform_device *pdev)
{
	int ret;
	struct device *dev = &pdev->dev;
	struct coresight_platform_data *pdata;
	struct csr_drvdata *drvdata;
	struct resource *res;
	struct coresight_desc *desc;

	pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
	if (IS_ERR(pdata))
		return PTR_ERR(pdata);
	pdev->dev.platform_data = pdata;

	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;
	drvdata->dev = &pdev->dev;
	platform_set_drvdata(pdev, drvdata);

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr-base");
	if (!res)
		return -ENODEV;
	drvdata->pbase = res->start;

	drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
	if (!drvdata->base)
		return -ENOMEM;

	ret = of_property_read_u32(pdev->dev.of_node, "qcom,blk-size",
			&drvdata->blksize);
	if (ret)
		drvdata->blksize = BLKSIZE_256;

	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
	if (!desc)
		return -ENOMEM;
	desc->type = CORESIGHT_DEV_TYPE_NONE;
	desc->pdata = pdev->dev.platform_data;
	desc->dev = &pdev->dev;
	drvdata->csdev = coresight_register(desc);
	if (IS_ERR(drvdata->csdev))
		return PTR_ERR(drvdata->csdev);

	/* Store the driver data pointer for use in exported functions */
	csrdrvdata = drvdata;
	dev_info(dev, "CSR initialized\n");
	return 0;
}

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

	coresight_unregister(drvdata->csdev);
	return 0;
}

static const struct of_device_id csr_match[] = {
	{.compatible = "qcom,coresight-csr"},
	{}
};

static struct platform_driver csr_driver = {
	.probe          = csr_probe,
	.remove         = csr_remove,
	.driver         = {
		.name   = "coresight-csr",
		.owner	= THIS_MODULE,
		.of_match_table = csr_match,
	},
};

static int __init csr_init(void)
{
	return platform_driver_register(&csr_driver);
}
module_init(csr_init);

static void __exit csr_exit(void)
{
	platform_driver_unregister(&csr_driver);
}
module_exit(csr_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("CoreSight CSR driver");
+171 −0
Original line number Diff line number Diff line
/* Copyright (c) 2016-2017, 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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/coresight.h>
#include <linux/of.h>

#define DUMMY_TRACE_ID_START	256

struct dummy_drvdata {
	struct device			*dev;
	struct coresight_device		*csdev;
	int				traceid;
};

static int dummy_source_enable(struct coresight_device *csdev,
			       struct perf_event *event, u32 mode)
{
	struct dummy_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);

	dev_info(drvdata->dev, "Dummy source enabled\n");

	return 0;
}

static void dummy_source_disable(struct coresight_device *csdev,
				 struct perf_event *event)
{
	struct dummy_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);

	dev_info(drvdata->dev, "Dummy source disabled\n");
}

static int dummy_sink_enable(struct coresight_device *csdev, u32 mode)
{
	struct dummy_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);

	dev_info(drvdata->dev, "Dummy sink enabled\n");

	return 0;
}

static void dummy_sink_disable(struct coresight_device *csdev)
{
	struct dummy_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);

	dev_info(drvdata->dev, "Dummy sink disabled\n");
}

static int dummy_trace_id(struct coresight_device *csdev)
{
	struct dummy_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);

	return drvdata->traceid;
}

static const struct coresight_ops_source dummy_source_ops = {
	.trace_id	= dummy_trace_id,
	.enable		= dummy_source_enable,
	.disable	= dummy_source_disable,
};

static const struct coresight_ops_sink dummy_sink_ops = {
	.enable		= dummy_sink_enable,
	.disable	= dummy_sink_disable,
};

static const struct coresight_ops dummy_cs_ops = {
	.source_ops	= &dummy_source_ops,
	.sink_ops	= &dummy_sink_ops,
};

static int dummy_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct coresight_platform_data *pdata;
	struct dummy_drvdata *drvdata;
	struct coresight_desc *desc;
	static int traceid = DUMMY_TRACE_ID_START;

	pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
	if (IS_ERR(pdata))
		return PTR_ERR(pdata);
	pdev->dev.platform_data = pdata;

	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	drvdata->dev = &pdev->dev;
	platform_set_drvdata(pdev, drvdata);

	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
	if (!desc)
		return -ENOMEM;

	drvdata->traceid = traceid++;

	if (of_property_read_bool(pdev->dev.of_node, "qcom,dummy-source")) {
		desc->type = CORESIGHT_DEV_TYPE_SOURCE;
		desc->subtype.source_subtype =
					CORESIGHT_DEV_SUBTYPE_SOURCE_PROC;
	} else if (of_property_read_bool(pdev->dev.of_node,
					 "qcom,dummy-sink")) {
		desc->type = CORESIGHT_DEV_TYPE_SINK;
		desc->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER;
	} else {
		dev_info(dev, "Device type not set.\n");
		return -EINVAL;
	}

	desc->ops = &dummy_cs_ops;
	desc->pdata = pdev->dev.platform_data;
	desc->dev = &pdev->dev;
	drvdata->csdev = coresight_register(desc);
	if (IS_ERR(drvdata->csdev))
		return PTR_ERR(drvdata->csdev);

	dev_info(dev, "Dummy device initialized\n");

	return 0;
}

static int dummy_remove(struct platform_device *pdev)
{
	struct dummy_drvdata *drvdata = platform_get_drvdata(pdev);

	coresight_unregister(drvdata->csdev);
	return 0;
}

static const struct of_device_id dummy_match[] = {
	{.compatible = "qcom,coresight-dummy"},
	{}
};

static struct platform_driver dummy_driver = {
	.probe	= dummy_probe,
	.remove	= dummy_remove,
	.driver	= {
		.name   = "coresight-dummy",
		.owner	= THIS_MODULE,
		.of_match_table = dummy_match,
	},
};

int __init dummy_init(void)
{
	return platform_driver_register(&dummy_driver);
}
module_init(dummy_init);

void __exit dummy_exit(void)
{
	platform_driver_unregister(&dummy_driver);
}
module_exit(dummy_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("CoreSight dummy source driver");
Loading