From patchwork Fri Dec 18 20:59:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Poirier X-Patchwork-Id: 7888041 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CD5D89F387 for ; Fri, 18 Dec 2015 21:03:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8092A20519 for ; Fri, 18 Dec 2015 21:03:44 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4AA602051D for ; Fri, 18 Dec 2015 21:03:43 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aA2A6-0006Vo-Sn; Fri, 18 Dec 2015 21:02:02 +0000 Received: from mail-io0-x229.google.com ([2607:f8b0:4001:c06::229]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aA28I-00047x-C6 for linux-arm-kernel@lists.infradead.org; Fri, 18 Dec 2015 21:00:14 +0000 Received: by mail-io0-x229.google.com with SMTP id q126so102236348iof.2 for ; Fri, 18 Dec 2015 12:59:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=EBtHHsmlFqSGM5aDwiyifO6PSie4jkkWRYROtZPhrBU=; b=jGRVxTJfH/2iZC0vkCDZWVBH6sUztcaUEu1qykPeYc8x/qUnk3sROKL6VEoy5ueMwC 7lt0Km7eY6JmQWo4a7gVc2AQHmz03OF/7XpA7FNqRW/v+RkcoyMgdPWxh4V0kYvdadvU GW/ZAcLgIZseFMqMG1798Z3/nq6Uay/iSFkps= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=EBtHHsmlFqSGM5aDwiyifO6PSie4jkkWRYROtZPhrBU=; b=RFG2rqnSvpniL7BDZmc0wZCmpp8kbBaGmPZu6gTyYnVUTQXKIuMxwCxQnkwWYjr7iw b1W9PPABkhVOBh+roQxpIOby4xfl8KRxW1N3684JMRKDq488CtvT1BLz8scgyh1oKt1I FMuUMuQaRfQBbErmKPRVlROY/3qPObR4gdt34i5rW8BBKZM+9XS4vNHlx7T5i3zLgAff BqQXkrortPqyBoraCm6cwB7GDOSYjJ8UolFIgayFESK09oikP+sFO8WnAXw72Lt6kwE+ 7U9gNap/3g0m7UjULFpj+IReWiW0snPhABz8wUH0NnCC7VeCYaLD9d+zmoGnNzu33+uG f6mA== X-Gm-Message-State: ALoCoQkEgNz8wvOlzzFrwp6TzCveBpmComgjqNLTrRwfavjOxxQN0sdAK5ud5kY7xkIlEayPzUDaadl/65RQtfwp40DAlvv2DQ== X-Received: by 10.107.33.212 with SMTP id h203mr7246376ioh.186.1450472393384; Fri, 18 Dec 2015 12:59:53 -0800 (PST) Received: from t430.cg.shawcable.net (S0106002369de4dac.cg.shawcable.net. [184.64.168.246]) by smtp.gmail.com with ESMTPSA id l10sm843701igx.18.2015.12.18.12.59.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 18 Dec 2015 12:59:52 -0800 (PST) From: Mathieu Poirier To: gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com Subject: [PATCH V7 09/24] coresight: etm3x: adding operation mode for etm_enable() Date: Fri, 18 Dec 2015 13:59:05 -0700 Message-Id: <1450472361-426-10-git-send-email-mathieu.poirier@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1450472361-426-1-git-send-email-mathieu.poirier@linaro.org> References: <1450472361-426-1-git-send-email-mathieu.poirier@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151218_130010_615416_D893F832 X-CRM114-Status: GOOD ( 21.03 ) X-Spam-Score: -2.7 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: al.grant@arm.com, Mathieu Poirier , linux-doc@vger.kernel.org, fainelli@broadcom.com, linux-kernel@vger.kernel.org, tor@ti.com, mike.leach@arm.com, zhang.chunyan@linaro.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Adding a new mode to source API enable() in order to distinguish where the request comes from. That way it is possible to perform different operations based on where the request was issued from. The ETM4x driver is also modified to keep in sync with the new interface. Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etm.h | 5 +- .../hwtracing/coresight/coresight-etm3x-sysfs.c | 4 +- drivers/hwtracing/coresight/coresight-etm3x.c | 68 +++++++++++++++++++--- drivers/hwtracing/coresight/coresight-etm4x.c | 2 +- drivers/hwtracing/coresight/coresight-priv.h | 6 ++ drivers/hwtracing/coresight/coresight.c | 6 +- include/linux/coresight.h | 2 +- 7 files changed, 76 insertions(+), 17 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h index 371fb7d2e829..5b29d5540fe5 100644 --- a/drivers/hwtracing/coresight/coresight-etm.h +++ b/drivers/hwtracing/coresight/coresight-etm.h @@ -13,6 +13,7 @@ #ifndef _CORESIGHT_CORESIGHT_ETM_H #define _CORESIGHT_CORESIGHT_ETM_H +#include #include #include "coresight-priv.h" @@ -214,7 +215,7 @@ struct etm_config { * @port_size: port size as reported by ETMCR bit 4-6 and 21. * @arch: ETM/PTM version number. * @use_cpu14: true if management registers need to be accessed via CP14. - * @enable: is this ETM/PTM currently tracing. + * @mode: this tracer's mode, i.e sysFS, Perf or disabled. * @sticky_enable: true if ETM base configuration has been done. * @boot_enable:true if we should start tracing at boot time. * @os_unlock: true if access to management registers is allowed. @@ -238,7 +239,7 @@ struct etm_drvdata { int port_size; u8 arch; bool use_cp14; - bool enable; + local_t mode; bool sticky_enable; bool boot_enable; bool os_unlock; diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c index 456df2378a6f..387c79fd9d5e 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c @@ -716,7 +716,7 @@ static ssize_t cntr_val_show(struct device *dev, struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); struct etm_config *config = &drvdata->config; - if (!drvdata->enable) { + if (!local_read(&drvdata->mode)) { spin_lock(&drvdata->spinlock); for (i = 0; i < drvdata->nr_cntr; i++) ret += sprintf(buf, "counter %d: %x\n", @@ -935,7 +935,7 @@ static ssize_t seq_curr_state_show(struct device *dev, struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent); struct etm_config *config = &drvdata->config; - if (!drvdata->enable) { + if (!local_read(&drvdata->mode)) { val = config->seq_curr_state; goto out; } diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 3036154e1a6a..ff9b83d02cb7 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -306,7 +306,7 @@ int etm_get_trace_id(struct etm_drvdata *drvdata) if (!drvdata) goto out; - if (!drvdata->enable) + if (!local_read(&drvdata->mode)) return drvdata->traceid; pm_runtime_get_sync(drvdata->dev); @@ -332,7 +332,7 @@ static int etm_trace_id(struct coresight_device *csdev) return etm_get_trace_id(drvdata); } -static int etm_enable(struct coresight_device *csdev) +static int etm_enable_sysfs(struct coresight_device *csdev) { struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); int ret; @@ -351,18 +351,44 @@ static int etm_enable(struct coresight_device *csdev) goto err; } - drvdata->enable = true; drvdata->sticky_enable = true; - spin_unlock(&drvdata->spinlock); dev_info(drvdata->dev, "ETM tracing enabled\n"); return 0; + err: spin_unlock(&drvdata->spinlock); return ret; } +static int etm_enable(struct coresight_device *csdev, u32 mode) +{ + int ret; + u32 val; + struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + val = local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode); + + /* Someone is already using the tracer */ + if (val) + return -EBUSY; + + switch (mode) { + case CS_MODE_SYSFS: + ret = etm_enable_sysfs(csdev); + break; + default: + ret = -EINVAL; + } + + /* The tracer didn't start */ + if (ret) + local_set(&drvdata->mode, CS_MODE_DISABLED); + + return ret; +} + static void etm_disable_hw(void *info) { int i; @@ -387,7 +413,7 @@ static void etm_disable_hw(void *info) dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu); } -static void etm_disable(struct coresight_device *csdev) +static void etm_disable_sysfs(struct coresight_device *csdev) { struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct etm_config *config = &drvdata->config; @@ -406,7 +432,6 @@ static void etm_disable(struct coresight_device *csdev) * ensures that register writes occur when cpu is powered. */ smp_call_function_single(drvdata->cpu, etm_disable_hw, drvdata, 1); - drvdata->enable = false; kfree(config); spin_unlock(&drvdata->spinlock); @@ -415,6 +440,33 @@ static void etm_disable(struct coresight_device *csdev) dev_info(drvdata->dev, "ETM tracing disabled\n"); } +static void etm_disable(struct coresight_device *csdev) +{ + u32 mode; + struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + /* + * For as long as the tracer isn't disabled another entity can't + * change its status. As such we can read the status here without + * fearing it will change under us. + */ + mode = local_read(&drvdata->mode); + + switch (mode) { + case CS_MODE_DISABLED: + break; + case CS_MODE_SYSFS: + etm_disable_sysfs(csdev); + break; + default: + WARN_ON_ONCE(mode); + return; + } + + if (mode) + local_set(&drvdata->mode, CS_MODE_DISABLED); +} + static const struct coresight_ops_source etm_source_ops = { .cpu_id = etm_cpu_id, .trace_id = etm_trace_id, @@ -442,7 +494,7 @@ static int etm_cpu_callback(struct notifier_block *nfb, unsigned long action, etmdrvdata[cpu]->os_unlock = true; } - if (etmdrvdata[cpu]->enable) + if (local_read(&etmdrvdata[cpu]->mode)) etm_enable_hw(etmdrvdata[cpu]); spin_unlock(&etmdrvdata[cpu]->spinlock); break; @@ -455,7 +507,7 @@ static int etm_cpu_callback(struct notifier_block *nfb, unsigned long action, case CPU_DYING: spin_lock(&etmdrvdata[cpu]->spinlock); - if (etmdrvdata[cpu]->enable) + if (local_read(&etmdrvdata[cpu]->mode)) etm_disable_hw(etmdrvdata[cpu]); spin_unlock(&etmdrvdata[cpu]->spinlock); break; diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 1c6e32dd6e49..4ab291b3a6c8 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -180,7 +180,7 @@ static void etm4_enable_hw(void *info) dev_dbg(drvdata->dev, "cpu: %d enable smp call done\n", drvdata->cpu); } -static int etm4_enable(struct coresight_device *csdev) +static int etm4_enable(struct coresight_device *csdev, u32 mode) { struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); int ret; diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 14f245a2018d..ed116b303e87 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -34,6 +34,12 @@ #define TIMEOUT_US 100 #define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb) +enum cs_mode { + CS_MODE_DISABLED, + CS_MODE_SYSFS, + CS_MODE_PERF, +}; + static inline void CS_LOCK(void __iomem *addr) { do { diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index d053e5940fbf..c02da2edfd80 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -222,7 +222,7 @@ static void coresight_disable_link(struct coresight_device *csdev, csdev->enable = false; } -static int coresight_enable_source(struct coresight_device *csdev) +static int coresight_enable_source(struct coresight_device *csdev, u32 mode) { int ret; @@ -234,7 +234,7 @@ static int coresight_enable_source(struct coresight_device *csdev) if (!csdev->enable) { if (source_ops(csdev)->enable) { - ret = source_ops(csdev)->enable(csdev); + ret = source_ops(csdev)->enable(csdev, mode); if (ret) return ret; } @@ -458,7 +458,7 @@ int coresight_enable(struct coresight_device *csdev) if (ret) goto err_path; - ret = coresight_enable_source(csdev); + ret = coresight_enable_source(csdev, CS_MODE_SYSFS); if (ret) goto err_source; diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 851ecb22397e..61dfb8d511ea 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -213,7 +213,7 @@ struct coresight_ops_link { struct coresight_ops_source { int (*cpu_id)(struct coresight_device *csdev); int (*trace_id)(struct coresight_device *csdev); - int (*enable)(struct coresight_device *csdev); + int (*enable)(struct coresight_device *csdev, u32 mode); void (*disable)(struct coresight_device *csdev); };