Skip to contentSkip to conversation

Enable CoreSight for the Ux500

PATCH Superseded Linus Walleij 4 participants 29 messages Apr 17, 2015 – Apr 24, 2015 Device tree bindings

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover Enable CoreSight for the Ux500

This patch series enables the CoreSight blocks for the Ux500.

To do so I ran into a few obstacles, all resolved in this series:

- The Ux500 have two distinct clocks clocking the CS blocks, APETRACECLK clocking the AHB interconnect, what is usually referred to as "apb_pclk" in the AMBA primecell abstraction layer, and another clock called APEATCLK which is connected to the actual ATCLK on the CS blocks. So I have to add handling for this second clock as only the PCLK is handled today.

- Doing so I need to use runtime PM, and I discovered that the current CS drivers go in and grab the PCLK from the AMBA primecell abstraction which is wrong: this shall be handled using runtime PM callbacks, see e.g. drivers/mmc/host/mmci.c. So I made a patch series fixing this. This also fixes the problem that the PCLK is left on since none of the drivers call pm_runtime_put() so the AMBA core can disable the PCLK, instead they are poking around with the PCLK themselves which is wrong.

Linus Walleij (13):
coresight: etm: print what version of ETM/PTM is detected
coresight: support the TPIU version found in Ux500
coresight: etm: let runtime PM handle core clock
coresight: tpiu: let runtime PM handle core clock
coresight: etb: let runtime PM handle core clock
coresight: funnel: let runtime PM handle core clock
coresight: tmc: let runtime PM handle core clock
coresight: etm: retrieve and handle atclk
coresight: tpiu: retrieve and handle atclk
coresight: etb: retrieve and handle atclk
coresight: funnel: retrieve and handle atclk
coresight: replicator: retrieve and handle atclk
ARM: ux500: add CoreSight blocks to DTS file

 arch/arm/boot/dts/ste-dbx5x0.dtsi        | 129 +++++++++++++++++++++++++++++++
 drivers/coresight/coresight-etb10.c      |  74 +++++++++++-------
 drivers/coresight/coresight-etm.h        |   4 +-
 drivers/coresight/coresight-etm3x.c      | 102 +++++++++++++-----------
 drivers/coresight/coresight-funnel.c     |  63 +++++++++++----
 drivers/coresight/coresight-replicator.c |  43 +++++++++++
 drivers/coresight/coresight-tmc.c        |  20 ++---
 drivers/coresight/coresight-tpiu.c       |  62 +++++++++++----
 8 files changed, 376 insertions(+), 121 deletions(-)
Signature · 1 line
1.9.3
#1 lore raw

PATCH 1/13 coresight: etm: print what version of ETM/PTM is detected

Helpfully report a bit more about the hardware found in the silicon when matching the AMBA device IDs by using the associated .data pointer in the AMBA match.

---
 drivers/coresight/coresight-etm3x.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/coresight/coresight-etm3x.c +5 -1
index c965f5724abd..66e210d5fddd 100644
@@ -1859,7 +1859,7 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
 		goto err_arch_supported;
 	}
 
-	dev_info(dev, "ETM initialized\n");
+	dev_info(dev, "%s initialized\n", (char *)id->data);
 
 	if (boot_enable) {
 		coresight_enable(drvdata->csdev);
@@ -1890,18 +1890,22 @@ static struct amba_id etm_ids[] = {
 	{	/* ETM 3.3 */
 		.id	= 0x0003b921,
 		.mask	= 0x0003ffff,
+		.data	= "ETM 3.3",
 	},
 	{	/* ETM 3.5 */
 		.id	= 0x0003b956,
 		.mask	= 0x0003ffff,
+		.data	= "ETM 3.5",
 	},
 	{	/* PTM 1.0 */
 		.id	= 0x0003b950,
 		.mask	= 0x0003ffff,
+		.data	= "PTM 1.0",
 	},
 	{	/* PTM 1.1 */
 		.id	= 0x0003b95f,
 		.mask	= 0x0003ffff,
+		.data	= "PTM 1.1",
 	},
 	{ 0, 0},
 };
Signature · 1 line
1.9.3
#2 lore raw

PATCH 2/13 coresight: support the TPIU version found in Ux500

In reply to Linus Walleij

The Ux500 has a PrimeCell version 4B instead of the 3B as supported by the driver, extend the match table to cover this version.

---
 drivers/coresight/coresight-tpiu.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/coresight/coresight-tpiu.c +4 -0
index 3b33af2416bb..88b6b0c32538 100644
@@ -188,6 +188,10 @@ static struct amba_id tpiu_ids[] = {
 		.id	= 0x0003b912,
 		.mask	= 0x0003ffff,
 	},
+	{
+		.id	= 0x0004b912,
+		.mask	= 0x0007ffff,
+	},
 	{ 0, 0},
 };
 
Signature · 1 line
1.9.3
#3 lore raw

PATCH 3/13 coresight: etm: let runtime PM handle core clock

In reply to Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as
the clk_prepare_enable() and clk_disable_unprepare() was called and thus just increase and decreas the refcount by one, without it reaching zero and actually disabling the clock. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

---
 drivers/coresight/coresight-etm.h   |  2 --
 drivers/coresight/coresight-etm3x.c | 60 ++++++++++---------------------------
 2 files changed, 16 insertions(+), 46 deletions(-)
drivers/coresight/coresight-etm.h +0 -2
index 501c5fac8a45..d1421e1f8b8a 100644
@@ -141,7 +141,6 @@
  * @base:	memory mapped base address for this component.
  * @dev:	the device entity associated to this component.
  * @csdev:	component vitals needed by the framework.
- * @clk:	the clock this component is associated to.
  * @spinlock:	only one at a time pls.
  * @cpu:	the cpu this component is affined to.
  * @port_size:	port size as reported by ETMCR bit 4-6 and 21.
