From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CBD11C2D0E4 for ; Tue, 17 Nov 2020 19:00:51 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 56F2924181 for ; Tue, 17 Nov 2020 19:00:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="rQWXCiLK"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="UylTm50K" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 56F2924181 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:Message-ID: Subject:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=69+x2RtuGErF8h6TwLb2MXG/0KGF42LSv4P4Q2qnoXI=; b=rQWXCiLKrVXYanvZS6qQwX8gv fJa9VgExCuyhZTCm00rPhvAEm2TkrE1vaP3PFVMSGmmtYT8rniomSnn0A71NBEaOdMhbTZs/6mD7e DsZ9Xj0CdVhePxHYDSKfVxa7VBTGTsRO0YX/bh57cUK/hR/d7iiLPnzxTfwNdzr8npz9J2vKlXGR9 OZQS8HxZgsqlSZkbuz+HFljDLkQTslH7B4ErzsffN649H2FiIFjguHxYbITXD6JOpu8vkbqMbqfIb ah2r0fplK4rR2eF4qzzkoMwAPFH0MzO5WSkXaZAC9O2gkj44+iBAcLja4b2AzPrp4SzjrbQ5lj6de d/ufh41Rg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kf6DF-0006Ec-MU; Tue, 17 Nov 2020 19:00:21 +0000 Received: from mail-pl1-x644.google.com ([2607:f8b0:4864:20::644]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kf6DC-0006E3-Ah for linux-arm-kernel@lists.infradead.org; Tue, 17 Nov 2020 19:00:19 +0000 Received: by mail-pl1-x644.google.com with SMTP id j5so10747668plk.7 for ; Tue, 17 Nov 2020 11:00:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=MlzpAROtnXHXhv34SanNKUOCUV8WClhXmbdr26suGtY=; b=UylTm50KxVhB1X9CBdQ8DlsTwfzeKmaiO/UUNV4inS98XmdHlE+ZC/YU4e/GO5kUMK oy3mhx9ecL4OeZiZemmKJ5WI9YowcgYOgGU2aDK1FQ+Y6jmxNMnIh6TMbWx6127CEW4W Hk0lTLVCeTAEKc1Qbr1kFEvQa2wFMrMZhUS9wqHVJZ6NBvN/fEW5VSHuzZHr9HlUFZpd dlLIolpkNksG1CAc2rhByGOhCy8/Pgcz0b6k94BHNSai+0NcwPRiCDpdSxXYAyvD2H98 nmwJnPD9nB3Bsk8C7s/FVYuNr6haN5vVEzagXd6LXeRonVkQdHRANPceMeO2+I4uKgA2 7ALw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=MlzpAROtnXHXhv34SanNKUOCUV8WClhXmbdr26suGtY=; b=fo9bO3Mue/IICPsZ5aTS9LyxfXv4020nY3pe4uS8jbVPTB0xBeMdYFSUWrqfOcSg23 /5fQr1gGV67iYjW67N0EDXMioWP8APBsEUU7qXU3l8KDs0lfHu1ezcCVnpyz7sEpJ7y1 Hz781TFEAPAz2tDkifIuTOhbV5LWw+Kt25tryBXEKG41HX+a8tecqKVYK8M2KFHQAUNJ xSfvoYmIsQ79SJKjqKqRdXyHx3Bj2p7t74nZwNFBYEm2w0/rtyW+BUHDAEV2mXtBySKN 5CMMwYukglRhPt5wFsYsyIW7zQg/SezOFMdKDsGCsThy76O1RIwKfQCtkHsoOxl3wnnA mB9Q== X-Gm-Message-State: AOAM5302iqnYVo3lm4kUPKOzgfx7W6vfQU2OV55MKucKzrb1c5rWP88f iLrWG6ymTq5PPo2xnXklJRUelg== X-Google-Smtp-Source: ABdhPJwIISXtJrZkzuhqvDctQdOHdIuWAQJ82Q4tpI2F1MBWzCK3kw9HRfp0xthHKgfJd8jKK47x9g== X-Received: by 2002:a17:90a:fa13:: with SMTP id cm19mr454002pjb.80.1605639614097; Tue, 17 Nov 2020 11:00:14 -0800 (PST) Received: from xps15 (S0106889e681aac74.cg.shawcable.net. [68.147.0.187]) by smtp.gmail.com with ESMTPSA id u4sm3985502pjg.55.2020.11.17.11.00.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Nov 2020 11:00:13 -0800 (PST) Date: Tue, 17 Nov 2020 12:00:11 -0700 From: Mathieu Poirier To: Mike Leach Subject: Re: [RFC PATCH v3 3/9] coresight: config: Add configuration and feature generic functions Message-ID: <20201117190011.GA3949265@xps15> References: <20201030175655.30126-1-mike.leach@linaro.org> <20201030175655.30126-4-mike.leach@linaro.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20201030175655.30126-4-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201117_140018_695811_6A2A6F06 X-CRM114-Status: GOOD ( 37.66 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: yabinc@google.com, coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, suzuki.poulose@arm.com Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Fri, Oct 30, 2020 at 05:56:49PM +0000, Mike Leach wrote: > Adds a set of generic support functions that allow devices to set and save > features values on the device, and enable and disable configurations. > > Additional functions for other common operations including feature > reset. > > Signed-off-by: Mike Leach > --- > drivers/hwtracing/coresight/Makefile | 2 +- > .../hwtracing/coresight/coresight-config.c | 362 ++++++++++++++++++ > .../hwtracing/coresight/coresight-config.h | 14 + > .../hwtracing/coresight/coresight-syscfg.c | 4 + > 4 files changed, 381 insertions(+), 1 deletion(-) > create mode 100644 drivers/hwtracing/coresight/coresight-config.c > > diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile > index 4ce854c434b1..daad9f103a78 100644 > --- a/drivers/hwtracing/coresight/Makefile > +++ b/drivers/hwtracing/coresight/Makefile > @@ -4,7 +4,7 @@ > # > obj-$(CONFIG_CORESIGHT) += coresight.o > coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \ > - coresight-sysfs.o coresight-syscfg.o > + coresight-sysfs.o coresight-syscfg.o coresight-config.o > obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o > coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \ > coresight-tmc-etr.o > diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c > new file mode 100644 > index 000000000000..d911e0f083c1 > --- /dev/null > +++ b/drivers/hwtracing/coresight/coresight-config.c > @@ -0,0 +1,362 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright(C) 2020 Linaro Limited. All rights reserved. > + * Author: Mike Leach > + */ > + > +#include > +#include "coresight-config.h" > +#include "coresight-priv.h" > + > +/* > + * Write the value held in the register structure into the driver internal memory > + * location. > + */ > +static void cscfg_set_reg(struct cscfg_reg_csdev *reg) > +{ > + u32 *p_val32 = (u32 *)reg->drv_store; > + u32 tmp32; > + > + if (!(reg->value.flags & CS_CFG_REG_VAL_64BIT)) { > + if (reg->value.flags & CS_CFG_REG_VAL_MASK) { > + tmp32 = *p_val32; > + tmp32 &= ~reg->value.mask32; > + tmp32 |= reg->value.val32 & reg->value.mask32; > + *p_val32 = tmp32; > + } else > + *p_val32 = reg->value.val32; > + } else > + *((u64 *)reg->drv_store) = reg->value.val64; > +} > + > +/* > + * Read the driver value into the reg if this is marked as one we want to save. > + */ > +static void cscfg_save_reg(struct cscfg_reg_csdev *reg) > +{ > + if (!(reg->value.flags & CS_CFG_REG_VAL_SAVE)) > + return; > + if (reg->value.flags & CS_CFG_REG_VAL_64BIT) > + reg->value.val64 = *(u64 *)(reg->drv_store); > + else > + reg->value.val32 = *(u32 *)(reg->drv_store); > +} > + > +static inline void cscfg_init_reg_val(struct cscfg_reg_csdev *reg, > + const struct cscfg_regval *desc) > +{ > + reg->value.val64 = desc->val64; > +} > + > +static inline void cscfg_init_reg_flags(struct cscfg_reg_csdev *reg, > + const struct cscfg_regval *desc) > +{ > + reg->value.flags = desc->flags; > +} > + > +static void cscfg_init_reg_param(struct cscfg_parameter_csdev *param, > + struct cscfg_reg_csdev *reg) > +{ > + param->reg = reg; > + param->val64 = reg->value.flags & CS_CFG_REG_VAL_64BIT; > + > + if (param->val64) > + param->reg->value.val64 = param->current_value; > + else > + param->reg->value.val32 = (u32)param->current_value; > +} > + > +/* default set - will set values without resource checking */ > +static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat, const bool force_set) > +{ > + int i; > + > + spin_lock(feat->csdev_spinlock); > + if (feat->enabled || force_set) { > + for (i = 0; i < feat->nr_regs; i++) > + cscfg_set_reg(&feat->regs[i]); > + } > + dev_dbg(&feat->csdev->dev, "Feature %s: %s", feat->desc->name, > + feat->enabled || force_set ? "Set enabled" : "Skip disabled"); > + spin_unlock(feat->csdev_spinlock); > + return 0; > +} > + > +static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat, const bool force_save) > +{ > + int i; > + > + spin_lock(feat->csdev_spinlock); > + if (feat->enabled || force_save) { > + for (i = 0; i < feat->nr_regs; i++) > + cscfg_save_reg(&feat->regs[i]); > + } > + dev_dbg(&feat->csdev->dev, "Feature %s: %s", feat->desc->name, > + feat->enabled || force_save ? "Save disabled" : "Skip disabled"); > + spin_unlock(feat->csdev_spinlock); > +} > + > +/* default reset - restore default values, disable feature */ > +static void cscfg_reset_feat(struct cscfg_feature_csdev *feat) > +{ > + struct cscfg_reg_csdev *reg; > + struct cscfg_regval *reg_desc; > + struct cscfg_parameter_csdev *param; > + int i; > + > + spin_lock(feat->csdev_spinlock); > + feat->enabled = false; > + > + /* > + * set the default values for all parameters and regs from the > + * relevant static descriptors. > + */ > + for (i = 0; i < feat->nr_params; i++) > + feat->params[i].current_value = feat->desc->params[i].value; > + > + for (i = 0; i < feat->nr_regs; i++) { > + reg_desc = &feat->desc->regs[i]; > + reg = &feat->regs[i]; > + cscfg_init_reg_flags(reg, reg_desc); > + > + /* check if reg set from a parameter otherwise desc default */ > + if (reg_desc->flags & CS_CFG_REG_VAL_PARAM) { > + param = &feat->params[reg_desc->val32]; > + cscfg_init_reg_param(param, reg); > + } else > + cscfg_init_reg_val(reg, reg_desc); > + } > + spin_unlock(feat->csdev_spinlock); > +} > + > +void cscfg_set_def_ops(struct cscfg_feature_csdev *feat) > +{ > + feat->ops.set_on_enable = cscfg_set_on_enable; > + feat->ops.save_on_disable = cscfg_save_on_disable; > + feat->ops.reset = cscfg_reset_feat; > +} > + > +int cscfg_csdev_set_enabled_feats(struct coresight_device *csdev) > +{ > + struct cscfg_feature_csdev *feat; > + int err = 0; > + > + spin_lock(&csdev->cfg_lock); > + if (list_empty(&csdev->feat_list)) { > + spin_unlock(&csdev->cfg_lock); > + return 0; > + } > + > + list_for_each_entry(feat, &csdev->feat_list, node) { > + dev_dbg(&csdev->dev, "Found feature:%s", feat->desc->name); > + > + if (feat->ops.set_on_enable) { > + err = feat->ops.set_on_enable(feat, false); > + dev_dbg(&csdev->dev, "Feature %s: %s", > + feat->desc->name, err ? "Set failed" : "OK"); > + if (!err) > + break; > + } > + } > + spin_unlock(&csdev->cfg_lock); > + return err; > +} > +EXPORT_SYMBOL_GPL(cscfg_csdev_set_enabled_feats); > + > +void cscfg_csdev_save_enabled_feats(struct coresight_device *csdev) > +{ > + struct cscfg_feature_csdev *feat; > + > + spin_lock(&csdev->cfg_lock); > + if (list_empty(&csdev->feat_list)) { > + spin_unlock(&csdev->cfg_lock); > + return; > + } > + > + list_for_each_entry(feat, &csdev->feat_list, node) { > + if (feat->ops.save_on_disable) > + feat->ops.save_on_disable(feat, false); > + } > + spin_unlock(&csdev->cfg_lock); > +} > +EXPORT_SYMBOL_GPL(cscfg_csdev_save_enabled_feats); > + > +void cscfg_csdev_reset_feats(struct coresight_device *csdev) > +{ > + struct cscfg_feature_csdev *feat; > + > + spin_lock(&csdev->cfg_lock); > + if (list_empty(&csdev->feat_list)) { > + spin_unlock(&csdev->cfg_lock); > + return; > + } > + > + list_for_each_entry(feat, &csdev->feat_list, node) { > + if (feat->ops.reset) > + feat->ops.reset(feat); > + } > + spin_unlock(&csdev->cfg_lock); > +} > +EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats); > + > +static int cscfg_update_presets(struct cscfg_config_csdev *cfg, int preset) > +{ > + int i, j, line_offset = 0, val_idx = 0, max_idx; > + u64 val; > + struct cscfg_feature_csdev *feat; > + struct cscfg_parameter_csdev *param; > + const char *name; int i, j, line_offset = 0, val_idx = 0, max_idx; struct cscfg_parameter_csdev *param; struct cscfg_feature_csdev *feat; const char *name; u64 val; > + > + if (preset > cfg->desc->nr_presets) Extra space between if and () > + return -EINVAL; > + /* > + * Go through the array of features, assigning preset values to > + * feature parameters in the order they appear. > + * There should be precisely the same number of preset values as the > + * sum of number of parameters over all the features - but we will > + * ensure there is no overrun. > + */ > + line_offset = (preset-1) * cfg->desc->nr_total_params; If I understand correctly this computation won't work in situations where there is more than one feature with varying number of parameters. > + max_idx = cfg->desc->nr_total_params; > + for (i = 0; i < cfg->nr_feat; i++) { > + feat = cfg->feats[i]; > + if (feat->nr_params) { if (!feat->nr_params) continue; > + spin_lock(feat->csdev_spinlock); > + for (j = 0; j < feat->nr_params; j++) { > + param = &feat->params[j]; > + name = feat->desc->params[j].name; > + val = cfg->desc->presets[line_offset + val_idx++]; > + if (param->val64) { > + dev_dbg(&cfg->csdev->dev, > + "set param %s (%lld)", name, val); > + param->reg->value.val64 = val; > + } else { > + param->reg->value.val32 = (u32)val; > + dev_dbg(&cfg->csdev->dev, > + "set param %s (%d)", name, (u32)val); > + } > + if (val_idx >= max_idx) > + break; > + } > + spin_unlock(feat->csdev_spinlock); > + } > + > + /* don't overrun the preset array line */ > + if (val_idx >= max_idx) > + break; > + } > + return 0; > +} > + > +/* > + * if we are not using a preset, then need to update the feature params > + * with current values. > + */ > +static int cscfg_update_curr_params(struct cscfg_config_csdev *cfg) > +{ > + int i, j; > + struct cscfg_feature_csdev *feat; > + struct cscfg_parameter_csdev *param; > + const char *name; > + u64 val; > + > + for (i = 0; i < cfg->nr_feat; i++) { > + feat = cfg->feats[i]; > + if (feat->nr_params) { if (!feat->nr_params) continue; > + spin_lock(feat->csdev_spinlock); Please add a comment on why taking the spinlock is needed, i.e what kind of action would corrupt the data. > + for (j = 0; j < feat->nr_params; j++) { > + param = &feat->params[j]; > + name = feat->desc->params[j].name; > + val = param->current_value; > + if (param->val64) { > + dev_dbg(&cfg->csdev->dev, > + "set param %s (%lld)", name, val); > + param->reg->value.val64 = val; > + } else { > + param->reg->value.val32 = (u32)val; > + dev_dbg(&cfg->csdev->dev, > + "set param %s (%d)", name, (u32)val); > + } > + } > + spin_unlock(feat->csdev_spinlock); > + } > + } > + return 0; > +} > + > +static int cscfg_prog_config(struct cscfg_config_csdev *cfg, bool enable) > +{ > + int i, err = 0; > + struct cscfg_feature_csdev *feat; > + struct coresight_device *csdev; > + > + for (i = 0; i < cfg->nr_feat; i++) { > + feat = cfg->feats[i]; > + csdev = feat->csdev; > + dev_dbg(&csdev->dev, "cfg %s; %s feature:%s", cfg->desc->name, > + enable ? "enable" : "disable", feat->desc->name); > + > + if (enable) { > + if (feat->ops.set_on_enable) > + err = feat->ops.set_on_enable(feat, true); > + } else { > + if (feat->ops.save_on_disable) > + feat->ops.save_on_disable(feat, true); > + } > + if (err) > + break; > + } > + return err; > +} > + > +/** > + * Enable configuration for the device. > + * Match the config id and optionally set preset values for parameters. > + * > + * @csdev: coresight device to set config on. > + * @cfg_id: hash id of configuration. > + * @preset: preset values to use - 0 for default. > + */ > +int cscfg_csdev_enable_config(struct coresight_device *csdev, > + unsigned long cfg_id, > + int preset) Please avoid stacking when possible. Here @preset fits on the previous line. The same applies for the function declaration in coresigt-config.h I will continue with this patch tomorrow. Thanks, Mathieu > +{ > + struct cscfg_config_csdev *cfg; > + int err = 0; > + > + dev_dbg(&csdev->dev, "Check for config %lx, preset %d", cfg_id, preset); > + > + spin_lock(&csdev->cfg_lock); > + list_for_each_entry(cfg, &csdev->syscfg_list, node) { > + dev_dbg(&csdev->dev, "checking %s", cfg->desc->name); > + if (cfg->id_hash == cfg_id) { > + if (preset) > + err = cscfg_update_presets(cfg, preset); > + else > + err = cscfg_update_curr_params(cfg); > + if (!err) > + err = cscfg_prog_config(cfg, true); > + if (!err) > + cfg->enabled = true; > + break; > + } > + } > + spin_unlock(&csdev->cfg_lock); > + return err; > +} > +EXPORT_SYMBOL_GPL(cscfg_csdev_enable_config); > + > +void cscfg_csdev_disable_config(struct coresight_device *csdev) > +{ > + struct cscfg_config_csdev *cfg; > + > + spin_lock(&csdev->cfg_lock); > + list_for_each_entry(cfg, &csdev->syscfg_list, node) { > + if (cfg->enabled) { > + cscfg_prog_config(cfg, false); > + cfg->enabled = false; > + } > + } > + spin_unlock(&csdev->cfg_lock); > +} > +EXPORT_SYMBOL_GPL(cscfg_csdev_disable_config); > diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h > index 8fd7ff991ced..a3d374ebb70f 100644 > --- a/drivers/hwtracing/coresight/coresight-config.h > +++ b/drivers/hwtracing/coresight/coresight-config.h > @@ -287,4 +287,18 @@ struct cscfg_csdev_feat_ops { > struct cscfg_feature_csdev *feat); > }; > > +/* coresight config API functions */ > + > +/* helper functions for feature manipulation */ > +void cscfg_set_def_ops(struct cscfg_feature_csdev *feat); > + > +/* enable / disable features or configs on a device */ > +int cscfg_csdev_set_enabled_feats(struct coresight_device *csdev); > +void cscfg_csdev_save_enabled_feats(struct coresight_device *csdev); > +void cscfg_csdev_reset_feats(struct coresight_device *csdev); > +int cscfg_csdev_enable_config(struct coresight_device *csdev, > + unsigned long cfg_id, > + int preset); > +void cscfg_csdev_disable_config(struct coresight_device *csdev); > + > #endif /* _CORESIGHT_CORESIGHT_CONFIG_H */ > diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c > index 53bc1d551171..98ee78e3412a 100644 > --- a/drivers/hwtracing/coresight/coresight-syscfg.c > +++ b/drivers/hwtracing/coresight/coresight-syscfg.c > @@ -166,6 +166,7 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc > feat->csdev = csdev; > for (i = 0; i < feat->nr_params; i++) > feat->params[i].feat = feat; > + cscfg_set_def_ops(feat); > > return feat; > } > @@ -195,6 +196,9 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev, > list_add(&feat_csdev->node, &csdev->feat_list); > spin_unlock(&csdev->cfg_lock); > > + /* force load of default parameter values into registers */ > + feat_csdev->ops.reset(feat_csdev); > + > return 0; > } > > -- > 2.17.1 > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel