From patchwork Wed May 6 15:27:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Poirier X-Patchwork-Id: 48063 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f199.google.com (mail-lb0-f199.google.com [209.85.217.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2DF012121F for ; Wed, 6 May 2015 15:31:22 +0000 (UTC) Received: by lbos2 with SMTP id s2sf4122973lbo.2 for ; Wed, 06 May 2015 08:31:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:subject:date:message-id :in-reply-to:references:cc:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :content-type:content-transfer-encoding:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list; bh=+7mSOHfv8xw411HGPSxpW/SMByf95vhWIbfAbRHGprI=; b=DROYNF5JOr1SO1xOTRNbXvhwL5ZMdO+Dw93MYkpzYF6T9CixEfVYGhkn8pVnZz54ak UJDgQxhC7+2NAoqyP6OciwVuwwfBQupvQ2B7lbD9BJQlPUF/t0Xr74h0pSXdhf26FXnV +tbOA+sAmPDfqF+DxBAmzZ/GREtNFlpx7CPsMc7Lt7h0JbTHCc9YzghuSAo74LaNgyWg FDVspOlg2xt1S3s2QqoAnh+IgKPkNef95B8o/5y02k7ohSFpptEYg1vKf0VuvquBW7xj aZLJfBTqlAWg2PAA4olf65D6gSx+Q5NhDMoqkdBd8CYoOP4UtcvbPGFW0dYqMUpJ2tN/ m/4Q== X-Gm-Message-State: ALoCoQlkJd12UN3RuIXQtiOwsa7m6dkrEu6vR3pb8dZvbhsfjGVeEacgE9/ExAQ9JxueR7qcMKQA X-Received: by 10.112.51.68 with SMTP id i4mr26405557lbo.13.1430926280699; Wed, 06 May 2015 08:31:20 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.43.8 with SMTP id s8ls61945lal.67.gmail; Wed, 06 May 2015 08:31:20 -0700 (PDT) X-Received: by 10.112.17.8 with SMTP id k8mr28912701lbd.28.1430926280555; Wed, 06 May 2015 08:31:20 -0700 (PDT) Received: from mail-la0-f46.google.com (mail-la0-f46.google.com. [209.85.215.46]) by mx.google.com with ESMTPS id j11si14929070lbg.95.2015.05.06.08.31.20 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 May 2015 08:31:20 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.46 as permitted sender) client-ip=209.85.215.46; Received: by laat2 with SMTP id t2so10252525laa.1 for ; Wed, 06 May 2015 08:31:20 -0700 (PDT) X-Received: by 10.152.27.1 with SMTP id p1mr28315779lag.112.1430926280430; Wed, 06 May 2015 08:31:20 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.67.65 with SMTP id l1csp2923530lbt; Wed, 6 May 2015 08:31:19 -0700 (PDT) X-Received: by 10.70.123.168 with SMTP id mb8mr61791281pdb.100.1430926278118; Wed, 06 May 2015 08:31:18 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id z11si29460863pas.160.2015.05.06.08.31.17 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 May 2015 08:31:18 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) client-ip=2001:1868:205::9; 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 1Yq1G8-0006Zn-Up; Wed, 06 May 2015 15:29:16 +0000 Received: from mail-pa0-f47.google.com ([209.85.220.47]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Yq1FJ-0006AA-GC for linux-arm-kernel@lists.infradead.org; Wed, 06 May 2015 15:28:27 +0000 Received: by pacyx8 with SMTP id yx8so12403093pac.1 for ; Wed, 06 May 2015 08:28:04 -0700 (PDT) X-Received: by 10.66.142.169 with SMTP id rx9mr62826481pab.84.1430926084376; Wed, 06 May 2015 08:28:04 -0700 (PDT) Received: from t430.cg.shawcable.net ([184.64.168.246]) by mx.google.com with ESMTPSA id fp3sm2221174pdb.52.2015.05.06.08.28.02 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 May 2015 08:28:03 -0700 (PDT) From: Mathieu Poirier To: gregkh@linuxfoundation.org Subject: [PATCH v3 03/11] coresight-etm4x: Controls pertaining to the reset, mode, pe and events Date: Wed, 6 May 2015 09:27:19 -0600 Message-Id: <1430926047-9125-4-git-send-email-mathieu.poirier@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1430926047-9125-1-git-send-email-mathieu.poirier@linaro.org> References: <1430926047-9125-1-git-send-email-mathieu.poirier@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150506_082825_667026_C7A58C50 X-CRM114-Status: GOOD ( 18.98 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.220.47 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.220.47 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record Cc: mathieu.poirier@linaro.org, linux-api@vger.kernel.org, linux-kernel@vger.kernel.org, zhang.chunyan@linaro.org, linux-arm-kernel@lists.infradead.org, kaixu.xia@linaro.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: mathieu.poirier@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.46 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Pratik Patel Adding sysfs entries to: . set the tracing entity with default values. . set various mode associated to the tracing entity. . select the processing entity the tracing entity relates to. . select various events of interest. Signed-off-by: Pratik Patel Signed-off-by: Mathieu Poirier --- .../ABI/testing/sysfs-bus-coresight-devices-etm4x | 33 ++ drivers/hwtracing/coresight/coresight-etm4x.c | 442 ++++++++++++++++++++- 2 files changed, 474 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x index 0f579eb24631..9caf70382088 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x @@ -87,3 +87,36 @@ KernelVersion: 4.01 Contact: Mathieu Poirier Description: (R) Indicates the number of single-shot comparator controls that are available for tracing. + +What: /sys/bus/coresight/devices/.etm/reset +Date: April 2015 +KernelVersion: 4.01 +Contact: Mathieu Poirier +Description: (W) Cancels all configuration on a trace unit and set it back + to its boot configuration. + +What: /sys/bus/coresight/devices/.etm/mode +Date: April 2015 +KernelVersion: 4.01 +Contact: Mathieu Poirier +Description: (RW) Controls various modes supported by this ETM, for example + P0 instruction tracing, branch broadcast, cycle counting and + context ID tracing. + +What: /sys/bus/coresight/devices/.etm/pe +Date: April 2015 +KernelVersion: 4.01 +Contact: Mathieu Poirier +Description: (RW) Controls which PE to trace. + +What: /sys/bus/coresight/devices/.etm/event +Date: April 2015 +KernelVersion: 4.01 +Contact: Mathieu Poirier +Description: (RW) Controls the tracing of arbitrary events from bank 0 to 3. + +What: /sys/bus/coresight/devices/.etm/event_instren +Date: April 2015 +KernelVersion: 4.01 +Contact: Mathieu Poirier +Description: (RW) Controls the behavior of the events in bank 0 to 3. diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index c7421f319350..1a93b968ab6e 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -268,6 +268,46 @@ static const struct coresight_ops etm4_cs_ops = { .source_ops = &etm4_source_ops, }; +static int etm4_set_mode_exclude(struct etmv4_drvdata *drvdata, bool exclude) +{ + u8 idx = drvdata->addr_idx; + + /* + * TRCACATRn.TYPE bit[1:0]: type of comparison + * the trace unit performs + */ + if (BMVAL(drvdata->addr_acc[idx], 0, 1) == ETM_INSTR_ADDR) { + if (idx % 2 != 0) + return -EINVAL; + + /* + * We are performing instruction address comparison. Set the + * relevant bit of ViewInst Include/Exclude Control register + * for corresponding address comparator pair. + */ + if (drvdata->addr_type[idx] != ETM_ADDR_TYPE_RANGE || + drvdata->addr_type[idx + 1] != ETM_ADDR_TYPE_RANGE) + return -EINVAL; + + if (exclude == true) { + /* + * Set exclude bit and unset the include bit + * corresponding to comparator pair + */ + drvdata->viiectlr |= BIT(idx / 2 + 16); + drvdata->viiectlr &= ~BIT(idx / 2); + } else { + /* + * Set include bit and unset exclude bit + * corresponding to comparator pair + */ + drvdata->viiectlr |= BIT(idx / 2); + drvdata->viiectlr &= ~BIT(idx / 2 + 16); + } + } + return 0; +} + static ssize_t nr_pe_cmp_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -376,6 +416,402 @@ static ssize_t nr_ss_cmp_show(struct device *dev, } static DEVICE_ATTR_RO(nr_ss_cmp); +static ssize_t reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int i; + unsigned long val; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (kstrtoul(buf, 16, &val)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + if (val) + drvdata->mode = 0x0; + + /* Disable data tracing: do not trace load and store data transfers */ + drvdata->mode &= ~(ETM_MODE_LOAD | ETM_MODE_STORE); + drvdata->cfg &= ~(BIT(1) | BIT(2)); + + /* Disable data value and data address tracing */ + drvdata->mode &= ~(ETM_MODE_DATA_TRACE_ADDR | + ETM_MODE_DATA_TRACE_VAL); + drvdata->cfg &= ~(BIT(16) | BIT(17)); + + /* Disable all events tracing */ + drvdata->eventctrl0 = 0x0; + drvdata->eventctrl1 = 0x0; + + /* Disable timestamp event */ + drvdata->ts_ctrl = 0x0; + + /* Disable stalling */ + drvdata->stall_ctrl = 0x0; + + /* Reset trace synchronization period to 2^8 = 256 bytes*/ + if (drvdata->syncpr == false) + drvdata->syncfreq = 0x8; + + /* + * Enable ViewInst to trace everything with start-stop logic in + * started state. ARM recommends start-stop logic is set before + * each trace run. + */ + drvdata->vinst_ctrl |= BIT(0); + if (drvdata->nr_addr_cmp == true) { + drvdata->mode |= ETM_MODE_VIEWINST_STARTSTOP; + /* SSSTATUS, bit[9] */ + drvdata->vinst_ctrl |= BIT(9); + } + + /* No address range filtering for ViewInst */ + drvdata->viiectlr = 0x0; + + /* No start-stop filtering for ViewInst */ + drvdata->vissctlr = 0x0; + + /* Disable seq events */ + for (i = 0; i < drvdata->nrseqstate-1; i++) + drvdata->seq_ctrl[i] = 0x0; + drvdata->seq_rst = 0x0; + drvdata->seq_state = 0x0; + + /* Disable external input events */ + drvdata->ext_inp = 0x0; + + drvdata->cntr_idx = 0x0; + for (i = 0; i < drvdata->nr_cntr; i++) { + drvdata->cntrldvr[i] = 0x0; + drvdata->cntr_ctrl[i] = 0x0; + drvdata->cntr_val[i] = 0x0; + } + + drvdata->res_idx = 0x0; + for (i = 0; i < drvdata->nr_resource; i++) + drvdata->res_ctrl[i] = 0x0; + + for (i = 0; i < drvdata->nr_ss_cmp; i++) { + drvdata->ss_ctrl[i] = 0x0; + drvdata->ss_pe_cmp[i] = 0x0; + } + + drvdata->addr_idx = 0x0; + for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) { + drvdata->addr_val[i] = 0x0; + drvdata->addr_acc[i] = 0x0; + drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE; + } + + drvdata->ctxid_idx = 0x0; + for (i = 0; i < drvdata->numcidc; i++) + drvdata->ctxid_val[i] = 0x0; + drvdata->ctxid_mask0 = 0x0; + drvdata->ctxid_mask1 = 0x0; + + drvdata->vmid_idx = 0x0; + for (i = 0; i < drvdata->numvmidc; i++) + drvdata->vmid_val[i] = 0x0; + drvdata->vmid_mask0 = 0x0; + drvdata->vmid_mask1 = 0x0; + + drvdata->trcid = drvdata->cpu + 1; + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_WO(reset); + +static ssize_t mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + unsigned long val; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->mode; + return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); +} + +static ssize_t mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val, mode; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (kstrtoul(buf, 16, &val)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + drvdata->mode = val & ETMv4_MODE_ALL; + + if (drvdata->mode & ETM_MODE_EXCLUDE) + etm4_set_mode_exclude(drvdata, true); + else + etm4_set_mode_exclude(drvdata, false); + + if (drvdata->instrp0 == true) { + /* start by clearing instruction P0 field */ + drvdata->cfg &= ~(BIT(1) | BIT(2)); + if (drvdata->mode & ETM_MODE_LOAD) + /* 0b01 Trace load instructions as P0 instructions */ + drvdata->cfg |= BIT(1); + if (drvdata->mode & ETM_MODE_STORE) + /* 0b10 Trace store instructions as P0 instructions */ + drvdata->cfg |= BIT(2); + if (drvdata->mode & ETM_MODE_LOAD_STORE) + /* + * 0b11 Trace load and store instructions + * as P0 instructions + */ + drvdata->cfg |= BIT(1) | BIT(2); + } + + /* bit[3], Branch broadcast mode */ + if ((drvdata->mode & ETM_MODE_BB) && (drvdata->trcbb == true)) + drvdata->cfg |= BIT(3); + else + drvdata->cfg &= ~BIT(3); + + /* bit[4], Cycle counting instruction trace bit */ + if ((drvdata->mode & ETMv4_MODE_CYCACC) && + (drvdata->trccci == true)) + drvdata->cfg |= BIT(4); + else + drvdata->cfg &= ~BIT(4); + + /* bit[6], Context ID tracing bit */ + if ((drvdata->mode & ETMv4_MODE_CTXID) && (drvdata->ctxid_size)) + drvdata->cfg |= BIT(6); + else + drvdata->cfg &= ~BIT(6); + + if ((drvdata->mode & ETM_MODE_VMID) && (drvdata->vmid_size)) + drvdata->cfg |= BIT(7); + else + drvdata->cfg &= ~BIT(7); + + /* bits[10:8], Conditional instruction tracing bit */ + mode = ETM_MODE_COND(drvdata->mode); + if (drvdata->trccond == true) { + drvdata->cfg &= ~(BIT(8) | BIT(9) | BIT(10)); + drvdata->cfg |= mode << 8; + } + + /* bit[11], Global timestamp tracing bit */ + if ((drvdata->mode & ETMv4_MODE_TIMESTAMP) && (drvdata->ts_size)) + drvdata->cfg |= BIT(11); + else + drvdata->cfg &= ~BIT(11); + + /* bit[12], Return stack enable bit */ + if ((drvdata->mode & ETM_MODE_RETURNSTACK) && + (drvdata->retstack == true)) + drvdata->cfg |= BIT(12); + else + drvdata->cfg &= ~BIT(12); + + /* bits[14:13], Q element enable field */ + mode = ETM_MODE_QELEM(drvdata->mode); + /* start by clearing QE bits */ + drvdata->cfg &= ~(BIT(13) | BIT(14)); + /* if supported, Q elements with instruction counts are enabled */ + if ((mode & BIT(0)) && (drvdata->q_support & BIT(0))) + drvdata->cfg |= BIT(13); + /* + * if supported, Q elements with and without instruction + * counts are enabled + */ + if ((mode & BIT(1)) && (drvdata->q_support & BIT(1))) + drvdata->cfg |= BIT(14); + + /* bit[11], AMBA Trace Bus (ATB) trigger enable bit */ + if ((drvdata->mode & ETM_MODE_ATB_TRIGGER) && + (drvdata->atbtrig == true)) + drvdata->eventctrl1 |= BIT(11); + else + drvdata->eventctrl1 &= ~BIT(11); + + /* bit[12], Low-power state behavior override bit */ + if ((drvdata->mode & ETM_MODE_LPOVERRIDE) && + (drvdata->lpoverride == true)) + drvdata->eventctrl1 |= BIT(12); + else + drvdata->eventctrl1 &= ~BIT(12); + + /* bit[8], Instruction stall bit */ + if (drvdata->mode & ETM_MODE_ISTALL_EN) + drvdata->stall_ctrl |= BIT(8); + else + drvdata->stall_ctrl &= ~BIT(8); + + /* bit[10], Prioritize instruction trace bit */ + if (drvdata->mode & ETM_MODE_INSTPRIO) + drvdata->stall_ctrl |= BIT(10); + else + drvdata->stall_ctrl &= ~BIT(10); + + /* bit[13], Trace overflow prevention bit */ + if ((drvdata->mode & ETM_MODE_NOOVERFLOW) && + (drvdata->nooverflow == true)) + drvdata->stall_ctrl |= BIT(13); + else + drvdata->stall_ctrl &= ~BIT(13); + + /* bit[9] Start/stop logic control bit */ + if (drvdata->mode & ETM_MODE_VIEWINST_STARTSTOP) + drvdata->vinst_ctrl |= BIT(9); + else + drvdata->vinst_ctrl &= ~BIT(9); + + /* bit[10], Whether a trace unit must trace a Reset exception */ + if (drvdata->mode & ETM_MODE_TRACE_RESET) + drvdata->vinst_ctrl |= BIT(10); + else + drvdata->vinst_ctrl &= ~BIT(10); + + /* bit[11], Whether a trace unit must trace a system error exception */ + if ((drvdata->mode & ETM_MODE_TRACE_ERR) && + (drvdata->trc_error == true)) + drvdata->vinst_ctrl |= BIT(11); + else + drvdata->vinst_ctrl &= ~BIT(11); + + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(mode); + +static ssize_t pe_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + unsigned long val; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->pe_sel; + return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); +} + +static ssize_t pe_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (kstrtoul(buf, 16, &val)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + if (val > drvdata->nr_pe) { + spin_unlock(&drvdata->spinlock); + return -EINVAL; + } + + drvdata->pe_sel = val; + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(pe); + +static ssize_t event_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + unsigned long val; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = drvdata->eventctrl0; + return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); +} + +static ssize_t event_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (kstrtoul(buf, 16, &val)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + switch (drvdata->nr_event) { + case 0x0: + /* EVENT0, bits[7:0] */ + drvdata->eventctrl0 = val & 0xFF; + break; + case 0x1: + /* EVENT1, bits[15:8] */ + drvdata->eventctrl0 = val & 0xFFFF; + break; + case 0x2: + /* EVENT2, bits[23:16] */ + drvdata->eventctrl0 = val & 0xFFFFFF; + break; + case 0x3: + /* EVENT3, bits[31:24] */ + drvdata->eventctrl0 = val; + break; + default: + break; + } + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(event); + +static ssize_t event_instren_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + unsigned long val; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); + + val = BMVAL(drvdata->eventctrl1, 0, 3); + return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); +} + +static ssize_t event_instren_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (kstrtoul(buf, 16, &val)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + /* start by clearing all instruction event enable bits */ + drvdata->eventctrl1 &= ~(BIT(0) | BIT(1) | BIT(2) | BIT(3)); + switch (drvdata->nr_event) { + case 0x0: + /* generate Event element for event 1 */ + drvdata->eventctrl1 |= val & BIT(1); + break; + case 0x1: + /* generate Event element for event 1 and 2 */ + drvdata->eventctrl1 |= val & (BIT(0) | BIT(1)); + break; + case 0x2: + /* generate Event element for event 1, 2 and 3 */ + drvdata->eventctrl1 |= val & (BIT(0) | BIT(1) | BIT(2)); + break; + case 0x3: + /* generate Event element for all 4 events */ + drvdata->eventctrl1 |= val & 0xF; + break; + default: + break; + } + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(event_instren); + static ssize_t status_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -518,7 +954,6 @@ static ssize_t trcidr_show(struct device *dev, return ret; } static DEVICE_ATTR_RO(trcidr); - static struct attribute *coresight_etmv4_attrs[] = { &dev_attr_nr_pe_cmp.attr, &dev_attr_nr_addr_cmp.attr, @@ -529,6 +964,11 @@ static struct attribute *coresight_etmv4_attrs[] = { &dev_attr_nrseqstate.attr, &dev_attr_nr_resource.attr, &dev_attr_nr_ss_cmp.attr, + &dev_attr_reset.attr, + &dev_attr_mode.attr, + &dev_attr_pe.attr, + &dev_attr_event.attr, + &dev_attr_event_instren.attr, &dev_attr_status.attr, &dev_attr_mgmt.attr, &dev_attr_trcidr.attr,