@@ -193,7 +192,6 @@ struct etm_drvdata {
 	void __iomem			*base;
 	struct device			*dev;
 	struct coresight_device		*csdev;
-	struct clk			*clk;
 	spinlock_t			spinlock;
 	int				cpu;
 	int				port_size;
drivers/coresight/coresight-etm3x.c +16 -44

183 lines not on this page · raw message

Signature · 1 line
1.9.3
#4 lore raw

PATCH 3/13 coresight: etm: let runtime PM handle core clock

Quoted 14 lines · Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as
the clk_prepare_enable() and clk_disable_unprepare() was called and thus just increase and decreas the refcount by one, without it reaching zero and actually disabling the clock. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

Quoted 1 line
Quoted 235 lines
---
 drivers/coresight/coresight-etm.h   |  2 --
 drivers/coresight/coresight-etm3x.c | 60 ++++++++++---------------------------
 2 files changed, 16 insertions(+), 46 deletions(-)
drivers/coresight/coresight-etm.h +0 -2
index 501c5fac8a45..d1421e1f8b8a 100644
@@ -141,7 +141,6 @@
  * @base:      memory mapped base address for this component.
  * @dev:       the device entity associated to this component.
  * @csdev:     component vitals needed by the framework.
- * @clk:       the clock this component is associated to.
  * @spinlock:  only one at a time pls.
  * @cpu:       the cpu this component is affined to.
  * @port_size: port size as reported by ETMCR bit 4-6 and 21.
@@ -193,7 +192,6 @@ struct etm_drvdata {
        void __iomem                    *base;
        struct device                   *dev;
        struct coresight_device         *csdev;
-       struct clk                      *clk;
        spinlock_t                      spinlock;
        int                             cpu;
        int                             port_size;
drivers/coresight/coresight-etm3x.c +16 -45
index 66e210d5fddd..f0be12bd79e0 100644
@@ -23,7 +23,7 @@
 #include <linux/smp.h>
 #include <linux/sysfs.h>
 #include <linux/stat.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/cpu.h>
 #include <linux/of.h>
 #include <linux/coresight.h>
@@ -325,9 +325,7 @@ static int etm_trace_id(struct coresight_device *csdev)
 
        if (!drvdata->enable)
                return drvdata->traceid;
-
-       if (clk_prepare_enable(drvdata->clk))
-               goto out;
+       pm_runtime_get_sync(csdev->dev.parent);
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
@@ -336,8 +334,8 @@ static int etm_trace_id(struct coresight_device *csdev)
        CS_LOCK(drvdata->base);
 
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
-       clk_disable_unprepare(drvdata->clk);
-out:
+       pm_runtime_put(csdev->dev.parent);
+
        return trace_id;
 }
 
@@ -346,10 +344,7 @@ static int etm_enable(struct coresight_device *csdev)
        struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
        int ret;
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               goto err_clk;
-
+       pm_runtime_get_sync(csdev->dev.parent);
        spin_lock(&drvdata->spinlock);
 
        /*
@@ -373,8 +368,7 @@ static int etm_enable(struct coresight_device *csdev)
        return 0;
 err:
        spin_unlock(&drvdata->spinlock);
-       clk_disable_unprepare(drvdata->clk);
-err_clk:
+       pm_runtime_put(csdev->dev.parent);
        return ret;
 }
 
@@ -423,8 +417,7 @@ static void etm_disable(struct coresight_device *csdev)
 
        spin_unlock(&drvdata->spinlock);
        put_online_cpus();
-
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(csdev->dev.parent);
 
        dev_info(drvdata->dev, "ETM tracing disabled\n");
 }
@@ -474,14 +467,10 @@ static DEVICE_ATTR_RO(nr_ctxid_cmp);
 static ssize_t etmsr_show(struct device *dev,
                          struct device_attribute *attr, char *buf)
 {
-       int ret;
        unsigned long flags, val;
        struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
-
+       pm_runtime_get_sync(drvdata->dev);
        spin_lock_irqsave(&drvdata->spinlock, flags);
        CS_UNLOCK(drvdata->base);
 
@@ -489,7 +478,7 @@ static ssize_t etmsr_show(struct device *dev,
 
        CS_LOCK(drvdata->base);
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(drvdata->dev);
 
        return sprintf(buf, "%#lx\n", val);
 }
@@ -1317,7 +1306,6 @@ static DEVICE_ATTR_RW(seq_13_event);
 static ssize_t seq_curr_state_show(struct device *dev,
                                   struct device_attribute *attr, char *buf)
 {
-       int ret;
        unsigned long val, flags;
        struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
@@ -1326,9 +1314,7 @@ static ssize_t seq_curr_state_show(struct device *dev,
                goto out;
        }
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
+       pm_runtime_get_sync(drvdata->dev);
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
@@ -1337,7 +1323,7 @@ static ssize_t seq_curr_state_show(struct device *dev,
        CS_LOCK(drvdata->base);
 
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(drvdata->dev);
 out:
        return sprintf(buf, "%#lx\n", val);
 }
@@ -1521,10 +1507,7 @@ static ssize_t status_show(struct device *dev,
        unsigned long flags;
        struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
-
+       pm_runtime_get_sync(drvdata->dev);
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        CS_UNLOCK(drvdata->base);
@@ -1550,7 +1533,7 @@ static ssize_t status_show(struct device *dev,
        CS_LOCK(drvdata->base);
 
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(drvdata->dev);
 
        return ret;
 }
@@ -1559,7 +1542,6 @@ static DEVICE_ATTR_RO(status);
 static ssize_t traceid_show(struct device *dev,
                            struct device_attribute *attr, char *buf)
 {
-       int ret;
        unsigned long val, flags;
        struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
@@ -1568,10 +1550,7 @@ static ssize_t traceid_show(struct device *dev,
                goto out;
        }
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
-
+       pm_runtime_get_sync(drvdata->dev);
        spin_lock_irqsave(&drvdata->spinlock, flags);
        CS_UNLOCK(drvdata->base);
 
@@ -1579,7 +1558,7 @@ static ssize_t traceid_show(struct device *dev,
 
        CS_LOCK(drvdata->base);
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(drvdata->dev);
 out:
        return sprintf(buf, "%#lx\n", val);
 }
@@ -1817,11 +1796,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
 
        spin_lock_init(&drvdata->spinlock);
 
-       drvdata->clk = adev->pclk;
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
-
        drvdata->cpu = pdata ? pdata->cpu : 0;
 
        get_online_cpus();
@@ -1845,8 +1819,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
        }
        etm_init_default_data(drvdata);
 
-       clk_disable_unprepare(drvdata->clk);
-
        desc->type = CORESIGHT_DEV_TYPE_SOURCE;
        desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC;
        desc->ops = &etm_cs_ops;
@@ -1859,6 +1831,7 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
                goto err_arch_supported;
        }
 
+       pm_runtime_put(&adev->dev);
        dev_info(dev, "%s initialized\n", (char *)id->data);
 
        if (boot_enable) {
@@ -1869,7 +1842,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
        return 0;
 
 err_arch_supported:
-       clk_disable_unprepare(drvdata->clk);
        if (--etm_count == 0)
                unregister_hotcpu_notifier(&etm_cpu_notifier);
        return ret;
--

1.9.3

#5 lore raw

PATCH 4/13 coresight: tpiu: let runtime PM handle core clock

In reply to Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as
the clk_prepare_enable() and clk_disable_unprepare() was called and thus just increase and decreas the refcount by one, without it reaching zero and actually disabling the clock. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

---
 drivers/coresight/coresight-tpiu.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)
drivers/coresight/coresight-tpiu.c +4 -17
index 88b6b0c32538..688ba937069e 100644
@@ -17,7 +17,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/slab.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
 
@@ -51,13 +51,11 @@
  * @base:	memory mapped base address for this component.
  * @dev:	the device entity associated to this component.
  * @csdev:	component vitals needed by the framework.
- * @clk:	the clock this component is associated to.
  */
 struct tpiu_drvdata {
 	void __iomem		*base;
 	struct device		*dev;
 	struct coresight_device	*csdev;
-	struct clk		*clk;
 };
 
 static void tpiu_enable_hw(struct tpiu_drvdata *drvdata)
@@ -72,12 +70,8 @@ static void tpiu_enable_hw(struct tpiu_drvdata *drvdata)
 static int tpiu_enable(struct coresight_device *csdev)
 {
 	struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	int ret;
-
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		return ret;
 
+	pm_runtime_get_sync(csdev->dev.parent);
 	tpiu_enable_hw(drvdata);
 
 	dev_info(drvdata->dev, "TPIU enabled\n");
@@ -101,8 +95,7 @@ static void tpiu_disable(struct coresight_device *csdev)
 	struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
 	tpiu_disable_hw(drvdata);
-
-	clk_disable_unprepare(drvdata->clk);
+	pm_runtime_put(csdev->dev.parent);
 
 	dev_info(drvdata->dev, "TPIU disabled\n");
 }
@@ -118,7 +111,6 @@ static const struct coresight_ops tpiu_cs_ops = {
 
 static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 {
-	int ret;
 	void __iomem *base;
 	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
@@ -148,15 +140,10 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 
 	drvdata->base = base;
 
-	drvdata->clk = adev->pclk;
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		return ret;
-
 	/* Disable tpiu to support older devices */
 	tpiu_disable_hw(drvdata);
 
-	clk_disable_unprepare(drvdata->clk);
+	pm_runtime_put(&adev->dev);
 
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
Signature · 1 line
1.9.3
#6 lore raw

PATCH 4/13 coresight: tpiu: let runtime PM handle core clock

Quoted 14 lines · Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as
the clk_prepare_enable() and clk_disable_unprepare() was called and thus just increase and decreas the refcount by one, without it reaching zero and actually disabling the clock. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

Quoted 1 line
Quoted 83 lines
---
 drivers/coresight/coresight-tpiu.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)
drivers/coresight/coresight-tpiu.c +4 -18
index 88b6b0c32538..688ba937069e 100644
@@ -17,7 +17,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/slab.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
 
@@ -51,13 +51,11 @@
  * @base:      memory mapped base address for this component.
  * @dev:       the device entity associated to this component.
  * @csdev:     component vitals needed by the framework.
- * @clk:       the clock this component is associated to.
  */
 struct tpiu_drvdata {
        void __iomem            *base;
        struct device           *dev;
        struct coresight_device *csdev;
-       struct clk              *clk;
 };
 
 static void tpiu_enable_hw(struct tpiu_drvdata *drvdata)
@@ -72,12 +70,8 @@ static void tpiu_enable_hw(struct tpiu_drvdata *drvdata)
 static int tpiu_enable(struct coresight_device *csdev)
 {
        struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-       int ret;
-
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
 
+       pm_runtime_get_sync(csdev->dev.parent);
        tpiu_enable_hw(drvdata);
 
        dev_info(drvdata->dev, "TPIU enabled\n");
@@ -101,8 +95,7 @@ static void tpiu_disable(struct coresight_device *csdev)
        struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
        tpiu_disable_hw(drvdata);
-
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(csdev->dev.parent);
 
        dev_info(drvdata->dev, "TPIU disabled\n");
 }
@@ -118,7 +111,6 @@ static const struct coresight_ops tpiu_cs_ops = {
 
 static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 {
-       int ret;
        void __iomem *base;
        struct device *dev = &adev->dev;
        struct coresight_platform_data *pdata = NULL;
@@ -148,15 +140,10 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 
        drvdata->base = base;
 
-       drvdata->clk = adev->pclk;
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
-
        /* Disable tpiu to support older devices */
        tpiu_disable_hw(drvdata);
 
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(&adev->dev);
 
        desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
        if (!desc)
--

1.9.3

#7 lore raw

PATCH 5/13 coresight: etb: let runtime PM handle core clock

In reply to Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as
the clk_prepare_enable() and clk_disable_unprepare() was called and thus just increase and decreas the refcount by one, without it reaching zero and actually disabling the clock. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

---
 drivers/coresight/coresight-etb10.c | 35 +++++++++--------------------------
 1 file changed, 9 insertions(+), 26 deletions(-)
drivers/coresight/coresight-etb10.c +9 -26
index c9acd406f0d0..c4587510a826 100644
@@ -22,7 +22,7 @@
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/seq_file.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
@@ -68,7 +68,6 @@
  * @dev:	the device entity associated to this component.
  * @csdev:	component vitals needed by the framework.
  * @miscdev:	specifics to handle "/dev/xyz.etb" entry.
- * @clk:	the clock this component is associated to.
  * @spinlock:	only one at a time pls.
  * @in_use:	synchronise user space access to etb buffer.
  * @buf:	area of memory where ETB buffer content gets sent.
@@ -81,7 +80,6 @@ struct etb_drvdata {
 	struct device		*dev;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
-	struct clk		*clk;
 	spinlock_t		spinlock;
 	atomic_t		in_use;
 	u8			*buf;
@@ -92,17 +90,14 @@ struct etb_drvdata {
 
 static unsigned int etb_get_buffer_depth(struct etb_drvdata *drvdata)
 {
-	int ret;
 	u32 depth = 0;
 
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		return ret;
+	pm_runtime_get_sync(drvdata->dev);
 
 	/* RO registers don't need locking */
 	depth = readl_relaxed(drvdata->base + ETB_RAM_DEPTH_REG);
 
-	clk_disable_unprepare(drvdata->clk);
+	pm_runtime_put(drvdata->dev);
 	return depth;
 }
 
@@ -137,12 +132,9 @@ static void etb_enable_hw(struct etb_drvdata *drvdata)
 static int etb_enable(struct coresight_device *csdev)
 {
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	int ret;
 	unsigned long flags;
 
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		return ret;
+	pm_runtime_get_sync(drvdata->dev);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 	etb_enable_hw(drvdata);
@@ -252,7 +244,7 @@ static void etb_disable(struct coresight_device *csdev)
 	drvdata->enable = false;
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-	clk_disable_unprepare(drvdata->clk);
+	pm_runtime_put(drvdata->dev);
 
 	dev_info(drvdata->dev, "ETB disabled\n");
 }
@@ -339,16 +331,12 @@ static const struct file_operations etb_fops = {
 static ssize_t status_show(struct device *dev,
 			   struct device_attribute *attr, char *buf)
 {
-	int ret;
 	unsigned long flags;
 	u32 etb_rdr, etb_sr, etb_rrp, etb_rwp;
 	u32 etb_trg, etb_cr, etb_ffsr, etb_ffcr;
 	struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		goto out;
-
+	pm_runtime_get_sync(drvdata->dev);
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 	CS_UNLOCK(drvdata->base);
 
@@ -364,7 +352,7 @@ static ssize_t status_show(struct device *dev,
 	CS_LOCK(drvdata->base);
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-	clk_disable_unprepare(drvdata->clk);
+	pm_runtime_put(drvdata->dev);
 
 	return sprintf(buf,
 		       "Depth:\t\t0x%x\n"
@@ -377,7 +365,7 @@ static ssize_t status_show(struct device *dev,
 		       "Flush ctrl:\t0x%x\n",
 		       etb_rdr, etb_sr, etb_rrp, etb_rwp,
 		       etb_trg, etb_cr, etb_ffsr, etb_ffcr);
-out:
+
 	return -EINVAL;
 }
 static DEVICE_ATTR_RO(status);
@@ -449,13 +437,8 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
 
 	spin_lock_init(&drvdata->spinlock);
 
-	drvdata->clk = adev->pclk;
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		return ret;
-
 	drvdata->buffer_depth = etb_get_buffer_depth(drvdata);
-	clk_disable_unprepare(drvdata->clk);
+	pm_runtime_put(&adev->dev);
 
 	if (drvdata->buffer_depth < 0)
 		return -EINVAL;
Signature · 1 line
1.9.3
#8 lore raw

PATCH 5/13 coresight: etb: let runtime PM handle core clock

Quoted 14 lines · Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as
the clk_prepare_enable() and clk_disable_unprepare() was called and thus just increase and decreas the refcount by one, without it reaching zero and actually disabling the clock. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

Quoted 1 line
Quoted 130 lines
---
 drivers/coresight/coresight-etb10.c | 35 +++++++++--------------------------
 1 file changed, 9 insertions(+), 26 deletions(-)
drivers/coresight/coresight-etb10.c +9 -27
index c9acd406f0d0..c4587510a826 100644
@@ -22,7 +22,7 @@
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/seq_file.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
@@ -68,7 +68,6 @@
  * @dev:       the device entity associated to this component.
  * @csdev:     component vitals needed by the framework.
  * @miscdev:   specifics to handle "/dev/xyz.etb" entry.
- * @clk:       the clock this component is associated to.
  * @spinlock:  only one at a time pls.
  * @in_use:    synchronise user space access to etb buffer.
  * @buf:       area of memory where ETB buffer content gets sent.
@@ -81,7 +80,6 @@ struct etb_drvdata {
        struct device           *dev;
        struct coresight_device *csdev;
        struct miscdevice       miscdev;
-       struct clk              *clk;
        spinlock_t              spinlock;
        atomic_t                in_use;
        u8                      *buf;
@@ -92,17 +90,14 @@ struct etb_drvdata {
 
 static unsigned int etb_get_buffer_depth(struct etb_drvdata *drvdata)
 {
-       int ret;
        u32 depth = 0;
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
+       pm_runtime_get_sync(drvdata->dev);
 
        /* RO registers don't need locking */
        depth = readl_relaxed(drvdata->base + ETB_RAM_DEPTH_REG);
 
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(drvdata->dev);
        return depth;
 }
 
@@ -137,12 +132,9 @@ static void etb_enable_hw(struct etb_drvdata *drvdata)
 static int etb_enable(struct coresight_device *csdev)
 {
        struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-       int ret;
        unsigned long flags;
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
+       pm_runtime_get_sync(drvdata->dev);
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
        etb_enable_hw(drvdata);
@@ -252,7 +244,7 @@ static void etb_disable(struct coresight_device *csdev)
        drvdata->enable = false;
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(drvdata->dev);
 
        dev_info(drvdata->dev, "ETB disabled\n");
 }
@@ -339,16 +331,12 @@ static const struct file_operations etb_fops = {
 static ssize_t status_show(struct device *dev,
                           struct device_attribute *attr, char *buf)
 {
-       int ret;
        unsigned long flags;
        u32 etb_rdr, etb_sr, etb_rrp, etb_rwp;
        u32 etb_trg, etb_cr, etb_ffsr, etb_ffcr;
        struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               goto out;
-
+       pm_runtime_get_sync(drvdata->dev);
        spin_lock_irqsave(&drvdata->spinlock, flags);
        CS_UNLOCK(drvdata->base);
 
@@ -364,7 +352,7 @@ static ssize_t status_show(struct device *dev,
        CS_LOCK(drvdata->base);
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(drvdata->dev);
 
        return sprintf(buf,
                       "Depth:\t\t0x%x\n"
@@ -377,7 +365,7 @@ static ssize_t status_show(struct device *dev,
                       "Flush ctrl:\t0x%x\n",
                       etb_rdr, etb_sr, etb_rrp, etb_rwp,
                       etb_trg, etb_cr, etb_ffsr, etb_ffcr);
-out:
+
        return -EINVAL;
 }
 static DEVICE_ATTR_RO(status);
@@ -449,13 +437,8 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
 
        spin_lock_init(&drvdata->spinlock);
 
-       drvdata->clk = adev->pclk;
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
-
        drvdata->buffer_depth = etb_get_buffer_depth(drvdata);
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(&adev->dev);
 
        if (drvdata->buffer_depth < 0)
                return -EINVAL;
--

1.9.3

#9 lore raw

PATCH 6/13 coresight: funnel: let runtime PM handle core clock

In reply to Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as clk_disable_unprepare() was not called. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

---
 drivers/coresight/coresight-funnel.c | 24 +++++++-----------------
 1 file changed, 7 insertions(+), 17 deletions(-)
drivers/coresight/coresight-funnel.c +7 -17
index 3db36f70b666..330de2c88759 100644
@@ -18,7 +18,7 @@
 #include <linux/err.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
 
@@ -36,14 +36,12 @@
  * @base:	memory mapped base address for this component.
  * @dev:	the device entity associated to this component.
  * @csdev:	component vitals needed by the framework.
- * @clk:	the clock this component is associated to.
  * @priority:	port selection order.
  */
 struct funnel_drvdata {
 	void __iomem		*base;
 	struct device		*dev;
 	struct coresight_device	*csdev;
-	struct clk		*clk;
 	unsigned long		priority;
 };
 
@@ -67,12 +65,8 @@ static int funnel_enable(struct coresight_device *csdev, int inport,
 			 int outport)
 {
 	struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	int ret;
-
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		return ret;
 
+	pm_runtime_get_sync(drvdata->dev);
 	funnel_enable_hw(drvdata, inport);
 
 	dev_info(drvdata->dev, "FUNNEL inport %d enabled\n", inport);
@@ -98,8 +92,7 @@ static void funnel_disable(struct coresight_device *csdev, int inport,
 	struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
 	funnel_disable_hw(drvdata, inport);
-
-	clk_disable_unprepare(drvdata->clk);
+	pm_runtime_put(drvdata->dev);
 
 	dev_info(drvdata->dev, "FUNNEL inport %d disabled\n", inport);
 }
@@ -153,16 +146,14 @@ static u32 get_funnel_ctrl_hw(struct funnel_drvdata *drvdata)
 static ssize_t funnel_ctrl_show(struct device *dev,
 			     struct device_attribute *attr, char *buf)
 {
-	int ret;
 	u32 val;
 	struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		return ret;
+	pm_runtime_get_sync(drvdata->dev);
 
 	val = get_funnel_ctrl_hw(drvdata);
-	clk_disable_unprepare(drvdata->clk);
+
+	pm_runtime_put(drvdata->dev);
 
 	return sprintf(buf, "%#x\n", val);
 }
@@ -205,8 +196,7 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id)
 		return PTR_ERR(base);
 
 	drvdata->base = base;
-
-	drvdata->clk = adev->pclk;
+	pm_runtime_put(&adev->dev);
 
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
Signature · 1 line
1.9.3
#10 lore raw

PATCH 6/13 coresight: funnel: let runtime PM handle core clock

Quoted 6 lines · Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Quoted 7 lines

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as clk_disable_unprepare() was not called. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

Quoted 89 lines
---
 drivers/coresight/coresight-funnel.c | 24 +++++++-----------------
 1 file changed, 7 insertions(+), 17 deletions(-)
drivers/coresight/coresight-funnel.c +7 -18
index 3db36f70b666..330de2c88759 100644
@@ -18,7 +18,7 @@
 #include <linux/err.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
 
@@ -36,14 +36,12 @@
  * @base:      memory mapped base address for this component.
  * @dev:       the device entity associated to this component.
  * @csdev:     component vitals needed by the framework.
- * @clk:       the clock this component is associated to.
  * @priority:  port selection order.
  */
 struct funnel_drvdata {
        void __iomem            *base;
        struct device           *dev;
        struct coresight_device *csdev;
-       struct clk              *clk;
        unsigned long           priority;
 };
 
@@ -67,12 +65,8 @@ static int funnel_enable(struct coresight_device *csdev, int inport,
                         int outport)
 {
        struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-       int ret;
-
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
 
+       pm_runtime_get_sync(drvdata->dev);
        funnel_enable_hw(drvdata, inport);
 
        dev_info(drvdata->dev, "FUNNEL inport %d enabled\n", inport);
@@ -98,8 +92,7 @@ static void funnel_disable(struct coresight_device *csdev, int inport,
        struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
        funnel_disable_hw(drvdata, inport);
-
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(drvdata->dev);
 
        dev_info(drvdata->dev, "FUNNEL inport %d disabled\n", inport);
 }
@@ -153,16 +146,14 @@ static u32 get_funnel_ctrl_hw(struct funnel_drvdata *drvdata)
 static ssize_t funnel_ctrl_show(struct device *dev,
                             struct device_attribute *attr, char *buf)
 {
-       int ret;
        u32 val;
        struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
+       pm_runtime_get_sync(drvdata->dev);
 
        val = get_funnel_ctrl_hw(drvdata);
-       clk_disable_unprepare(drvdata->clk);
+
+       pm_runtime_put(drvdata->dev);
 
        return sprintf(buf, "%#x\n", val);
 }
@@ -205,8 +196,7 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id)
                return PTR_ERR(base);
 
        drvdata->base = base;
-
-       drvdata->clk = adev->pclk;
+       pm_runtime_put(&adev->dev);
 
        desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
        if (!desc)
--

1.9.3

#11 lore raw

PATCH 7/13 coresight: tmc: let runtime PM handle core clock

In reply to Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as
the clk_prepare_enable() and clk_disable_unprepare() was called and thus just increase and decreas the refcount by one, without it reaching zero and actually disabling the clock. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

---
 drivers/coresight/coresight-tmc.c | 20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)
drivers/coresight/coresight-tmc.c +5 -15
index 3ff232f9ddf7..db917c70d2b3 100644
@@ -23,7 +23,7 @@
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
@@ -104,7 +104,6 @@ enum tmc_mem_intf_width {
  * @dev:	the device entity associated to this component.
  * @csdev:	component vitals needed by the framework.
  * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
- * @clk:	the clock this component is associated to.
  * @spinlock:	only one at a time pls.
  * @read_count:	manages preparation of buffer for reading.
  * @buf:	area of memory where trace data get sent.
@@ -120,7 +119,6 @@ struct tmc_drvdata {
 	struct device		*dev;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
-	struct clk		*clk;
 	spinlock_t		spinlock;
 	int			read_count;
 	bool			reading;
@@ -242,17 +240,14 @@ static void tmc_etf_enable_hw(struct tmc_drvdata *drvdata)
 
 static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
 {
-	int ret;
 	unsigned long flags;
 
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		return ret;
+	pm_runtime_get_sync(drvdata->dev);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
 		spin_unlock_irqrestore(&drvdata->spinlock, flags);
-		clk_disable_unprepare(drvdata->clk);
+		pm_runtime_put(drvdata->dev);
 		return -EBUSY;
 	}
 
@@ -386,7 +381,7 @@ out:
 	drvdata->enable = false;
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-	clk_disable_unprepare(drvdata->clk);
+	pm_runtime_put(drvdata->dev);
 
 	dev_info(drvdata->dev, "TMC disabled\n");
 }
@@ -644,11 +639,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 
 	spin_lock_init(&drvdata->spinlock);
 
-	drvdata->clk = adev->pclk;
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		return ret;
-
 	devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
 	drvdata->config_type = BMVAL(devid, 6, 7);
 
@@ -663,7 +653,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 		drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4;
 	}
 
-	clk_disable_unprepare(drvdata->clk);
+	pm_runtime_put(&adev->dev);
 
 	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
 		drvdata->vaddr = dma_alloc_coherent(dev, drvdata->size,
Signature · 1 line
1.9.3
#12 lore raw

PATCH 7/13 coresight: tmc: let runtime PM handle core clock

Quoted 14 lines · Linus Walleij

This uses runtime PM to manage the PCLK ("amba_pclk") instead of screwing around with the framework by going in and taking a copy from the amba device. The amba bus core will uprepare and disable the clock when the device is unused when CONFIG_PM is selected, else the clock will be always on.

Prior to this patch, as the AMBA primecell bus code enables the PCLK, it would be left on after probe as
the clk_prepare_enable() and clk_disable_unprepare() was called and thus just increase and decreas the refcount by one, without it reaching zero and actually disabling the clock. Now the runtime PM callbacks will make sure the PCLK is properly disabled after probe.

Quoted 1 line
Quoted 86 lines
---
 drivers/coresight/coresight-tmc.c | 20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)
drivers/coresight/coresight-tmc.c +5 -16
index 3ff232f9ddf7..db917c70d2b3 100644
@@ -23,7 +23,7 @@
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
@@ -104,7 +104,6 @@ enum tmc_mem_intf_width {
  * @dev:       the device entity associated to this component.
  * @csdev:     component vitals needed by the framework.
  * @miscdev:   specifics to handle "/dev/xyz.tmc" entry.
- * @clk:       the clock this component is associated to.
  * @spinlock:  only one at a time pls.
  * @read_count:        manages preparation of buffer for reading.
  * @buf:       area of memory where trace data get sent.
@@ -120,7 +119,6 @@ struct tmc_drvdata {
        struct device           *dev;
        struct coresight_device *csdev;
        struct miscdevice       miscdev;
-       struct clk              *clk;
        spinlock_t              spinlock;
        int                     read_count;
        bool                    reading;
@@ -242,17 +240,14 @@ static void tmc_etf_enable_hw(struct tmc_drvdata *drvdata)
 
 static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
 {
-       int ret;
        unsigned long flags;
 
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
+       pm_runtime_get_sync(drvdata->dev);
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
        if (drvdata->reading) {
                spin_unlock_irqrestore(&drvdata->spinlock, flags);
-               clk_disable_unprepare(drvdata->clk);
+               pm_runtime_put(drvdata->dev);
                return -EBUSY;
        }
 
@@ -386,7 +381,7 @@ out:
        drvdata->enable = false;
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(drvdata->dev);
 
        dev_info(drvdata->dev, "TMC disabled\n");
 }
@@ -644,11 +639,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 
        spin_lock_init(&drvdata->spinlock);
 
-       drvdata->clk = adev->pclk;
-       ret = clk_prepare_enable(drvdata->clk);
-       if (ret)
-               return ret;
-
        devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
        drvdata->config_type = BMVAL(devid, 6, 7);
 
@@ -663,7 +653,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
                drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4;
        }
 
-       clk_disable_unprepare(drvdata->clk);
+       pm_runtime_put(&adev->dev);
 
        if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
                drvdata->vaddr = dma_alloc_coherent(dev, drvdata->size,
--

1.9.3

#13 lore raw

PATCH 8/13 coresight: etm: retrieve and handle atclk

In reply to Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0401C A.1.1 the ETM has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks.

The ATCLK is enabled and disabled using the runtime PM callbacks.

---
 drivers/coresight/coresight-etm.h   |  2 ++
 drivers/coresight/coresight-etm3x.c | 38 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)
drivers/coresight/coresight-etm.h +2 -0
index d1421e1f8b8a..098ffbec0a44 100644
@@ -140,6 +140,7 @@
  * struct etm_drvdata - specifics associated to an ETM component
  * @base:	memory mapped base address for this component.
  * @dev:	the device entity associated to this component.
+ * @atclk:	optional clock for the core parts of the ETM.
  * @csdev:	component vitals needed by the framework.
  * @spinlock:	only one at a time pls.
  * @cpu:	the cpu this component is affined to.
@@ -191,6 +192,7 @@
 struct etm_drvdata {
 	void __iomem			*base;
 	struct device			*dev;
+	struct clk			*atclk;
 	struct coresight_device		*csdev;
 	spinlock_t			spinlock;
 	int				cpu;
drivers/coresight/coresight-etm3x.c +37 -1
index f0be12bd79e0..25f49b84a6d2 100644
@@ -30,6 +30,7 @@
 #include <linux/amba/bus.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
+#include <linux/clk.h>
 #include <asm/sections.h>
 
 #include "coresight-etm.h"
@@ -1315,7 +1316,6 @@ static ssize_t seq_curr_state_show(struct device *dev,
 	}
 
 	pm_runtime_get_sync(drvdata->dev);
-
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	CS_UNLOCK(drvdata->base);
@@ -1796,6 +1796,13 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
 
 	spin_lock_init(&drvdata->spinlock);
 
+	drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+	if (!IS_ERR(drvdata->atclk)) {
+		ret = clk_prepare_enable(drvdata->atclk);
+		if (ret)
+			return ret;
+	}
+
 	drvdata->cpu = pdata ? pdata->cpu : 0;
 
 	get_online_cpus();
@@ -1858,6 +1865,34 @@ static int etm_remove(struct amba_device *adev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int etm_runtime_suspend(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct etm_drvdata *drvdata = amba_get_drvdata(adev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_disable_unprepare(drvdata->atclk);
+
+	return 0;
+}
+
+static int etm_runtime_resume(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct etm_drvdata *drvdata = amba_get_drvdata(adev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_prepare_enable(drvdata->atclk);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops etm_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(etm_runtime_suspend, etm_runtime_resume, NULL)
+};
+
 static struct amba_id etm_ids[] = {
 	{	/* ETM 3.3 */
 		.id	= 0x0003b921,
@@ -1886,6 +1921,7 @@ static struct amba_driver etm_driver = {
 	.drv = {
 		.name	= "coresight-etm3x",
 		.owner	= THIS_MODULE,
+		.pm	= &etm_dev_pm_ops,
 	},
 	.probe		= etm_probe,
 	.remove		= etm_remove,
Signature · 1 line
1.9.3
#14 lore raw

PATCH 8/13 coresight: etm: retrieve and handle atclk

Quoted 76 lines · Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0401C A.1.1 the ETM has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks.

The ATCLK is enabled and disabled using the runtime PM callbacks.

---
 drivers/coresight/coresight-etm.h   |  2 ++
 drivers/coresight/coresight-etm3x.c | 38 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)
drivers/coresight/coresight-etm.h +2 -0
index d1421e1f8b8a..098ffbec0a44 100644
@@ -140,6 +140,7 @@
  * struct etm_drvdata - specifics associated to an ETM component
  * @base:      memory mapped base address for this component.
  * @dev:       the device entity associated to this component.
+ * @atclk:     optional clock for the core parts of the ETM.
  * @csdev:     component vitals needed by the framework.
  * @spinlock:  only one at a time pls.
  * @cpu:       the cpu this component is affined to.
@@ -191,6 +192,7 @@
 struct etm_drvdata {
        void __iomem                    *base;
        struct device                   *dev;
+       struct clk                      *atclk;
        struct coresight_device         *csdev;
        spinlock_t                      spinlock;
        int                             cpu;
drivers/coresight/coresight-etm3x.c +8 -1
index f0be12bd79e0..25f49b84a6d2 100644
@@ -30,6 +30,7 @@
 #include <linux/amba/bus.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
+#include <linux/clk.h>
 #include <asm/sections.h>
 
 #include "coresight-etm.h"
@@ -1315,7 +1316,6 @@ static ssize_t seq_curr_state_show(struct device *dev,
        }
 
        pm_runtime_get_sync(drvdata->dev);
-
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        CS_UNLOCK(drvdata->base);
@@ -1796,6 +1796,13 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
 
        spin_lock_init(&drvdata->spinlock);
 
+       drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+       if (!IS_ERR(drvdata->atclk)) {
+               ret = clk_prepare_enable(drvdata->atclk);
+               if (ret)
+                       return ret;
+       }
+
        drvdata->cpu = pdata ? pdata->cpu : 0;
 
        get_online_cpus();

drivers/coresight/coresight-etm3x.c static int etm_remove(struct amba_device *adev) · line 1872

Quoted 8 lines
drivers/coresight/coresight-etm3x.c +5 -0
@@ -1858,6 +1865,34 @@ static int etm_remove(struct amba_device *adev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int etm_runtime_suspend(struct device *dev)
+{
+       struct amba_device *adev = to_amba_device(dev);
+       struct etm_drvdata *drvdata = amba_get_drvdata(adev);

I think you could replace the above two lines with:

struct etm_drvdata *drvdata = dev_get_drvdata(dev);

drivers/coresight/coresight-etm3x.c static int etm_remove(struct amba_device *adev) · line 1883

Quoted 11 lines
drivers/coresight/coresight-etm3x.c +11 -0
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_disable_unprepare(drvdata->atclk);
+
+       return 0;
+}
+
+static int etm_runtime_resume(struct device *dev)
+{
+       struct amba_device *adev = to_amba_device(dev);
+       struct etm_drvdata *drvdata = amba_get_drvdata(adev);

I think you could replace the above two lines with:

struct etm_drvdata *drvdata = dev_get_drvdata(dev)

Quoted 24 lines
drivers/coresight/coresight-etm3x.c +13 -1
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_prepare_enable(drvdata->atclk);
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops etm_dev_pm_ops = {
+       SET_RUNTIME_PM_OPS(etm_runtime_suspend, etm_runtime_resume, NULL)
+};
+
 static struct amba_id etm_ids[] = {
        {       /* ETM 3.3 */
                .id     = 0x0003b921,
@@ -1886,6 +1921,7 @@ static struct amba_driver etm_driver = {
        .drv = {
                .name   = "coresight-etm3x",
                .owner  = THIS_MODULE,
+               .pm     = &etm_dev_pm_ops,
        },
        .probe          = etm_probe,
        .remove         = etm_remove,
--
Quoted 2 lines

1.9.3

With the minor changes suggested.

#15 lore raw

PATCH 9/13 coresight: tpiu: retrieve and handle atclk

In reply to Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0314H page A-19 the TPIU has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks in conjunction.

The ATCLK is enabled and disabled using the runtime PM callbacks.

---
 drivers/coresight/coresight-tpiu.c | 39 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
drivers/coresight/coresight-tpiu.c +39 -0
index 688ba937069e..55faea7d55dd 100644
@@ -20,6 +20,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
+#include <linux/clk.h>
 
 #include "coresight-priv.h"
 
@@ -50,11 +51,13 @@
 /**
  * @base:	memory mapped base address for this component.
  * @dev:	the device entity associated to this component.
+ * @atclk:	optional clock for the core parts of the TPIU.
  * @csdev:	component vitals needed by the framework.
  */
 struct tpiu_drvdata {
 	void __iomem		*base;
 	struct device		*dev;
+	struct clk		*atclk;
 	struct coresight_device	*csdev;
 };
 
@@ -111,6 +114,7 @@ static const struct coresight_ops tpiu_cs_ops = {
 
 static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 {
+	int ret;
 	void __iomem *base;
 	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
@@ -131,6 +135,12 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 		return -ENOMEM;
 
 	drvdata->dev = &adev->dev;
+	drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+	if (!IS_ERR(drvdata->atclk)) {
+		ret = clk_prepare_enable(drvdata->atclk);
+		if (ret)
+			return ret;
+	}
 	dev_set_drvdata(dev, drvdata);
 
 	/* Validity for the resource is already checked by the AMBA core */
@@ -170,6 +180,34 @@ static int tpiu_remove(struct amba_device *adev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int tpiu_runtime_suspend(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct tpiu_drvdata *drvdata = amba_get_drvdata(adev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_disable_unprepare(drvdata->atclk);
+
+	return 0;
+}
+
+static int tpiu_runtime_resume(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct tpiu_drvdata *drvdata = amba_get_drvdata(adev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_prepare_enable(drvdata->atclk);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops tpiu_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(tpiu_runtime_suspend, tpiu_runtime_resume, NULL)
+};
+
 static struct amba_id tpiu_ids[] = {
 	{
 		.id	= 0x0003b912,
@@ -186,6 +224,7 @@ static struct amba_driver tpiu_driver = {
 	.drv = {
 		.name	= "coresight-tpiu",
 		.owner	= THIS_MODULE,
+		.pm	= &tpiu_dev_pm_ops,
 	},
 	.probe		= tpiu_probe,
 	.remove		= tpiu_remove,
Signature · 1 line
1.9.3
#16 lore raw

PATCH 9/13 coresight: tpiu: retrieve and handle atclk

Quoted 68 lines · Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0314H page A-19 the TPIU has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks in conjunction.

The ATCLK is enabled and disabled using the runtime PM callbacks.

---
 drivers/coresight/coresight-tpiu.c | 39 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
drivers/coresight/coresight-tpiu.c +10 -0
index 688ba937069e..55faea7d55dd 100644
@@ -20,6 +20,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
+#include <linux/clk.h>
 
 #include "coresight-priv.h"
 
@@ -50,11 +51,13 @@
 /**
  * @base:      memory mapped base address for this component.
  * @dev:       the device entity associated to this component.
+ * @atclk:     optional clock for the core parts of the TPIU.
  * @csdev:     component vitals needed by the framework.
  */
 struct tpiu_drvdata {
        void __iomem            *base;
        struct device           *dev;
+       struct clk              *atclk;
        struct coresight_device *csdev;
 };
 
@@ -111,6 +114,7 @@ static const struct coresight_ops tpiu_cs_ops = {
 
 static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
 {
+       int ret;
        void __iomem *base;
        struct device *dev = &adev->dev;
        struct coresight_platform_data *pdata = NULL;
@@ -131,6 +135,12 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
                return -ENOMEM;
 
        drvdata->dev = &adev->dev;
+       drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+       if (!IS_ERR(drvdata->atclk)) {
+               ret = clk_prepare_enable(drvdata->atclk);
+               if (ret)
+                       return ret;
+       }
        dev_set_drvdata(dev, drvdata);
 
        /* Validity for the resource is already checked by the AMBA core */

drivers/coresight/coresight-tpiu.c static int tpiu_remove(struct amba_device *adev) · line 187

Quoted 8 lines
drivers/coresight/coresight-tpiu.c +5 -0
@@ -170,6 +180,34 @@ static int tpiu_remove(struct amba_device *adev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int tpiu_runtime_suspend(struct device *dev)
+{
+       struct amba_device *adev = to_amba_device(dev);
+       struct tpiu_drvdata *drvdata = amba_get_drvdata(adev);

Same comment as previous patch.

drivers/coresight/coresight-tpiu.c static int tpiu_remove(struct amba_device *adev) · line 198

Quoted 11 lines
drivers/coresight/coresight-tpiu.c +11 -0
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_disable_unprepare(drvdata->atclk);
+
+       return 0;
+}
+
+static int tpiu_runtime_resume(struct device *dev)
+{
+       struct amba_device *adev = to_amba_device(dev);
+       struct tpiu_drvdata *drvdata = amba_get_drvdata(adev);

Same comment as previous patch.

Quoted 24 lines
drivers/coresight/coresight-tpiu.c +13 -1
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_prepare_enable(drvdata->atclk);
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops tpiu_dev_pm_ops = {
+       SET_RUNTIME_PM_OPS(tpiu_runtime_suspend, tpiu_runtime_resume, NULL)
+};
+
 static struct amba_id tpiu_ids[] = {
        {
                .id     = 0x0003b912,
@@ -186,6 +224,7 @@ static struct amba_driver tpiu_driver = {
        .drv = {
                .name   = "coresight-tpiu",
                .owner  = THIS_MODULE,
+               .pm     = &tpiu_dev_pm_ops,
        },
        .probe          = tpiu_probe,
        .remove         = tpiu_remove,
--
Quoted 2 lines

1.9.3

With the minor changes suggested.

#17 lore raw

PATCH 10/13 coresight: etb: retrieve and handle atclk

In reply to Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0314 table A-8 the ETB has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks.

The ATCLK is enabled and disabled using the runtime PM callbacks.

---
 drivers/coresight/coresight-etb10.c | 39 +++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
drivers/coresight/coresight-etb10.c +39 -0
index c4587510a826..7d751a39d959 100644
@@ -26,6 +26,7 @@
 #include <linux/seq_file.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
+#include <linux/clk.h>
 
 #include "coresight-priv.h"
 
@@ -66,6 +67,7 @@
  * struct etb_drvdata - specifics associated to an ETB component
  * @base:	memory mapped base address for this component.
  * @dev:	the device entity associated to this component.
+ * @atclk:	optional clock for the core parts of the ETB.
  * @csdev:	component vitals needed by the framework.
  * @miscdev:	specifics to handle "/dev/xyz.etb" entry.
  * @spinlock:	only one at a time pls.
@@ -78,6 +80,7 @@
 struct etb_drvdata {
 	void __iomem		*base;
 	struct device		*dev;
+	struct clk		*atclk;
 	struct coresight_device	*csdev;
 	struct miscdevice	miscdev;
 	spinlock_t		spinlock;
@@ -426,6 +429,12 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
 		return -ENOMEM;
 
 	drvdata->dev = &adev->dev;
+	drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+	if (!IS_ERR(drvdata->atclk)) {
+		ret = clk_prepare_enable(drvdata->atclk);
+		if (ret)
+			return ret;
+	}
 	dev_set_drvdata(dev, drvdata);
 
 	/* validity for the resource is already checked by the AMBA core */
@@ -486,6 +495,34 @@ static int etb_remove(struct amba_device *adev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int etb_runtime_suspend(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct etb_drvdata *drvdata = amba_get_drvdata(adev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_disable_unprepare(drvdata->atclk);
+
+	return 0;
+}
+
+static int etb_runtime_resume(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct etb_drvdata *drvdata = amba_get_drvdata(adev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_prepare_enable(drvdata->atclk);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops etb_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(etb_runtime_suspend, etb_runtime_resume, NULL)
+};
+
 static struct amba_id etb_ids[] = {
 	{
 		.id	= 0x0003b907,
@@ -498,6 +535,8 @@ static struct amba_driver etb_driver = {
 	.drv = {
 		.name	= "coresight-etb10",
 		.owner	= THIS_MODULE,
+		.pm	= &etb_dev_pm_ops,
+
 	},
 	.probe		= etb_probe,
 	.remove		= etb_remove,
Signature · 1 line
1.9.3
#18 lore raw

PATCH 10/13 coresight: etb: retrieve and handle atclk

Quoted 106 lines · Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0314 table A-8 the ETB has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks.

The ATCLK is enabled and disabled using the runtime PM callbacks.

---
 drivers/coresight/coresight-etb10.c | 39 +++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
drivers/coresight/coresight-etb10.c +39 -1
index c4587510a826..7d751a39d959 100644
@@ -26,6 +26,7 @@
 #include <linux/seq_file.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
+#include <linux/clk.h>
 
 #include "coresight-priv.h"
 
@@ -66,6 +67,7 @@
  * struct etb_drvdata - specifics associated to an ETB component
  * @base:      memory mapped base address for this component.
  * @dev:       the device entity associated to this component.
+ * @atclk:     optional clock for the core parts of the ETB.
  * @csdev:     component vitals needed by the framework.
  * @miscdev:   specifics to handle "/dev/xyz.etb" entry.
  * @spinlock:  only one at a time pls.
@@ -78,6 +80,7 @@
 struct etb_drvdata {
        void __iomem            *base;
        struct device           *dev;
+       struct clk              *atclk;
        struct coresight_device *csdev;
        struct miscdevice       miscdev;
        spinlock_t              spinlock;
@@ -426,6 +429,12 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
                return -ENOMEM;
 
        drvdata->dev = &adev->dev;
+       drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+       if (!IS_ERR(drvdata->atclk)) {
+               ret = clk_prepare_enable(drvdata->atclk);
+               if (ret)
+                       return ret;
+       }
        dev_set_drvdata(dev, drvdata);
 
        /* validity for the resource is already checked by the AMBA core */
@@ -486,6 +495,34 @@ static int etb_remove(struct amba_device *adev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int etb_runtime_suspend(struct device *dev)
+{
+       struct amba_device *adev = to_amba_device(dev);
+       struct etb_drvdata *drvdata = amba_get_drvdata(adev);
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_disable_unprepare(drvdata->atclk);
+
+       return 0;
+}
+
+static int etb_runtime_resume(struct device *dev)
+{
+       struct amba_device *adev = to_amba_device(dev);
+       struct etb_drvdata *drvdata = amba_get_drvdata(adev);
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_prepare_enable(drvdata->atclk);
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops etb_dev_pm_ops = {
+       SET_RUNTIME_PM_OPS(etb_runtime_suspend, etb_runtime_resume, NULL)
+};
+
 static struct amba_id etb_ids[] = {
        {
                .id     = 0x0003b907,
@@ -498,6 +535,8 @@ static struct amba_driver etb_driver = {
        .drv = {
                .name   = "coresight-etb10",
                .owner  = THIS_MODULE,
+               .pm     = &etb_dev_pm_ops,
+
        },
        .probe          = etb_probe,
        .remove         = etb_remove,
--
Quoted 2 lines

1.9.3

With the same comment as I had to previous patchnumber.

#19 lore raw

PATCH 11/13 coresight: funnel: retrieve and handle atclk

In reply to Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0314 table A-6 the funnel has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks.

The ATCLK is enabled and disabled using the runtime PM callbacks.

---
 drivers/coresight/coresight-funnel.c | 39 ++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
drivers/coresight/coresight-funnel.c +39 -0
index 330de2c88759..36c14ca4b916 100644
@@ -21,6 +21,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
+#include <linux/clk.h>
 
 #include "coresight-priv.h"
 
@@ -35,12 +36,14 @@
  * struct funnel_drvdata - specifics associated to a funnel component
  * @base:	memory mapped base address for this component.
  * @dev:	the device entity associated to this component.
+ * @atclk:	optional clock for the core parts of the funnel.
  * @csdev:	component vitals needed by the framework.
  * @priority:	port selection order.
  */
 struct funnel_drvdata {
 	void __iomem		*base;
 	struct device		*dev;
+	struct clk		*atclk;
 	struct coresight_device	*csdev;
 	unsigned long		priority;
 };
@@ -168,6 +171,7 @@ ATTRIBUTE_GROUPS(coresight_funnel);
 
 static int funnel_probe(struct amba_device *adev, const struct amba_id *id)
 {
+	int ret;
 	void __iomem *base;
 	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
@@ -188,6 +192,12 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id)
 		return -ENOMEM;
 
 	drvdata->dev = &adev->dev;
+	drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+	if (!IS_ERR(drvdata->atclk)) {
+		ret = clk_prepare_enable(drvdata->atclk);
+		if (ret)
+			return ret;
+	}
 	dev_set_drvdata(dev, drvdata);
 
 	/* Validity for the resource is already checked by the AMBA core */
@@ -224,6 +234,34 @@ static int funnel_remove(struct amba_device *adev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int funnel_runtime_suspend(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct funnel_drvdata *drvdata = amba_get_drvdata(adev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_disable_unprepare(drvdata->atclk);
+
+	return 0;
+}
+
+static int funnel_runtime_resume(struct device *dev)
+{
+	struct amba_device *adev = to_amba_device(dev);
+	struct funnel_drvdata *drvdata = amba_get_drvdata(adev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_prepare_enable(drvdata->atclk);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops funnel_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(funnel_runtime_suspend, funnel_runtime_resume, NULL)
+};
+
 static struct amba_id funnel_ids[] = {
 	{
 		.id     = 0x0003b908,
@@ -236,6 +274,7 @@ static struct amba_driver funnel_driver = {
 	.drv = {
 		.name	= "coresight-funnel",
 		.owner	= THIS_MODULE,
+		.pm	= &funnel_dev_pm_ops,
 	},
 	.probe		= funnel_probe,
 	.remove		= funnel_remove,
Signature · 1 line
1.9.3
#20 lore raw

PATCH 11/13 coresight: funnel: retrieve and handle atclk

Quoted 112 lines · Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0314 table A-6 the funnel has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks.

The ATCLK is enabled and disabled using the runtime PM callbacks.

---
 drivers/coresight/coresight-funnel.c | 39 ++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
drivers/coresight/coresight-funnel.c +39 -1
index 330de2c88759..36c14ca4b916 100644
@@ -21,6 +21,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
+#include <linux/clk.h>
 
 #include "coresight-priv.h"
 
@@ -35,12 +36,14 @@
  * struct funnel_drvdata - specifics associated to a funnel component
  * @base:      memory mapped base address for this component.
  * @dev:       the device entity associated to this component.
+ * @atclk:     optional clock for the core parts of the funnel.
  * @csdev:     component vitals needed by the framework.
  * @priority:  port selection order.
  */
 struct funnel_drvdata {
        void __iomem            *base;
        struct device           *dev;
+       struct clk              *atclk;
        struct coresight_device *csdev;
        unsigned long           priority;
 };
@@ -168,6 +171,7 @@ ATTRIBUTE_GROUPS(coresight_funnel);
 
 static int funnel_probe(struct amba_device *adev, const struct amba_id *id)
 {
+       int ret;
        void __iomem *base;
        struct device *dev = &adev->dev;
        struct coresight_platform_data *pdata = NULL;
@@ -188,6 +192,12 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id)
                return -ENOMEM;
 
        drvdata->dev = &adev->dev;
+       drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
+       if (!IS_ERR(drvdata->atclk)) {
+               ret = clk_prepare_enable(drvdata->atclk);
+               if (ret)
+                       return ret;
+       }
        dev_set_drvdata(dev, drvdata);
 
        /* Validity for the resource is already checked by the AMBA core */
@@ -224,6 +234,34 @@ static int funnel_remove(struct amba_device *adev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int funnel_runtime_suspend(struct device *dev)
+{
+       struct amba_device *adev = to_amba_device(dev);
+       struct funnel_drvdata *drvdata = amba_get_drvdata(adev);
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_disable_unprepare(drvdata->atclk);
+
+       return 0;
+}
+
+static int funnel_runtime_resume(struct device *dev)
+{
+       struct amba_device *adev = to_amba_device(dev);
+       struct funnel_drvdata *drvdata = amba_get_drvdata(adev);
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_prepare_enable(drvdata->atclk);
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops funnel_dev_pm_ops = {
+       SET_RUNTIME_PM_OPS(funnel_runtime_suspend, funnel_runtime_resume, NULL)
+};
+
 static struct amba_id funnel_ids[] = {
        {
                .id     = 0x0003b908,
@@ -236,6 +274,7 @@ static struct amba_driver funnel_driver = {
        .drv = {
                .name   = "coresight-funnel",
                .owner  = THIS_MODULE,
+               .pm     = &funnel_dev_pm_ops,
        },
        .probe          = funnel_probe,
        .remove         = funnel_remove,
--
Quoted 2 lines

1.9.3

With the same comment as I had to previous patchnumber.

#21 lore raw

PATCH 12/13 coresight: replicator: retrieve and handle atclk

In reply to Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0314 table A-4 the funnel has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks.

The ATCLK is enabled and disabled using the runtime PM callbacks. As the replicator is a platform device, the code is a bit different from the other CoreSight components and the bus core does not activate runtime PM by default, so we need a few extra calls.

---
 drivers/coresight/coresight-replicator.c | 43 ++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
drivers/coresight/coresight-replicator.c +43 -0
index cdf05537d574..126ae1f731d7 100644
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/coresight.h>
@@ -27,10 +28,12 @@
 /**
  * struct replicator_drvdata - specifics associated to a replicator component
  * @dev:	the device entity associated with this component
+ * @atclk:	optional clock for the core parts of the replicator.
  * @csdev:	component vitals needed by the framework
  */
 struct replicator_drvdata {
 	struct device		*dev;
+	struct clk		*atclk;
 	struct coresight_device	*csdev;
 };
 
@@ -39,6 +42,7 @@ static int replicator_enable(struct coresight_device *csdev, int inport,
 {
 	struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
+	pm_runtime_get_sync(drvdata->dev);
 	dev_info(drvdata->dev, "REPLICATOR enabled\n");
 	return 0;
 }
@@ -48,6 +52,7 @@ static void replicator_disable(struct coresight_device *csdev, int inport,
 {
 	struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
+	pm_runtime_put(drvdata->dev);
 	dev_info(drvdata->dev, "REPLICATOR disabled\n");
 }
 
@@ -62,6 +67,7 @@ static const struct coresight_ops replicator_cs_ops = {
 
 static int replicator_probe(struct platform_device *pdev)
 {
+	int ret;
 	struct device *dev = &pdev->dev;
 	struct coresight_platform_data *pdata = NULL;
 	struct replicator_drvdata *drvdata;
@@ -80,7 +86,16 @@ static int replicator_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	drvdata->dev = &pdev->dev;
+	drvdata->atclk = devm_clk_get(&pdev->dev, "atclk"); /* optional */
+	if (!IS_ERR(drvdata->atclk)) {
+		ret = clk_prepare_enable(drvdata->atclk);
+		if (ret)
+			return ret;
+	}
 	platform_set_drvdata(pdev, drvdata);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_put(&pdev->dev);
 
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
@@ -107,6 +122,33 @@ static int replicator_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int replicator_runtime_suspend(struct device *dev)
+{
+	struct replicator_drvdata *drvdata = dev_get_drvdata(dev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_disable_unprepare(drvdata->atclk);
+
+	return 0;
+}
+
+static int replicator_runtime_resume(struct device *dev)
+{
+struct replicator_drvdata *drvdata = dev_get_drvdata(dev);
+
+	if (drvdata && !IS_ERR(drvdata->atclk))
+		clk_prepare_enable(drvdata->atclk);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops replicator_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(replicator_runtime_suspend,
+			   replicator_runtime_resume, NULL)
+};
+
 static struct of_device_id replicator_match[] = {
 	{.compatible = "arm,coresight-replicator"},
 	{}
@@ -118,6 +160,7 @@ static struct platform_driver replicator_driver = {
 	.driver         = {
 		.name   = "coresight-replicator",
 		.of_match_table = replicator_match,
+		.pm	= &replicator_dev_pm_ops,
 	},
 };
 
Signature · 1 line
1.9.3
#22 lore raw

PATCH 12/13 coresight: replicator: retrieve and handle atclk

Quoted 77 lines · Linus Walleij

As can be seen from the datasheet of the CoreSight Components, DDI0314 table A-4 the funnel has a clock signal apart from the AHB interconnect ("amba_pclk", that we're already handling) called ATCLK, ARM Trace Clock, that SoC implementers may provide from an entirely different clock source. So to model this correctly create an optional path for handling ATCLK alongside the PCLK so we don't break old platforms that only define PCLK ("amba_pclk") but still makes it possible for SoCs that have both clock signals (such as the DB8500) to fetch and prepare/enable/disable/ unprepare both clocks.

The ATCLK is enabled and disabled using the runtime PM callbacks. As the replicator is a platform device, the code is a bit different from the other CoreSight components and the bus core does not activate runtime PM by default, so we need a few extra calls.

---
 drivers/coresight/coresight-replicator.c | 43 ++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
drivers/coresight/coresight-replicator.c +7 -0
index cdf05537d574..126ae1f731d7 100644
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/coresight.h>
@@ -27,10 +28,12 @@
 /**
  * struct replicator_drvdata - specifics associated to a replicator component
  * @dev:       the device entity associated with this component
+ * @atclk:     optional clock for the core parts of the replicator.
  * @csdev:     component vitals needed by the framework
  */
 struct replicator_drvdata {
        struct device           *dev;
+       struct clk              *atclk;
        struct coresight_device *csdev;
 };
 
@@ -39,6 +42,7 @@ static int replicator_enable(struct coresight_device *csdev, int inport,
 {
        struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
+       pm_runtime_get_sync(drvdata->dev);
        dev_info(drvdata->dev, "REPLICATOR enabled\n");
        return 0;
 }
@@ -48,6 +52,7 @@ static void replicator_disable(struct coresight_device *csdev, int inport,
 {
        struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
+       pm_runtime_put(drvdata->dev);
        dev_info(drvdata->dev, "REPLICATOR disabled\n");
 }
 
@@ -62,6 +67,7 @@ static const struct coresight_ops replicator_cs_ops = {
 
 static int replicator_probe(struct platform_device *pdev)
 {
+       int ret;
        struct device *dev = &pdev->dev;
        struct coresight_platform_data *pdata = NULL;
        struct replicator_drvdata *drvdata;
@@ -80,7 +86,16 @@ static int replicator_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        drvdata->dev = &pdev->dev;
+       drvdata->atclk = devm_clk_get(&pdev->dev, "atclk"); /* optional */

drivers/coresight/coresight-replicator.c static int replicator_probe(struct platform_device *pdev) · line 99

Quoted 10 lines
drivers/coresight/coresight-replicator.c +8 -0
+       if (!IS_ERR(drvdata->atclk)) {
+               ret = clk_prepare_enable(drvdata->atclk);
+               if (ret)
+                       return ret;
+       }
        platform_set_drvdata(pdev, drvdata);
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_put(&pdev->dev);
 

Move the pm_runtime_put() to the end of the ->probe().

Add a pm_runtime_get_noresume() prior the pm_runtime_set_active() call.

The you also need to add error handling. Taking care of gating the clock, decreasing the runtime PM reference count and disabling runtime PM.

Quoted 10 lines
drivers/coresight/coresight-replicator.c +4 -0
        desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
        if (!desc)
@@ -107,6 +122,33 @@ static int replicator_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int replicator_runtime_suspend(struct device *dev)
+{
+       struct replicator_drvdata *drvdata = dev_get_drvdata(dev);

drivers/coresight/coresight-replicator.c static int replicator_remove(struct platform_device *pdev) · line 138

Quoted 10 lines
drivers/coresight/coresight-replicator.c +10 -0
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_disable_unprepare(drvdata->atclk);
+
+       return 0;
+}
+
+static int replicator_runtime_resume(struct device *dev)
+{
+struct replicator_drvdata *drvdata = dev_get_drvdata(dev);

Tab?

Quoted 25 lines
drivers/coresight/coresight-replicator.c +14 -1
+
+       if (drvdata && !IS_ERR(drvdata->atclk))
+               clk_prepare_enable(drvdata->atclk);
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops replicator_dev_pm_ops = {
+       SET_RUNTIME_PM_OPS(replicator_runtime_suspend,
+                          replicator_runtime_resume, NULL)
+};
+
 static struct of_device_id replicator_match[] = {
        {.compatible = "arm,coresight-replicator"},
        {}
@@ -118,6 +160,7 @@ static struct platform_driver replicator_driver = {
        .driver         = {
                .name   = "coresight-replicator",
                .of_match_table = replicator_match,
+               .pm     = &replicator_dev_pm_ops,
        },
 };
 
--
Quoted 2 lines

1.9.3

Kind regards
Uffe

#23 lore raw

PATCH 13/13 ARM: ux500: add CoreSight blocks to DTS file

In reply to Linus Walleij

This registers all the CoreSight blocks on the DB8500 SoC:
each core has a PTM (v1.0, r1p0-00rel0) connected, both connected to a funnel (DK-TM908-r0p1-00rel0) which in turn connects to a replicator (DM-TM909-r0p1-00rel0). The replicator has two outputs, port 0 to a TPIU interface and port 1 to an ETB (DK-TM907-r0p3-00rel0). The CoreSight blocks are all clocked by the APEATCLK from the PRCMU and their AHB interconnect is clocked from a separate clock called APETRACECLK.

The SoC also has a CTI/CTM block which can be added later as we have upstream support in the CoreSight subsystem.

---
Mathieu: this patch will go into the ux500 tree if you think it looks OK. Just provide your ACK if you think it's looking good and I'll take care of it. The rest of the CoreSight stuff should be funneled through your tree I guess.

---
 arch/arm/boot/dts/ste-dbx5x0.dtsi | 129 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 129 insertions(+)
arch/arm/boot/dts/ste-dbx5x0.dtsi +129 -0
index bd6bd0926931..2f6ed08db9fe 100644
@@ -48,6 +48,135 @@
 			};
 		};
 
+		ptm at 801ae000 {
+			compatible = "arm,coresight-etm3x", "arm,primecell";
+			reg = <0x801ae000 0x1000>;
+
+			clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+			clock-names = "apb_pclk", "atclk";
+			cpu = <&CPU0>;
+			port {
+				ptm0_out_port: endpoint {
+					remote-endpoint = <&funnel_in_port0>;
+				};
+			};
+		};
+
+		ptm at 801af000 {
+			compatible = "arm,coresight-etm3x", "arm,primecell";
+			reg = <0x801af000 0x1000>;
+
+			clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+			clock-names = "apb_pclk", "atclk";
+			cpu = <&CPU1>;
+			port {
+				ptm1_out_port: endpoint {
+					remote-endpoint = <&funnel_in_port1>;
+				};
+			};
+		};
+
+		funnel at 801a6000 {
+			compatible = "arm,coresight-funnel", "arm,primecell";
+			reg = <0x801a6000 0x1000>;
+
+			clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+			clock-names = "apb_pclk", "atclk";
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				/* funnel output ports */
+				port at 0 {
+					reg = <0>;
+					funnel_out_port: endpoint {
+						remote-endpoint =
+							<&replicator_in_port0>;
+					};
+				};
+
+				/* funnel input ports */
+				port at 1 {
+					reg = <0>;
+					funnel_in_port0: endpoint {
+						slave-mode;
+						remote-endpoint = <&ptm0_out_port>;
+					};
+				};
+
+				port at 2 {
+					reg = <1>;
+					funnel_in_port1: endpoint {
+						slave-mode;
+						remote-endpoint = <&ptm1_out_port>;
+					};
+				};
+			};
+		};
+
+		replicator {
+			compatible = "arm,coresight-replicator";
+			clocks = <&prcmu_clk PRCMU_APEATCLK>;
+			clock-names = "atclk";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				/* replicator output ports */
+				port at 0 {
+					reg = <0>;
+					replicator_out_port0: endpoint {
+						remote-endpoint = <&tpiu_in_port>;
+					};
+				};
+				port at 1 {
+					reg = <1>;
+					replicator_out_port1: endpoint {
+						remote-endpoint = <&etb_in_port>;
+					};
+				};
+
+				/* replicator input port */
+				port at 2 {
+					reg = <0>;
+					replicator_in_port0: endpoint {
+						slave-mode;
+						remote-endpoint = <&funnel_out_port>;
+					};
+				};
+			};
+		};
+
+		tpiu at 80190000 {
+			compatible = "arm,coresight-tpiu", "arm,primecell";
+			reg = <0x80190000 0x1000>;
+
+			clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+			clock-names = "apb_pclk", "atclk";
+			port {
+				tpiu_in_port: endpoint {
+					slave-mode;
+					remote-endpoint = <&replicator_out_port0>;
+				};
+			};
+		};
+
+		etb at 801a4000 {
+			compatible = "arm,coresight-etb10", "arm,primecell";
+			reg = <0x801a4000 0x1000>;
+
+			coresight-default-sink;
+			clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+			clock-names = "apb_pclk", "atclk";
+			port {
+				etb_in_port: endpoint {
+					slave-mode;
+					remote-endpoint = <&replicator_out_port1>;
+				};
+			};
+		};
+
 		intc: interrupt-controller at a0411000 {
 			compatible = "arm,cortex-a9-gic";
 			#interrupt-cells = <3>;
Signature · 1 line
1.9.3
#24 lore raw

PATCH 13/13 ARM: ux500: add CoreSight blocks to DTS file

Quoted 139 lines · Linus Walleij

This registers all the CoreSight blocks on the DB8500 SoC:
each core has a PTM (v1.0, r1p0-00rel0) connected, both connected to a funnel (DK-TM908-r0p1-00rel0) which in turn connects to a replicator (DM-TM909-r0p1-00rel0). The replicator has two outputs, port 0 to a TPIU interface and port 1 to an ETB (DK-TM907-r0p3-00rel0). The CoreSight blocks are all clocked by the APEATCLK from the PRCMU and their AHB interconnect is clocked from a separate clock called APETRACECLK.

The SoC also has a CTI/CTM block which can be added later as we have upstream support in the CoreSight subsystem.

---
Mathieu: this patch will go into the ux500 tree if you think it looks OK. Just provide your ACK if you think it's looking good and I'll take care of it. The rest of the CoreSight stuff should be funneled through your tree I guess.

---
 arch/arm/boot/dts/ste-dbx5x0.dtsi | 129 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 129 insertions(+)
arch/arm/boot/dts/ste-dbx5x0.dtsi +109 -0
index bd6bd0926931..2f6ed08db9fe 100644
@@ -48,6 +48,135 @@
                        };
                };
 
+               ptm at 801ae000 {
+                       compatible = "arm,coresight-etm3x", "arm,primecell";
+                       reg = <0x801ae000 0x1000>;
+
+                       clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+                       clock-names = "apb_pclk", "atclk";
+                       cpu = <&CPU0>;
+                       port {
+                               ptm0_out_port: endpoint {
+                                       remote-endpoint = <&funnel_in_port0>;
+                               };
+                       };
+               };
+
+               ptm at 801af000 {
+                       compatible = "arm,coresight-etm3x", "arm,primecell";
+                       reg = <0x801af000 0x1000>;
+
+                       clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+                       clock-names = "apb_pclk", "atclk";
+                       cpu = <&CPU1>;
+                       port {
+                               ptm1_out_port: endpoint {
+                                       remote-endpoint = <&funnel_in_port1>;
+                               };
+                       };
+               };
+
+               funnel at 801a6000 {
+                       compatible = "arm,coresight-funnel", "arm,primecell";
+                       reg = <0x801a6000 0x1000>;
+
+                       clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+                       clock-names = "apb_pclk", "atclk";
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               /* funnel output ports */
+                               port at 0 {
+                                       reg = <0>;
+                                       funnel_out_port: endpoint {
+                                               remote-endpoint =
+                                                       <&replicator_in_port0>;
+                                       };
+                               };
+
+                               /* funnel input ports */
+                               port at 1 {
+                                       reg = <0>;
+                                       funnel_in_port0: endpoint {
+                                               slave-mode;
+                                               remote-endpoint = <&ptm0_out_port>;
+                                       };
+                               };
+
+                               port at 2 {
+                                       reg = <1>;
+                                       funnel_in_port1: endpoint {
+                                               slave-mode;
+                                               remote-endpoint = <&ptm1_out_port>;
+                                       };
+                               };
+                       };
+               };
+
+               replicator {
+                       compatible = "arm,coresight-replicator";
+                       clocks = <&prcmu_clk PRCMU_APEATCLK>;
+                       clock-names = "atclk";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               /* replicator output ports */
+                               port at 0 {
+                                       reg = <0>;
+                                       replicator_out_port0: endpoint {
+                                               remote-endpoint = <&tpiu_in_port>;
+                                       };
+                               };
+                               port at 1 {
+                                       reg = <1>;
+                                       replicator_out_port1: endpoint {
+                                               remote-endpoint = <&etb_in_port>;
+                                       };
+                               };
+
+                               /* replicator input port */
+                               port at 2 {
+                                       reg = <0>;
+                                       replicator_in_port0: endpoint {
+                                               slave-mode;
+                                               remote-endpoint = <&funnel_out_port>;
+                                       };
+                               };
+                       };
+               };
+
+               tpiu at 80190000 {
+                       compatible = "arm,coresight-tpiu", "arm,primecell";
+                       reg = <0x80190000 0x1000>;
+
+                       clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+                       clock-names = "apb_pclk", "atclk";
+                       port {
+                               tpiu_in_port: endpoint {
+                                       slave-mode;

arch/arm/boot/dts/ste-dbx5x0.dtsi line 169

Quoted 10 lines
arch/arm/boot/dts/ste-dbx5x0.dtsi +10 -0
+                                       remote-endpoint = <&replicator_out_port0>;
+                               };
+                       };
+               };
+
+               etb at 801a4000 {
+                       compatible = "arm,coresight-etb10", "arm,primecell";
+                       reg = <0x801a4000 0x1000>;
+
+                       coresight-default-sink;

This option is now obsolete and should be removed.

Quoted 14 lines
arch/arm/boot/dts/ste-dbx5x0.dtsi +10 -1
+                       clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
+                       clock-names = "apb_pclk", "atclk";
+                       port {
+                               etb_in_port: endpoint {
+                                       slave-mode;
+                                       remote-endpoint = <&replicator_out_port1>;
+                               };
+                       };
+               };
+
                intc: interrupt-controller at a0411000 {
                        compatible = "arm,cortex-a9-gic";
                        #interrupt-cells = <3>;
--
Quoted 2 lines

1.9.3

With the above change,

#25 lore raw

cover Enable CoreSight for the Ux500

In reply to Linus Walleij
Quoted 48 lines · Linus Walleij

This patch series enables the CoreSight blocks for the Ux500.

To do so I ran into a few obstacles, all resolved in this series:

- The Ux500 have two distinct clocks clocking the CS blocks, APETRACECLK clocking the AHB interconnect, what is usually referred to as "apb_pclk" in the AMBA primecell abstraction layer, and another clock called APEATCLK which is connected to the actual ATCLK on the CS blocks. So I have to add handling for this second clock as only the PCLK is handled today.

- Doing so I need to use runtime PM, and I discovered that the current CS drivers go in and grab the PCLK from the AMBA primecell abstraction which is wrong: this shall be handled using runtime PM callbacks, see e.g. drivers/mmc/host/mmci.c. So I made a patch series fixing this. This also fixes the problem that the PCLK is left on since none of the drivers call pm_runtime_put() so the AMBA core can disable the PCLK, instead they are poking around with the PCLK themselves which is wrong.

Linus Walleij (13):
coresight: etm: print what version of ETM/PTM is detected
coresight: support the TPIU version found in Ux500
coresight: etm: let runtime PM handle core clock
coresight: tpiu: let runtime PM handle core clock
coresight: etb: let runtime PM handle core clock
coresight: funnel: let runtime PM handle core clock
coresight: tmc: let runtime PM handle core clock
coresight: etm: retrieve and handle atclk
coresight: tpiu: retrieve and handle atclk
coresight: etb: retrieve and handle atclk
coresight: funnel: retrieve and handle atclk
coresight: replicator: retrieve and handle atclk
ARM: ux500: add CoreSight blocks to DTS file

 arch/arm/boot/dts/ste-dbx5x0.dtsi        | 129 +++++++++++++++++++++++++++++++
 drivers/coresight/coresight-etb10.c      |  74 +++++++++++-------
 drivers/coresight/coresight-etm.h        |   4 +-
 drivers/coresight/coresight-etm3x.c      | 102 +++++++++++++-----------
 drivers/coresight/coresight-funnel.c     |  63 +++++++++++----
 drivers/coresight/coresight-replicator.c |  43 +++++++++++
 drivers/coresight/coresight-tmc.c        |  20 ++---
 drivers/coresight/coresight-tpiu.c       |  62 +++++++++++----
 8 files changed, 376 insertions(+), 121 deletions(-)
Quoted 3 lines

--
1.9.3

Thank you for the submission.

I was waiting for issues with associating cpuidle_states and genPDs to be sorted out before sending my own patchset, which is pretty close to what you did, but this work can go in.

I'm in agreement with the comments raised by Ulf. Also this patchset doesn't apply against my coresight branch [1] or what is going into 4.1. Do you think you can get me another version?

Thanks,
Mathieu

[1]. https://git.linaro.org/kernel/coresight.git/ master

#26 lore raw

cover Enable CoreSight for the Ux500

In reply to Linus Walleij
Quoted 13 lines · Linus Walleij

This patch series enables the CoreSight blocks for the Ux500.

To do so I ran into a few obstacles, all resolved in this series:

- The Ux500 have two distinct clocks clocking the CS blocks, APETRACECLK clocking the AHB interconnect, what is usually referred to as "apb_pclk" in the AMBA primecell abstraction layer, and another clock called APEATCLK which is connected to the actual ATCLK on the CS blocks. So I have to add handling for this second clock as only the PCLK is handled today.

Quoted 9 lines

- Doing so I need to use runtime PM, and I discovered that the current CS drivers go in and grab the PCLK from the AMBA primecell abstraction which is wrong: this shall be handled using runtime PM callbacks, see e.g. drivers/mmc/host/mmci.c. So I made a patch series fixing this. This also fixes the problem that the PCLK is left on since none of the drivers call pm_runtime_put() so the AMBA core can disable the PCLK, instead they are poking around with the PCLK themselves which is wrong.

Probably stupid question, but.. How this is
supposed to work if CONFIG_PM is not enabled?

Regards,
Ivan

#27 lore raw

cover Enable CoreSight for the Ux500

Quoted 25 lines · Ivan T. Ivanov
Quoted 13 lines · Linus Walleij

This patch series enables the CoreSight blocks for the Ux500.

To do so I ran into a few obstacles, all resolved in this series:

- The Ux500 have two distinct clocks clocking the CS blocks, APETRACECLK clocking the AHB interconnect, what is usually referred to as "apb_pclk" in the AMBA primecell abstraction layer, and another clock called APEATCLK which is connected to the actual ATCLK on the CS blocks. So I have to add handling for this second clock as only the PCLK is handled today.

Quoted 9 lines

- Doing so I need to use runtime PM, and I discovered that the current CS drivers go in and grab the PCLK from the AMBA primecell abstraction which is wrong: this shall be handled using runtime PM callbacks, see e.g. drivers/mmc/host/mmci.c. So I made a patch series fixing this. This also fixes the problem that the PCLK is left on since none of the drivers call pm_runtime_put() so the AMBA core can disable the PCLK, instead they are poking around with the PCLK themselves which is wrong.

Quoted 2 lines

Probably stupid question, but.. How this is
supposed to work if CONFIG_PM is not enabled?

The clock(s) will stay enabled after ->probe().

Kind regards
Uffe

#28 lore raw

cover Enable CoreSight for the Ux500

Quoted 29 lines · Ulf Hansson
Quoted 25 lines · Ivan T. Ivanov
Quoted 22 lines · Linus Walleij

This patch series enables the CoreSight blocks for the Ux500.

To do so I ran into a few obstacles, all resolved in this series:

- The Ux500 have two distinct clocks clocking the CS blocks, APETRACECLK clocking the AHB interconnect, what is usually referred to as "apb_pclk" in the AMBA primecell abstraction layer, and another clock called APEATCLK which is connected to the actual ATCLK on the CS blocks. So I have to add handling for this second clock as only the PCLK is handled today.

- Doing so I need to use runtime PM, and I discovered that the current CS drivers go in and grab the PCLK from the AMBA primecell abstraction which is wrong: this shall be handled using runtime PM callbacks, see e.g. drivers/mmc/host/mmci.c. So I made a patch series fixing this. This also fixes the problem that the PCLK is left on since none of the drivers call pm_runtime_put() so the AMBA core can disable the PCLK, instead they are poking around with the PCLK themselves which is wrong.

Quoted 4 lines
Quoted 2 lines

Probably stupid question, but.. How this is
supposed to work if CONFIG_PM is not enabled?

The clock(s) will stay enabled after ->probe().

Thanks. I have missed explicit ATCLCK enable in probe.

Regards,
Ivan