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=-15.4 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=unavailable 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 770FEC4338F for ; Wed, 4 Aug 2021 17:33:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 57B7A60F35 for ; Wed, 4 Aug 2021 17:33:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237816AbhHDRdy (ORCPT ); Wed, 4 Aug 2021 13:33:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230231AbhHDRdx (ORCPT ); Wed, 4 Aug 2021 13:33:53 -0400 Received: from mail-oi1-x236.google.com (mail-oi1-x236.google.com [IPv6:2607:f8b0:4864:20::236]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16FCAC0613D5; Wed, 4 Aug 2021 10:33:40 -0700 (PDT) Received: by mail-oi1-x236.google.com with SMTP id 21so3707277oin.8; Wed, 04 Aug 2021 10:33:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:cc:references:from:subject:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=boQtfMOkZY9hdjBQivOx+8/FvLGtf9v8PYVfUON6vUQ=; b=GvZ1SBNr2DcgJSQTR+uzl4H3+WJD0SNH7HsHspqb1BuouaZcwWSbrOHZ+5+HQweU3Q SMGyUIijwEnz1zocHU2f3X51iEnbnHYb6QNZS6+L/bmhDL0udvq2jZEDzJH7QCPZfg6i TSj6sC7jX/J/xEmLLGkIcmArcjjT5iYMeGXdZ/mc0ExqIXdG//pYUjIRR4bvfgwI0qHT T/d6z23Qsjstwvy5CdR74maXQ0BkfvtzjvpFPE2vVilXNhN3ERNBCO9oxlBk/9Cx8lR8 ilnua+8hAP85QWI+qlaF3Mk4b7tWWscPH5SgzvMC6B8M/2AuGqyrdFUJrgrxe+Nzu0WV G/vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:cc:references:from:subject:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=boQtfMOkZY9hdjBQivOx+8/FvLGtf9v8PYVfUON6vUQ=; b=uUwhrf86WznfE6V/d0WgXiaZJY89boIkbKjMXgre9Z69gZ/5RtRj4uqiFCtm45XKaz ZO7rRsEDhUWng/QXB9WtRX3glmrTW6F4zVyiC+G2aZTeKXz4+RQVpIq00k8+mg0U75gj EVxhOAIp7oQeRLbNP049MKZ9ytov5wZYMj5GA/Sh9Q4a5pd2lNObTjRolsjb20gWzgY7 +6uS7khRxAL/8b5kIMiVy4AnfS08NCo2+75TNT+eu3PPeSCPqD5b1zlKR7ojZYY8om7I ISwcuPtDypMs7d5FDvjgDD1/q5xkIJjq0kuqHdh+sFKJI3DO9KVYSbOfP4id/97AAYGH RaXw== X-Gm-Message-State: AOAM533ahJ8AeZRKijwFMUTW7tllvlQzBkgFKkf4i5SSgtwdiRxa/pGi eclW42LgfGhucQR5hl4FIGI= X-Google-Smtp-Source: ABdhPJzPmtomHiFQRHu0Frnwj19U5U9ieIGCtt/9GmfJnQQrdsF77jcXTd2yPxviTb/mGRTxwKZmwA== X-Received: by 2002:aca:39c6:: with SMTP id g189mr2259435oia.47.1628098419381; Wed, 04 Aug 2021 10:33:39 -0700 (PDT) Received: from server.roeck-us.net ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id c21sm560538oiw.16.2021.08.04.10.33.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 04 Aug 2021 10:33:38 -0700 (PDT) Sender: Guenter Roeck To: "Winiarska, Iwona" Cc: "corbet@lwn.net" , "jae.hyun.yoo@linux.intel.com" , "Williams, Dan J" , "linux-hwmon@vger.kernel.org" , "andrew@aj.id.au" , "Luck, Tony" , "Lutomirski, Andy" , "andriy.shevchenko@linux.intel.com" , "mchehab@kernel.org" , "jdelvare@suse.com" , "linux-kernel@vger.kernel.org" , "olof@lixom.net" , "mingo@redhat.com" , "rdunlap@infradead.org" , "devicetree@vger.kernel.org" , "tglx@linutronix.de" , "linux-aspeed@lists.ozlabs.org" , "arnd@arndb.de" , "linux-doc@vger.kernel.org" , "yazen.ghannam@amd.com" , "zweiss@equinix.com" , "robh+dt@kernel.org" , "openbmc@lists.ozlabs.org" , "gregkh@linuxfoundation.org" , "joel@jms.id.au" , "d.mueller@elsoft.ch" , "linux-arm-kernel@lists.infradead.org" , "pierre-louis.bossart@linux.intel.com" , "x86@kernel.org" , "bp@alien8.de" References: <20210803113134.2262882-1-iwona.winiarska@intel.com> <20210803113134.2262882-14-iwona.winiarska@intel.com> <20210803153937.GA337938@roeck-us.net> From: Guenter Roeck Subject: Re: [PATCH v2 13/15] hwmon: peci: Add dimmtemp driver Message-ID: Date: Wed, 4 Aug 2021 10:33:35 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org On 8/4/21 3:46 AM, Winiarska, Iwona wrote: > On Tue, 2021-08-03 at 08:39 -0700, Guenter Roeck wrote: >> On Tue, Aug 03, 2021 at 01:31:32PM +0200, Iwona Winiarska wrote: >>> Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that >>> are accessible via the processor PECI interface. >>> >>> The main use case for the driver (and PECI interface) is out-of-band >>> management, where we're able to obtain thermal readings from an external >>> entity connected with PECI, e.g. BMC on server platforms. >>> >>> Co-developed-by: Jae Hyun Yoo >>> Signed-off-by: Jae Hyun Yoo >>> Signed-off-by: Iwona Winiarska >>> Reviewed-by: Pierre-Louis Bossart >>> --- >>> Note that the timeout was completely removed - we're going to probe >>> for detected DIMMs every 5 seconds until we reach "stable" state of >>> either getting correct DIMM data or getting all -EINVAL (which >>> suggest that the CPU doesn't have any DIMMs). >>> >>>  drivers/hwmon/peci/Kconfig    |  13 + >>>  drivers/hwmon/peci/Makefile   |   2 + >>>  drivers/hwmon/peci/dimmtemp.c | 614 ++++++++++++++++++++++++++++++++++ >>>  3 files changed, 629 insertions(+) >>>  create mode 100644 drivers/hwmon/peci/dimmtemp.c >>> >>> diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig >>> index e10eed68d70a..9d32a57badfe 100644 >>> --- a/drivers/hwmon/peci/Kconfig >>> +++ b/drivers/hwmon/peci/Kconfig >>> @@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP >>>           This driver can also be built as a module. If so, the module >>>           will be called peci-cputemp. >>> >>> +config SENSORS_PECI_DIMMTEMP >>> +       tristate "PECI DIMM temperature monitoring client" >>> +       depends on PECI >>> +       select SENSORS_PECI >>> +       select PECI_CPU >>> +       help >>> +         If you say yes here you get support for the generic Intel PECI >>> hwmon >>> +         driver which provides Temperature Sensor on DIMM readings that are >>> +         accessible via the processor PECI interface. >>> + >>> +         This driver can also be built as a module. If so, the module >>> +         will be called peci-dimmtemp. >>> + >>>  config SENSORS_PECI >>>         tristate >>> diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile >>> index e8a0ada5ab1f..191cfa0227f3 100644 >>> --- a/drivers/hwmon/peci/Makefile >>> +++ b/drivers/hwmon/peci/Makefile >>> @@ -1,5 +1,7 @@ >>>  # SPDX-License-Identifier: GPL-2.0-only >>> >>>  peci-cputemp-y := cputemp.o >>> +peci-dimmtemp-y := dimmtemp.o >>> >>>  obj-$(CONFIG_SENSORS_PECI_CPUTEMP)     += peci-cputemp.o >>> +obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)    += peci-dimmtemp.o >>> diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c >>> new file mode 100644 >>> index 000000000000..6264c29bb6c0 >>> --- /dev/null >>> +++ b/drivers/hwmon/peci/dimmtemp.c >>> @@ -0,0 +1,614 @@ >>> +// SPDX-License-Identifier: GPL-2.0-only >>> +// Copyright (c) 2018-2021 Intel Corporation >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#include "common.h" >>> + >>> +#define DIMM_MASK_CHECK_DELAY_JIFFIES  msecs_to_jiffies(5000) >>> + >>> +/* Max number of channel ranks and DIMM index per channel */ >>> +#define CHAN_RANK_MAX_ON_HSX   8 >>> +#define DIMM_IDX_MAX_ON_HSX    3 >>> +#define CHAN_RANK_MAX_ON_BDX   4 >>> +#define DIMM_IDX_MAX_ON_BDX    3 >>> +#define CHAN_RANK_MAX_ON_BDXD  2 >>> +#define DIMM_IDX_MAX_ON_BDXD   2 >>> +#define CHAN_RANK_MAX_ON_SKX   6 >>> +#define DIMM_IDX_MAX_ON_SKX    2 >>> +#define CHAN_RANK_MAX_ON_ICX   8 >>> +#define DIMM_IDX_MAX_ON_ICX    2 >>> +#define CHAN_RANK_MAX_ON_ICXD  4 >>> +#define DIMM_IDX_MAX_ON_ICXD   2 >>> + >>> +#define CHAN_RANK_MAX          CHAN_RANK_MAX_ON_HSX >>> +#define DIMM_IDX_MAX           DIMM_IDX_MAX_ON_HSX >>> +#define DIMM_NUMS_MAX          (CHAN_RANK_MAX * DIMM_IDX_MAX) >>> + >>> +#define CPU_SEG_MASK           GENMASK(23, 16) >>> +#define GET_CPU_SEG(x)         (((x) & CPU_SEG_MASK) >> 16) >>> +#define CPU_BUS_MASK           GENMASK(7, 0) >>> +#define GET_CPU_BUS(x)         ((x) & CPU_BUS_MASK) >>> + >>> +#define DIMM_TEMP_MAX          GENMASK(15, 8) >>> +#define DIMM_TEMP_CRIT         GENMASK(23, 16) >>> +#define GET_TEMP_MAX(x)                (((x) & DIMM_TEMP_MAX) >> 8) >>> +#define GET_TEMP_CRIT(x)       (((x) & DIMM_TEMP_CRIT) >> 16) >>> + >>> +struct peci_dimmtemp; >>> + >>> +struct dimm_info { >>> +       int chan_rank_max; >>> +       int dimm_idx_max; >>> +       u8 min_peci_revision; >>> +       int (*read_thresholds)(struct peci_dimmtemp *priv, int dimm_order, >>> +                              int chan_rank, u32 *data); >>> +}; >>> + >>> +struct peci_dimm_thresholds { >>> +       long temp_max; >>> +       long temp_crit; >>> +       struct peci_sensor_state state; >>> +}; >>> + >>> +enum peci_dimm_threshold_type { >>> +       temp_max_type, >>> +       temp_crit_type, >>> +}; >>> + >>> +struct peci_dimmtemp { >>> +       struct peci_device *peci_dev; >>> +       struct device *dev; >>> +       const char *name; >>> +       const struct dimm_info *gen_info; >>> +       struct delayed_work detect_work; >>> +       struct { >>> +               struct peci_sensor_data temp; >>> +               struct peci_dimm_thresholds thresholds; >>> +       } dimm[DIMM_NUMS_MAX]; >>> +       char **dimmtemp_label; >>> +       DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX); >>> +}; >>> + >>> +static u8 __dimm_temp(u32 reg, int dimm_order) >>> +{ >>> +       return (reg >> (dimm_order * 8)) & 0xff; >>> +} >>> + >>> +static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long >>> *val) >>> +{ >>> +       int dimm_order = dimm_no % priv->gen_info->dimm_idx_max; >>> +       int chan_rank = dimm_no / priv->gen_info->dimm_idx_max; >>> +       u32 data; >>> +       int ret; >> >>         int ret = 0; >> >>> + >>> +       mutex_lock(&priv->dimm[dimm_no].temp.state.lock); >>> +       if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state)) >>> +               goto skip_update; >>> + >>> +       ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, >>> chan_rank, &data); >>> +       if (ret) { >>> +               mutex_unlock(&priv->dimm[dimm_no].temp.state.lock); >>> +               return ret; >>> +       } >> >>         if (ret) >>                 goto unlock; >> >>> + >>> +       priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) * >>> MILLIDEGREE_PER_DEGREE; >>> + >>> +       peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state); >>> + >>> +skip_update: >>> +       *val = priv->dimm[dimm_no].temp.value; >> >> unlock: >>> +       mutex_unlock(&priv->dimm[dimm_no].temp.state.lock); >>> +       return 0; >> >>         return ret; > > Ack. > >> >>> +} >>> + >>> +static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no) >>> +{ >>> +       int dimm_order = dimm_no % priv->gen_info->dimm_idx_max; >>> +       int chan_rank = dimm_no / priv->gen_info->dimm_idx_max; >>> +       u32 data; >>> +       int ret; >>> + >>> +       if (!peci_sensor_need_update(&priv->dimm[dimm_no].thresholds.state)) >>> +               return 0; >>> + >>> +       ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank, >>> &data); >>> +       if (ret == -ENODATA) /* Use default or previous value */ >>> +               return 0; >>> +       if (ret) >>> +               return ret; >>> + >>> +       priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) * >>> MILLIDEGREE_PER_DEGREE; >>> +       priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) * >>> MILLIDEGREE_PER_DEGREE; >>> + >>> +       peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state); >>> + >>> +       return 0; >>> +} >>> + >>> +static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum >>> peci_dimm_threshold_type type, >>> +                              int dimm_no, long *val) >>> +{ >>> +       int ret; >>> + >>> +       mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock); >>> +       ret = update_thresholds(priv, dimm_no); >>> +       if (ret) >>> +               goto unlock; >>> + >>> +       switch (type) { >>> +       case temp_max_type: >>> +               *val = priv->dimm[dimm_no].thresholds.temp_max; >>> +               break; >>> +       case temp_crit_type: >>> +               *val = priv->dimm[dimm_no].thresholds.temp_crit; >>> +               break; >>> +       default: >>> +               ret = -EOPNOTSUPP; >>> +               break; >>> +       } >>> +unlock: >>> +       mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock); >>> + >>> +       return ret; >>> +} >>> + >>> +static int dimmtemp_read_string(struct device *dev, >>> +                               enum hwmon_sensor_types type, >>> +                               u32 attr, int channel, const char **str) >>> +{ >>> +       struct peci_dimmtemp *priv = dev_get_drvdata(dev); >>> + >>> +       if (attr != hwmon_temp_label) >>> +               return -EOPNOTSUPP; >>> + >>> +       *str = (const char *)priv->dimmtemp_label[channel]; >>> + >>> +       return 0; >>> +} >>> + >>> +static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type, >>> +                        u32 attr, int channel, long *val) >>> +{ >>> +       struct peci_dimmtemp *priv = dev_get_drvdata(dev); >>> + >>> +       switch (attr) { >>> +       case hwmon_temp_input: >>> +               return get_dimm_temp(priv, channel, val); >>> +       case hwmon_temp_max: >>> +               return get_dimm_thresholds(priv, temp_max_type, channel, >>> val); >>> +       case hwmon_temp_crit: >>> +               return get_dimm_thresholds(priv, temp_crit_type, channel, >>> val); >>> +       default: >>> +               break; >>> +       } >>> + >>> +       return -EOPNOTSUPP; >>> +} >>> + >>> +static umode_t dimmtemp_is_visible(const void *data, enum >>> hwmon_sensor_types type, >>> +                                  u32 attr, int channel) >>> +{ >>> +       const struct peci_dimmtemp *priv = data; >>> + >>> +       if (test_bit(channel, priv->dimm_mask)) >>> +               return 0444; >>> + >>> +       return 0; >>> +} >>> + >>> +static const struct hwmon_ops peci_dimmtemp_ops = { >>> +       .is_visible = dimmtemp_is_visible, >>> +       .read_string = dimmtemp_read_string, >>> +       .read = dimmtemp_read, >>> +}; >>> + >>> +static int check_populated_dimms(struct peci_dimmtemp *priv) >>> +{ >>> +       int chan_rank_max = priv->gen_info->chan_rank_max; >>> +       int dimm_idx_max = priv->gen_info->dimm_idx_max; >>> +       u32 chan_rank_empty = 0; >>> +       u64 dimm_mask = 0; >>> +       int chan_rank, dimm_idx, ret; >>> +       u32 pcs; >>> + >>> +       BUILD_BUG_ON(CHAN_RANK_MAX > 32); >>> +       BUILD_BUG_ON(DIMM_NUMS_MAX > 64); >> >> I don't immediately see the value of those build bugs. What happens if >> CHAN_RANK_MAX > 32 or DIMM_NUMS_MAX > 64 ? Where do those limits come >> from ? > > Supported HW doesn't come near the limit for now - it's just an "artificial" > limit imposed by variables we're using (u64 for dimm_mask and u32 for > chan_rank_empty). > Please use a value derived from the size of those variables for the check to clarify and explain the constraints. Thanks, Guenter 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=-15.2 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=unavailable 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 9745EC4338F for ; Wed, 4 Aug 2021 23:03:14 +0000 (UTC) Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (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 91CF060BD3 for ; Wed, 4 Aug 2021 23:03:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 91CF060BD3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=roeck-us.net Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.ozlabs.org Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4Gg6jD2Gnyz3cTn for ; Thu, 5 Aug 2021 09:03:12 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=GvZ1SBNr; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::22d; helo=mail-oi1-x22d.google.com; envelope-from=groeck7@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=GvZ1SBNr; dkim-atps=neutral Received: from mail-oi1-x22d.google.com (mail-oi1-x22d.google.com [IPv6:2607:f8b0:4864:20::22d]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4GfzP30TR3z3bmB; Thu, 5 Aug 2021 03:33:42 +1000 (AEST) Received: by mail-oi1-x22d.google.com with SMTP id n16so3744473oij.2; Wed, 04 Aug 2021 10:33:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:cc:references:from:subject:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=boQtfMOkZY9hdjBQivOx+8/FvLGtf9v8PYVfUON6vUQ=; b=GvZ1SBNr2DcgJSQTR+uzl4H3+WJD0SNH7HsHspqb1BuouaZcwWSbrOHZ+5+HQweU3Q SMGyUIijwEnz1zocHU2f3X51iEnbnHYb6QNZS6+L/bmhDL0udvq2jZEDzJH7QCPZfg6i TSj6sC7jX/J/xEmLLGkIcmArcjjT5iYMeGXdZ/mc0ExqIXdG//pYUjIRR4bvfgwI0qHT T/d6z23Qsjstwvy5CdR74maXQ0BkfvtzjvpFPE2vVilXNhN3ERNBCO9oxlBk/9Cx8lR8 ilnua+8hAP85QWI+qlaF3Mk4b7tWWscPH5SgzvMC6B8M/2AuGqyrdFUJrgrxe+Nzu0WV G/vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:cc:references:from:subject:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=boQtfMOkZY9hdjBQivOx+8/FvLGtf9v8PYVfUON6vUQ=; b=RVvqTScJ4T+WkJk/+HNlzXjJEtxBC2u91dScxEL5fHPZO7orouqXEMbxjU/TKgjK3q 9e+9+aVXwODZZEouI7yVNWAIAFwF/ejnudK0qUkqovrtDHsHch6QjUWxBBM0zaok/Mw3 BgvgK+av4p7naN8S/skli5DDk8yPQJ9p1wM0d4z+PdS6DEgm/DgkwWAtfeNsK1oCaciZ J73Wq83q6pdpBeZS+yfUZZd/8V0VvrHvDDysB5pcssyPSXVCYoLDHBjjCrrz0WMitWZn zpLHxpk0h78e5sCqFlHzQlytcnK+LWxSoQczzunjn3IZ2/8Lxomy5v5dVsF/mcpvHEHu tYsg== X-Gm-Message-State: AOAM531SlhBxzxsaOjfcmMI6kWiQlv3GxzqNjaNFGTtGFG1QfLT/j3ou Nwwj2K0nOzsvguo3E+fNKxk= X-Google-Smtp-Source: ABdhPJzPmtomHiFQRHu0Frnwj19U5U9ieIGCtt/9GmfJnQQrdsF77jcXTd2yPxviTb/mGRTxwKZmwA== X-Received: by 2002:aca:39c6:: with SMTP id g189mr2259435oia.47.1628098419381; Wed, 04 Aug 2021 10:33:39 -0700 (PDT) Received: from server.roeck-us.net ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id c21sm560538oiw.16.2021.08.04.10.33.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 04 Aug 2021 10:33:38 -0700 (PDT) To: "Winiarska, Iwona" References: <20210803113134.2262882-1-iwona.winiarska@intel.com> <20210803113134.2262882-14-iwona.winiarska@intel.com> <20210803153937.GA337938@roeck-us.net> From: Guenter Roeck Subject: Re: [PATCH v2 13/15] hwmon: peci: Add dimmtemp driver Message-ID: Date: Wed, 4 Aug 2021 10:33:35 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-Mailman-Approved-At: Thu, 05 Aug 2021 09:01:42 +1000 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "linux-aspeed@lists.ozlabs.org" , "linux-doc@vger.kernel.org" , "Williams, Dan J" , "zweiss@equinix.com" , "jae.hyun.yoo@linux.intel.com" , "andriy.shevchenko@linux.intel.com" , "corbet@lwn.net" , "openbmc@lists.ozlabs.org" , "x86@kernel.org" , "pierre-louis.bossart@linux.intel.com" , "mingo@redhat.com" , "devicetree@vger.kernel.org" , "jdelvare@suse.com" , "arnd@arndb.de" , "robh+dt@kernel.org" , "bp@alien8.de" , "Lutomirski, Andy" , "tglx@linutronix.de" , "mchehab@kernel.org" , "linux-arm-kernel@lists.infradead.org" , "linux-hwmon@vger.kernel.org" , "Luck, Tony" , "andrew@aj.id.au" , "gregkh@linuxfoundation.org" , "rdunlap@infradead.org" , "linux-kernel@vger.kernel.org" , "yazen.ghannam@amd.com" , "olof@lixom.net" Errors-To: openbmc-bounces+openbmc=archiver.kernel.org@lists.ozlabs.org Sender: "openbmc" On 8/4/21 3:46 AM, Winiarska, Iwona wrote: > On Tue, 2021-08-03 at 08:39 -0700, Guenter Roeck wrote: >> On Tue, Aug 03, 2021 at 01:31:32PM +0200, Iwona Winiarska wrote: >>> Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that >>> are accessible via the processor PECI interface. >>> >>> The main use case for the driver (and PECI interface) is out-of-band >>> management, where we're able to obtain thermal readings from an external >>> entity connected with PECI, e.g. BMC on server platforms. >>> >>> Co-developed-by: Jae Hyun Yoo >>> Signed-off-by: Jae Hyun Yoo >>> Signed-off-by: Iwona Winiarska >>> Reviewed-by: Pierre-Louis Bossart >>> --- >>> Note that the timeout was completely removed - we're going to probe >>> for detected DIMMs every 5 seconds until we reach "stable" state of >>> either getting correct DIMM data or getting all -EINVAL (which >>> suggest that the CPU doesn't have any DIMMs). >>> >>>  drivers/hwmon/peci/Kconfig    |  13 + >>>  drivers/hwmon/peci/Makefile   |   2 + >>>  drivers/hwmon/peci/dimmtemp.c | 614 ++++++++++++++++++++++++++++++++++ >>>  3 files changed, 629 insertions(+) >>>  create mode 100644 drivers/hwmon/peci/dimmtemp.c >>> >>> diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig >>> index e10eed68d70a..9d32a57badfe 100644 >>> --- a/drivers/hwmon/peci/Kconfig >>> +++ b/drivers/hwmon/peci/Kconfig >>> @@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP >>>           This driver can also be built as a module. If so, the module >>>           will be called peci-cputemp. >>> >>> +config SENSORS_PECI_DIMMTEMP >>> +       tristate "PECI DIMM temperature monitoring client" >>> +       depends on PECI >>> +       select SENSORS_PECI >>> +       select PECI_CPU >>> +       help >>> +         If you say yes here you get support for the generic Intel PECI >>> hwmon >>> +         driver which provides Temperature Sensor on DIMM readings that are >>> +         accessible via the processor PECI interface. >>> + >>> +         This driver can also be built as a module. If so, the module >>> +         will be called peci-dimmtemp. >>> + >>>  config SENSORS_PECI >>>         tristate >>> diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile >>> index e8a0ada5ab1f..191cfa0227f3 100644 >>> --- a/drivers/hwmon/peci/Makefile >>> +++ b/drivers/hwmon/peci/Makefile >>> @@ -1,5 +1,7 @@ >>>  # SPDX-License-Identifier: GPL-2.0-only >>> >>>  peci-cputemp-y := cputemp.o >>> +peci-dimmtemp-y := dimmtemp.o >>> >>>  obj-$(CONFIG_SENSORS_PECI_CPUTEMP)     += peci-cputemp.o >>> +obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)    += peci-dimmtemp.o >>> diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c >>> new file mode 100644 >>> index 000000000000..6264c29bb6c0 >>> --- /dev/null >>> +++ b/drivers/hwmon/peci/dimmtemp.c >>> @@ -0,0 +1,614 @@ >>> +// SPDX-License-Identifier: GPL-2.0-only >>> +// Copyright (c) 2018-2021 Intel Corporation >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#include "common.h" >>> + >>> +#define DIMM_MASK_CHECK_DELAY_JIFFIES  msecs_to_jiffies(5000) >>> + >>> +/* Max number of channel ranks and DIMM index per channel */ >>> +#define CHAN_RANK_MAX_ON_HSX   8 >>> +#define DIMM_IDX_MAX_ON_HSX    3 >>> +#define CHAN_RANK_MAX_ON_BDX   4 >>> +#define DIMM_IDX_MAX_ON_BDX    3 >>> +#define CHAN_RANK_MAX_ON_BDXD  2 >>> +#define DIMM_IDX_MAX_ON_BDXD   2 >>> +#define CHAN_RANK_MAX_ON_SKX   6 >>> +#define DIMM_IDX_MAX_ON_SKX    2 >>> +#define CHAN_RANK_MAX_ON_ICX   8 >>> +#define DIMM_IDX_MAX_ON_ICX    2 >>> +#define CHAN_RANK_MAX_ON_ICXD  4 >>> +#define DIMM_IDX_MAX_ON_ICXD   2 >>> + >>> +#define CHAN_RANK_MAX          CHAN_RANK_MAX_ON_HSX >>> +#define DIMM_IDX_MAX           DIMM_IDX_MAX_ON_HSX >>> +#define DIMM_NUMS_MAX          (CHAN_RANK_MAX * DIMM_IDX_MAX) >>> + >>> +#define CPU_SEG_MASK           GENMASK(23, 16) >>> +#define GET_CPU_SEG(x)         (((x) & CPU_SEG_MASK) >> 16) >>> +#define CPU_BUS_MASK           GENMASK(7, 0) >>> +#define GET_CPU_BUS(x)         ((x) & CPU_BUS_MASK) >>> + >>> +#define DIMM_TEMP_MAX          GENMASK(15, 8) >>> +#define DIMM_TEMP_CRIT         GENMASK(23, 16) >>> +#define GET_TEMP_MAX(x)                (((x) & DIMM_TEMP_MAX) >> 8) >>> +#define GET_TEMP_CRIT(x)       (((x) & DIMM_TEMP_CRIT) >> 16) >>> + >>> +struct peci_dimmtemp; >>> + >>> +struct dimm_info { >>> +       int chan_rank_max; >>> +       int dimm_idx_max; >>> +       u8 min_peci_revision; >>> +       int (*read_thresholds)(struct peci_dimmtemp *priv, int dimm_order, >>> +                              int chan_rank, u32 *data); >>> +}; >>> + >>> +struct peci_dimm_thresholds { >>> +       long temp_max; >>> +       long temp_crit; >>> +       struct peci_sensor_state state; >>> +}; >>> + >>> +enum peci_dimm_threshold_type { >>> +       temp_max_type, >>> +       temp_crit_type, >>> +}; >>> + >>> +struct peci_dimmtemp { >>> +       struct peci_device *peci_dev; >>> +       struct device *dev; >>> +       const char *name; >>> +       const struct dimm_info *gen_info; >>> +       struct delayed_work detect_work; >>> +       struct { >>> +               struct peci_sensor_data temp; >>> +               struct peci_dimm_thresholds thresholds; >>> +       } dimm[DIMM_NUMS_MAX]; >>> +       char **dimmtemp_label; >>> +       DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX); >>> +}; >>> + >>> +static u8 __dimm_temp(u32 reg, int dimm_order) >>> +{ >>> +       return (reg >> (dimm_order * 8)) & 0xff; >>> +} >>> + >>> +static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long >>> *val) >>> +{ >>> +       int dimm_order = dimm_no % priv->gen_info->dimm_idx_max; >>> +       int chan_rank = dimm_no / priv->gen_info->dimm_idx_max; >>> +       u32 data; >>> +       int ret; >> >>         int ret = 0; >> >>> + >>> +       mutex_lock(&priv->dimm[dimm_no].temp.state.lock); >>> +       if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state)) >>> +               goto skip_update; >>> + >>> +       ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, >>> chan_rank, &data); >>> +       if (ret) { >>> +               mutex_unlock(&priv->dimm[dimm_no].temp.state.lock); >>> +               return ret; >>> +       } >> >>         if (ret) >>                 goto unlock; >> >>> + >>> +       priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) * >>> MILLIDEGREE_PER_DEGREE; >>> + >>> +       peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state); >>> + >>> +skip_update: >>> +       *val = priv->dimm[dimm_no].temp.value; >> >> unlock: >>> +       mutex_unlock(&priv->dimm[dimm_no].temp.state.lock); >>> +       return 0; >> >>         return ret; > > Ack. > >> >>> +} >>> + >>> +static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no) >>> +{ >>> +       int dimm_order = dimm_no % priv->gen_info->dimm_idx_max; >>> +       int chan_rank = dimm_no / priv->gen_info->dimm_idx_max; >>> +       u32 data; >>> +       int ret; >>> + >>> +       if (!peci_sensor_need_update(&priv->dimm[dimm_no].thresholds.state)) >>> +               return 0; >>> + >>> +       ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank, >>> &data); >>> +       if (ret == -ENODATA) /* Use default or previous value */ >>> +               return 0; >>> +       if (ret) >>> +               return ret; >>> + >>> +       priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) * >>> MILLIDEGREE_PER_DEGREE; >>> +       priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) * >>> MILLIDEGREE_PER_DEGREE; >>> + >>> +       peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state); >>> + >>> +       return 0; >>> +} >>> + >>> +static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum >>> peci_dimm_threshold_type type, >>> +                              int dimm_no, long *val) >>> +{ >>> +       int ret; >>> + >>> +       mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock); >>> +       ret = update_thresholds(priv, dimm_no); >>> +       if (ret) >>> +               goto unlock; >>> + >>> +       switch (type) { >>> +       case temp_max_type: >>> +               *val = priv->dimm[dimm_no].thresholds.temp_max; >>> +               break; >>> +       case temp_crit_type: >>> +               *val = priv->dimm[dimm_no].thresholds.temp_crit; >>> +               break; >>> +       default: >>> +               ret = -EOPNOTSUPP; >>> +               break; >>> +       } >>> +unlock: >>> +       mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock); >>> + >>> +       return ret; >>> +} >>> + >>> +static int dimmtemp_read_string(struct device *dev, >>> +                               enum hwmon_sensor_types type, >>> +                               u32 attr, int channel, const char **str) >>> +{ >>> +       struct peci_dimmtemp *priv = dev_get_drvdata(dev); >>> + >>> +       if (attr != hwmon_temp_label) >>> +               return -EOPNOTSUPP; >>> + >>> +       *str = (const char *)priv->dimmtemp_label[channel]; >>> + >>> +       return 0; >>> +} >>> + >>> +static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type, >>> +                        u32 attr, int channel, long *val) >>> +{ >>> +       struct peci_dimmtemp *priv = dev_get_drvdata(dev); >>> + >>> +       switch (attr) { >>> +       case hwmon_temp_input: >>> +               return get_dimm_temp(priv, channel, val); >>> +       case hwmon_temp_max: >>> +               return get_dimm_thresholds(priv, temp_max_type, channel, >>> val); >>> +       case hwmon_temp_crit: >>> +               return get_dimm_thresholds(priv, temp_crit_type, channel, >>> val); >>> +       default: >>> +               break; >>> +       } >>> + >>> +       return -EOPNOTSUPP; >>> +} >>> + >>> +static umode_t dimmtemp_is_visible(const void *data, enum >>> hwmon_sensor_types type, >>> +                                  u32 attr, int channel) >>> +{ >>> +       const struct peci_dimmtemp *priv = data; >>> + >>> +       if (test_bit(channel, priv->dimm_mask)) >>> +               return 0444; >>> + >>> +       return 0; >>> +} >>> + >>> +static const struct hwmon_ops peci_dimmtemp_ops = { >>> +       .is_visible = dimmtemp_is_visible, >>> +       .read_string = dimmtemp_read_string, >>> +       .read = dimmtemp_read, >>> +}; >>> + >>> +static int check_populated_dimms(struct peci_dimmtemp *priv) >>> +{ >>> +       int chan_rank_max = priv->gen_info->chan_rank_max; >>> +       int dimm_idx_max = priv->gen_info->dimm_idx_max; >>> +       u32 chan_rank_empty = 0; >>> +       u64 dimm_mask = 0; >>> +       int chan_rank, dimm_idx, ret; >>> +       u32 pcs; >>> + >>> +       BUILD_BUG_ON(CHAN_RANK_MAX > 32); >>> +       BUILD_BUG_ON(DIMM_NUMS_MAX > 64); >> >> I don't immediately see the value of those build bugs. What happens if >> CHAN_RANK_MAX > 32 or DIMM_NUMS_MAX > 64 ? Where do those limits come >> from ? > > Supported HW doesn't come near the limit for now - it's just an "artificial" > limit imposed by variables we're using (u64 for dimm_mask and u32 for > chan_rank_empty). > Please use a value derived from the size of those variables for the check to clarify and explain the constraints. Thanks, Guenter 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=-16.1 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,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_1 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 4B57EC4338F for ; Wed, 4 Aug 2021 17:38:35 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 065BB60E78 for ; Wed, 4 Aug 2021 17:38:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 065BB60E78 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=roeck-us.net Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:Subject: From:References:Cc:To:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=q+meXCOkXJyBtB2cFe9bEMH2Z5M8bP8sCwYrsYDR3HA=; b=rRUf/nyU5swYY104UkqWpHMdgU 8f73HpWqXL1R42xTLwpjbpOgaJjDf4ZYl0Cd+Ob4Te/hC2Y7ugYmrsU41kIIVirV82AlytYX+gaTr UXZNblamGpBtPkoZvG4v6sSQcKYeNMntHJS6NeniHbDocSi35BrPnofeEFn45rTtBNDBMvTCjwjHk jmvhv+0JauHCz8nmbiaH8F6evdTz8zfJ7oqVjoC4AMkpVCYchJOX+L+9ILuOx574fLWGZ41SGE6+O 0Nq3+lR6LWfkZ+pbuAclfoHs5/ufXibo27cGwjX5mwTiLWzqKYJb/aDF7D+j4wj7rOP1OSsE/nLG6 aYicKuow==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBKoP-0072gN-5w; Wed, 04 Aug 2021 17:36:15 +0000 Received: from mail-oi1-x22c.google.com ([2607:f8b0:4864:20::22c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBKlx-0071U5-LJ for linux-arm-kernel@lists.infradead.org; Wed, 04 Aug 2021 17:33:46 +0000 Received: by mail-oi1-x22c.google.com with SMTP id a19so3723782oiw.6 for ; Wed, 04 Aug 2021 10:33:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:cc:references:from:subject:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=boQtfMOkZY9hdjBQivOx+8/FvLGtf9v8PYVfUON6vUQ=; b=GvZ1SBNr2DcgJSQTR+uzl4H3+WJD0SNH7HsHspqb1BuouaZcwWSbrOHZ+5+HQweU3Q SMGyUIijwEnz1zocHU2f3X51iEnbnHYb6QNZS6+L/bmhDL0udvq2jZEDzJH7QCPZfg6i TSj6sC7jX/J/xEmLLGkIcmArcjjT5iYMeGXdZ/mc0ExqIXdG//pYUjIRR4bvfgwI0qHT T/d6z23Qsjstwvy5CdR74maXQ0BkfvtzjvpFPE2vVilXNhN3ERNBCO9oxlBk/9Cx8lR8 ilnua+8hAP85QWI+qlaF3Mk4b7tWWscPH5SgzvMC6B8M/2AuGqyrdFUJrgrxe+Nzu0WV G/vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:cc:references:from:subject:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=boQtfMOkZY9hdjBQivOx+8/FvLGtf9v8PYVfUON6vUQ=; b=pE96q4RtRoQUpfhdlble5Hs2Q0o1XiHmhkeQEP/y8YCORcwB8mflB/S9A31lBuvhZA 8L3ZmzGS6QrMk45lDx5U8n44nsdnbSZU27jGn4ZjReSQkzroTG2vYwnCGJ9m1tDimdKz uDTSbClKcSomuPnaGCWRVXBT96nYVeqJi74kC70bpr40G2Y9BO5MC4wmVnytpig/WA5V L7BNXQIas1H7Sf44VA5wGa41hWA5OeycyXm4nJSW262VqfBU47Qk/tECzaQ9et61dfZn A50KZJVJQstZukFKTXRCdbV/w8Le6/l3cveySR6c7uEX4pPSP4/ZEB1VcjVoyYXqcac5 P62Q== X-Gm-Message-State: AOAM533N74EEGSdYTLsHOCu8PlvLkh1LIbeXQGcB7kbNx6EioBX5fyLD NRMkH7ShFd+OzBawRYWWSWw= X-Google-Smtp-Source: ABdhPJzPmtomHiFQRHu0Frnwj19U5U9ieIGCtt/9GmfJnQQrdsF77jcXTd2yPxviTb/mGRTxwKZmwA== X-Received: by 2002:aca:39c6:: with SMTP id g189mr2259435oia.47.1628098419381; Wed, 04 Aug 2021 10:33:39 -0700 (PDT) Received: from server.roeck-us.net ([2600:1700:e321:62f0:329c:23ff:fee3:9d7c]) by smtp.gmail.com with ESMTPSA id c21sm560538oiw.16.2021.08.04.10.33.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 04 Aug 2021 10:33:38 -0700 (PDT) To: "Winiarska, Iwona" Cc: "corbet@lwn.net" , "jae.hyun.yoo@linux.intel.com" , "Williams, Dan J" , "linux-hwmon@vger.kernel.org" , "andrew@aj.id.au" , "Luck, Tony" , "Lutomirski, Andy" , "andriy.shevchenko@linux.intel.com" , "mchehab@kernel.org" , "jdelvare@suse.com" , "linux-kernel@vger.kernel.org" , "olof@lixom.net" , "mingo@redhat.com" , "rdunlap@infradead.org" , "devicetree@vger.kernel.org" , "tglx@linutronix.de" , "linux-aspeed@lists.ozlabs.org" , "arnd@arndb.de" , "linux-doc@vger.kernel.org" , "yazen.ghannam@amd.com" , "zweiss@equinix.com" , "robh+dt@kernel.org" , "openbmc@lists.ozlabs.org" , "gregkh@linuxfoundation.org" , "joel@jms.id.au" , "d.mueller@elsoft.ch" , "linux-arm-kernel@lists.infradead.org" , "pierre-louis.bossart@linux.intel.com" , "x86@kernel.org" , "bp@alien8.de" References: <20210803113134.2262882-1-iwona.winiarska@intel.com> <20210803113134.2262882-14-iwona.winiarska@intel.com> <20210803153937.GA337938@roeck-us.net> From: Guenter Roeck Subject: Re: [PATCH v2 13/15] hwmon: peci: Add dimmtemp driver Message-ID: Date: Wed, 4 Aug 2021 10:33:35 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210804_103341_773132_55FA3E7E X-CRM114-Status: GOOD ( 25.76 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org T24gOC80LzIxIDM6NDYgQU0sIFdpbmlhcnNrYSwgSXdvbmEgd3JvdGU6Cj4gT24gVHVlLCAyMDIx LTA4LTAzIGF0IDA4OjM5IC0wNzAwLCBHdWVudGVyIFJvZWNrIHdyb3RlOgo+PiBPbiBUdWUsIEF1 ZyAwMywgMjAyMSBhdCAwMTozMTozMlBNICswMjAwLCBJd29uYSBXaW5pYXJza2Egd3JvdGU6Cj4+ PiBBZGQgcGVjaS1kaW1tdGVtcCBkcml2ZXIgZm9yIFRlbXBlcmF0dXJlIFNlbnNvciBvbiBESU1N IHJlYWRpbmdzIHRoYXQKPj4+IGFyZSBhY2Nlc3NpYmxlIHZpYSB0aGUgcHJvY2Vzc29yIFBFQ0kg aW50ZXJmYWNlLgo+Pj4KPj4+IFRoZSBtYWluIHVzZSBjYXNlIGZvciB0aGUgZHJpdmVyIChhbmQg UEVDSSBpbnRlcmZhY2UpIGlzIG91dC1vZi1iYW5kCj4+PiBtYW5hZ2VtZW50LCB3aGVyZSB3ZSdy ZSBhYmxlIHRvIG9idGFpbiB0aGVybWFsIHJlYWRpbmdzIGZyb20gYW4gZXh0ZXJuYWwKPj4+IGVu dGl0eSBjb25uZWN0ZWQgd2l0aCBQRUNJLCBlLmcuIEJNQyBvbiBzZXJ2ZXIgcGxhdGZvcm1zLgo+ Pj4KPj4+IENvLWRldmVsb3BlZC1ieTogSmFlIEh5dW4gWW9vIDxqYWUuaHl1bi55b29AbGludXgu aW50ZWwuY29tPgo+Pj4gU2lnbmVkLW9mZi1ieTogSmFlIEh5dW4gWW9vIDxqYWUuaHl1bi55b29A bGludXguaW50ZWwuY29tPgo+Pj4gU2lnbmVkLW9mZi1ieTogSXdvbmEgV2luaWFyc2thIDxpd29u YS53aW5pYXJza2FAaW50ZWwuY29tPgo+Pj4gUmV2aWV3ZWQtYnk6IFBpZXJyZS1Mb3VpcyBCb3Nz YXJ0IDxwaWVycmUtbG91aXMuYm9zc2FydEBsaW51eC5pbnRlbC5jb20+Cj4+PiAtLS0KPj4+IE5v dGUgdGhhdCB0aGUgdGltZW91dCB3YXMgY29tcGxldGVseSByZW1vdmVkIC0gd2UncmUgZ29pbmcg dG8gcHJvYmUKPj4+IGZvciBkZXRlY3RlZCBESU1NcyBldmVyeSA1IHNlY29uZHMgdW50aWwgd2Ug cmVhY2ggInN0YWJsZSIgc3RhdGUgb2YKPj4+IGVpdGhlciBnZXR0aW5nIGNvcnJlY3QgRElNTSBk YXRhIG9yIGdldHRpbmcgYWxsIC1FSU5WQUwgKHdoaWNoCj4+PiBzdWdnZXN0IHRoYXQgdGhlIENQ VSBkb2Vzbid0IGhhdmUgYW55IERJTU1zKS4KPj4+Cj4+PiAgwqBkcml2ZXJzL2h3bW9uL3BlY2kv S2NvbmZpZ8KgwqDCoCB8wqAgMTMgKwo+Pj4gIMKgZHJpdmVycy9od21vbi9wZWNpL01ha2VmaWxl wqDCoCB8wqDCoCAyICsKPj4+ICDCoGRyaXZlcnMvaHdtb24vcGVjaS9kaW1tdGVtcC5jIHwgNjE0 ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPj4+ICDCoDMgZmlsZXMgY2hhbmdl ZCwgNjI5IGluc2VydGlvbnMoKykKPj4+ICDCoGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2h3 bW9uL3BlY2kvZGltbXRlbXAuYwo+Pj4KPj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2h3bW9uL3Bl Y2kvS2NvbmZpZyBiL2RyaXZlcnMvaHdtb24vcGVjaS9LY29uZmlnCj4+PiBpbmRleCBlMTBlZWQ2 OGQ3MGEuLjlkMzJhNTdiYWRmZSAxMDA2NDQKPj4+IC0tLSBhL2RyaXZlcnMvaHdtb24vcGVjaS9L Y29uZmlnCj4+PiArKysgYi9kcml2ZXJzL2h3bW9uL3BlY2kvS2NvbmZpZwo+Pj4gQEAgLTE0LDUg KzE0LDE4IEBAIGNvbmZpZyBTRU5TT1JTX1BFQ0lfQ1BVVEVNUAo+Pj4gIMKgwqDCoMKgwqDCoMKg wqDCoCBUaGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRo ZSBtb2R1bGUKPj4+ICDCoMKgwqDCoMKgwqDCoMKgwqAgd2lsbCBiZSBjYWxsZWQgcGVjaS1jcHV0 ZW1wLgo+Pj4gICAKPj4+ICtjb25maWcgU0VOU09SU19QRUNJX0RJTU1URU1QCj4+PiArwqDCoMKg wqDCoMKgwqB0cmlzdGF0ZSAiUEVDSSBESU1NIHRlbXBlcmF0dXJlIG1vbml0b3JpbmcgY2xpZW50 Igo+Pj4gK8KgwqDCoMKgwqDCoMKgZGVwZW5kcyBvbiBQRUNJCj4+PiArwqDCoMKgwqDCoMKgwqBz ZWxlY3QgU0VOU09SU19QRUNJCj4+PiArwqDCoMKgwqDCoMKgwqBzZWxlY3QgUEVDSV9DUFUKPj4+ ICvCoMKgwqDCoMKgwqDCoGhlbHAKPj4+ICvCoMKgwqDCoMKgwqDCoMKgIElmIHlvdSBzYXkgeWVz IGhlcmUgeW91IGdldCBzdXBwb3J0IGZvciB0aGUgZ2VuZXJpYyBJbnRlbCBQRUNJCj4+PiBod21v bgo+Pj4gK8KgwqDCoMKgwqDCoMKgwqAgZHJpdmVyIHdoaWNoIHByb3ZpZGVzIFRlbXBlcmF0dXJl IFNlbnNvciBvbiBESU1NIHJlYWRpbmdzIHRoYXQgYXJlCj4+PiArwqDCoMKgwqDCoMKgwqDCoCBh Y2Nlc3NpYmxlIHZpYSB0aGUgcHJvY2Vzc29yIFBFQ0kgaW50ZXJmYWNlLgo+Pj4gKwo+Pj4gK8Kg wqDCoMKgwqDCoMKgwqAgVGhpcyBkcml2ZXIgY2FuIGFsc28gYmUgYnVpbHQgYXMgYSBtb2R1bGUu IElmIHNvLCB0aGUgbW9kdWxlCj4+PiArwqDCoMKgwqDCoMKgwqDCoCB3aWxsIGJlIGNhbGxlZCBw ZWNpLWRpbW10ZW1wLgo+Pj4gKwo+Pj4gIMKgY29uZmlnIFNFTlNPUlNfUEVDSQo+Pj4gIMKgwqDC oMKgwqDCoMKgwqB0cmlzdGF0ZQo+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaHdtb24vcGVjaS9N YWtlZmlsZSBiL2RyaXZlcnMvaHdtb24vcGVjaS9NYWtlZmlsZQo+Pj4gaW5kZXggZThhMGFkYTVh YjFmLi4xOTFjZmEwMjI3ZjMgMTAwNjQ0Cj4+PiAtLS0gYS9kcml2ZXJzL2h3bW9uL3BlY2kvTWFr ZWZpbGUKPj4+ICsrKyBiL2RyaXZlcnMvaHdtb24vcGVjaS9NYWtlZmlsZQo+Pj4gQEAgLTEsNSAr MSw3IEBACj4+PiAgwqAjIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkKPj4+ ICAgCj4+PiAgwqBwZWNpLWNwdXRlbXAteSA6PSBjcHV0ZW1wLm8KPj4+ICtwZWNpLWRpbW10ZW1w LXkgOj0gZGltbXRlbXAubwo+Pj4gICAKPj4+ICDCoG9iai0kKENPTkZJR19TRU5TT1JTX1BFQ0lf Q1BVVEVNUCnCoMKgwqDCoMKgKz0gcGVjaS1jcHV0ZW1wLm8KPj4+ICtvYmotJChDT05GSUdfU0VO U09SU19QRUNJX0RJTU1URU1QKcKgwqDCoMKgKz0gcGVjaS1kaW1tdGVtcC5vCj4+PiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9od21vbi9wZWNpL2RpbW10ZW1wLmMgYi9kcml2ZXJzL2h3bW9uL3BlY2kv ZGltbXRlbXAuYwo+Pj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4+IGluZGV4IDAwMDAwMDAwMDAw MC4uNjI2NGMyOWJiNmMwCj4+PiAtLS0gL2Rldi9udWxsCj4+PiArKysgYi9kcml2ZXJzL2h3bW9u L3BlY2kvZGltbXRlbXAuYwo+Pj4gQEAgLTAsMCArMSw2MTQgQEAKPj4+ICsvLyBTUERYLUxpY2Vu c2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5Cj4+PiArLy8gQ29weXJpZ2h0IChjKSAyMDE4LTIw MjEgSW50ZWwgQ29ycG9yYXRpb24KPj4+ICsKPj4+ICsjaW5jbHVkZSA8bGludXgvYXV4aWxpYXJ5 X2J1cy5oPgo+Pj4gKyNpbmNsdWRlIDxsaW51eC9iaXRmaWVsZC5oPgo+Pj4gKyNpbmNsdWRlIDxs aW51eC9iaXRvcHMuaD4KPj4+ICsjaW5jbHVkZSA8bGludXgvaHdtb24uaD4KPj4+ICsjaW5jbHVk ZSA8bGludXgvamlmZmllcy5oPgo+Pj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPj4+ICsj aW5jbHVkZSA8bGludXgvcGVjaS5oPgo+Pj4gKyNpbmNsdWRlIDxsaW51eC9wZWNpLWNwdS5oPgo+ Pj4gKyNpbmNsdWRlIDxsaW51eC91bml0cy5oPgo+Pj4gKyNpbmNsdWRlIDxsaW51eC93b3JrcXVl dWUuaD4KPj4+ICsjaW5jbHVkZSA8bGludXgveDg2L2ludGVsLWZhbWlseS5oPgo+Pj4gKwo+Pj4g KyNpbmNsdWRlICJjb21tb24uaCIKPj4+ICsKPj4+ICsjZGVmaW5lIERJTU1fTUFTS19DSEVDS19E RUxBWV9KSUZGSUVTwqDCoG1zZWNzX3RvX2ppZmZpZXMoNTAwMCkKPj4+ICsKPj4+ICsvKiBNYXgg bnVtYmVyIG9mIGNoYW5uZWwgcmFua3MgYW5kIERJTU0gaW5kZXggcGVyIGNoYW5uZWwgKi8KPj4+ ICsjZGVmaW5lIENIQU5fUkFOS19NQVhfT05fSFNYwqDCoMKgOAo+Pj4gKyNkZWZpbmUgRElNTV9J RFhfTUFYX09OX0hTWMKgwqDCoMKgMwo+Pj4gKyNkZWZpbmUgQ0hBTl9SQU5LX01BWF9PTl9CRFjC oMKgwqA0Cj4+PiArI2RlZmluZSBESU1NX0lEWF9NQVhfT05fQkRYwqDCoMKgwqAzCj4+PiArI2Rl ZmluZSBDSEFOX1JBTktfTUFYX09OX0JEWETCoMKgMgo+Pj4gKyNkZWZpbmUgRElNTV9JRFhfTUFY X09OX0JEWETCoMKgwqAyCj4+PiArI2RlZmluZSBDSEFOX1JBTktfTUFYX09OX1NLWMKgwqDCoDYK Pj4+ICsjZGVmaW5lIERJTU1fSURYX01BWF9PTl9TS1jCoMKgwqDCoDIKPj4+ICsjZGVmaW5lIENI QU5fUkFOS19NQVhfT05fSUNYwqDCoMKgOAo+Pj4gKyNkZWZpbmUgRElNTV9JRFhfTUFYX09OX0lD WMKgwqDCoMKgMgo+Pj4gKyNkZWZpbmUgQ0hBTl9SQU5LX01BWF9PTl9JQ1hEwqDCoDQKPj4+ICsj ZGVmaW5lIERJTU1fSURYX01BWF9PTl9JQ1hEwqDCoMKgMgo+Pj4gKwo+Pj4gKyNkZWZpbmUgQ0hB Tl9SQU5LX01BWMKgwqDCoMKgwqDCoMKgwqDCoMKgQ0hBTl9SQU5LX01BWF9PTl9IU1gKPj4+ICsj ZGVmaW5lIERJTU1fSURYX01BWMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBESU1NX0lEWF9NQVhfT05f SFNYCj4+PiArI2RlZmluZSBESU1NX05VTVNfTUFYwqDCoMKgwqDCoMKgwqDCoMKgwqAoQ0hBTl9S QU5LX01BWCAqIERJTU1fSURYX01BWCkKPj4+ICsKPj4+ICsjZGVmaW5lIENQVV9TRUdfTUFTS8Kg wqDCoMKgwqDCoMKgwqDCoMKgwqBHRU5NQVNLKDIzLCAxNikKPj4+ICsjZGVmaW5lIEdFVF9DUFVf U0VHKHgpwqDCoMKgwqDCoMKgwqDCoMKgKCgoeCkgJiBDUFVfU0VHX01BU0spID4+IDE2KQo+Pj4g KyNkZWZpbmUgQ1BVX0JVU19NQVNLwqDCoMKgwqDCoMKgwqDCoMKgwqDCoEdFTk1BU0soNywgMCkK Pj4+ICsjZGVmaW5lIEdFVF9DUFVfQlVTKHgpwqDCoMKgwqDCoMKgwqDCoMKgKCh4KSAmIENQVV9C VVNfTUFTSykKPj4+ICsKPj4+ICsjZGVmaW5lIERJTU1fVEVNUF9NQVjCoMKgwqDCoMKgwqDCoMKg wqDCoEdFTk1BU0soMTUsIDgpCj4+PiArI2RlZmluZSBESU1NX1RFTVBfQ1JJVMKgwqDCoMKgwqDC oMKgwqDCoEdFTk1BU0soMjMsIDE2KQo+Pj4gKyNkZWZpbmUgR0VUX1RFTVBfTUFYKHgpwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAoKCh4KSAmIERJTU1fVEVNUF9NQVgpID4+IDgpCj4+ PiArI2RlZmluZSBHRVRfVEVNUF9DUklUKHgpwqDCoMKgwqDCoMKgwqAoKCh4KSAmIERJTU1fVEVN UF9DUklUKSA+PiAxNikKPj4+ICsKPj4+ICtzdHJ1Y3QgcGVjaV9kaW1tdGVtcDsKPj4+ICsKPj4+ ICtzdHJ1Y3QgZGltbV9pbmZvIHsKPj4+ICvCoMKgwqDCoMKgwqDCoGludCBjaGFuX3JhbmtfbWF4 Owo+Pj4gK8KgwqDCoMKgwqDCoMKgaW50IGRpbW1faWR4X21heDsKPj4+ICvCoMKgwqDCoMKgwqDC oHU4IG1pbl9wZWNpX3JldmlzaW9uOwo+Pj4gK8KgwqDCoMKgwqDCoMKgaW50ICgqcmVhZF90aHJl c2hvbGRzKShzdHJ1Y3QgcGVjaV9kaW1tdGVtcCAqcHJpdiwgaW50IGRpbW1fb3JkZXIsCj4+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBpbnQgY2hhbl9yYW5rLCB1MzIgKmRhdGEpOwo+Pj4gK307Cj4+PiArCj4+PiArc3RydWN0IHBl Y2lfZGltbV90aHJlc2hvbGRzIHsKPj4+ICvCoMKgwqDCoMKgwqDCoGxvbmcgdGVtcF9tYXg7Cj4+ PiArwqDCoMKgwqDCoMKgwqBsb25nIHRlbXBfY3JpdDsKPj4+ICvCoMKgwqDCoMKgwqDCoHN0cnVj dCBwZWNpX3NlbnNvcl9zdGF0ZSBzdGF0ZTsKPj4+ICt9Owo+Pj4gKwo+Pj4gK2VudW0gcGVjaV9k aW1tX3RocmVzaG9sZF90eXBlIHsKPj4+ICvCoMKgwqDCoMKgwqDCoHRlbXBfbWF4X3R5cGUsCj4+ PiArwqDCoMKgwqDCoMKgwqB0ZW1wX2NyaXRfdHlwZSwKPj4+ICt9Owo+Pj4gKwo+Pj4gK3N0cnVj dCBwZWNpX2RpbW10ZW1wIHsKPj4+ICvCoMKgwqDCoMKgwqDCoHN0cnVjdCBwZWNpX2RldmljZSAq cGVjaV9kZXY7Cj4+PiArwqDCoMKgwqDCoMKgwqBzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4+PiArwqDC oMKgwqDCoMKgwqBjb25zdCBjaGFyICpuYW1lOwo+Pj4gK8KgwqDCoMKgwqDCoMKgY29uc3Qgc3Ry dWN0IGRpbW1faW5mbyAqZ2VuX2luZm87Cj4+PiArwqDCoMKgwqDCoMKgwqBzdHJ1Y3QgZGVsYXll ZF93b3JrIGRldGVjdF93b3JrOwo+Pj4gK8KgwqDCoMKgwqDCoMKgc3RydWN0IHsKPj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBzdHJ1Y3QgcGVjaV9zZW5zb3JfZGF0YSB0ZW1wOwo+ Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHN0cnVjdCBwZWNpX2RpbW1fdGhyZXNo b2xkcyB0aHJlc2hvbGRzOwo+Pj4gK8KgwqDCoMKgwqDCoMKgfSBkaW1tW0RJTU1fTlVNU19NQVhd Owo+Pj4gK8KgwqDCoMKgwqDCoMKgY2hhciAqKmRpbW10ZW1wX2xhYmVsOwo+Pj4gK8KgwqDCoMKg wqDCoMKgREVDTEFSRV9CSVRNQVAoZGltbV9tYXNrLCBESU1NX05VTVNfTUFYKTsKPj4+ICt9Owo+ Pj4gKwo+Pj4gK3N0YXRpYyB1OCBfX2RpbW1fdGVtcCh1MzIgcmVnLCBpbnQgZGltbV9vcmRlcikK Pj4+ICt7Cj4+PiArwqDCoMKgwqDCoMKgwqByZXR1cm4gKHJlZyA+PiAoZGltbV9vcmRlciAqIDgp KSAmIDB4ZmY7Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyBpbnQgZ2V0X2RpbW1fdGVtcChzdHJ1 Y3QgcGVjaV9kaW1tdGVtcCAqcHJpdiwgaW50IGRpbW1fbm8sIGxvbmcKPj4+ICp2YWwpCj4+PiAr ewo+Pj4gK8KgwqDCoMKgwqDCoMKgaW50IGRpbW1fb3JkZXIgPSBkaW1tX25vICUgcHJpdi0+Z2Vu X2luZm8tPmRpbW1faWR4X21heDsKPj4+ICvCoMKgwqDCoMKgwqDCoGludCBjaGFuX3JhbmsgPSBk aW1tX25vIC8gcHJpdi0+Z2VuX2luZm8tPmRpbW1faWR4X21heDsKPj4+ICvCoMKgwqDCoMKgwqDC oHUzMiBkYXRhOwo+Pj4gK8KgwqDCoMKgwqDCoMKgaW50IHJldDsKPj4KPj4gIMKgwqDCoMKgwqDC oMKgwqBpbnQgcmV0ID0gMDsKPj4KPj4+ICsKPj4+ICvCoMKgwqDCoMKgwqDCoG11dGV4X2xvY2so JnByaXYtPmRpbW1bZGltbV9ub10udGVtcC5zdGF0ZS5sb2NrKTsKPj4+ICvCoMKgwqDCoMKgwqDC oGlmICghcGVjaV9zZW5zb3JfbmVlZF91cGRhdGUoJnByaXYtPmRpbW1bZGltbV9ub10udGVtcC5z dGF0ZSkpCj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgZ290byBza2lwX3VwZGF0 ZTsKPj4+ICsKPj4+ICvCoMKgwqDCoMKgwqDCoHJldCA9IHBlY2lfcGNzX3JlYWQocHJpdi0+cGVj aV9kZXYsIFBFQ0lfUENTX0REUl9ESU1NX1RFTVAsCj4+PiBjaGFuX3JhbmssICZkYXRhKTsKPj4+ ICvCoMKgwqDCoMKgwqDCoGlmIChyZXQpIHsKPj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqBtdXRleF91bmxvY2soJnByaXYtPmRpbW1bZGltbV9ub10udGVtcC5zdGF0ZS5sb2NrKTsK Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqByZXR1cm4gcmV0Owo+Pj4gK8KgwqDC oMKgwqDCoMKgfQo+Pgo+PiAgwqDCoMKgwqDCoMKgwqDCoGlmIChyZXQpCj4+ICDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoGdvdG8gdW5sb2NrOwo+Pgo+Pj4gKwo+Pj4gK8KgwqDCoMKg wqDCoMKgcHJpdi0+ZGltbVtkaW1tX25vXS50ZW1wLnZhbHVlID0gX19kaW1tX3RlbXAoZGF0YSwg ZGltbV9vcmRlcikgKgo+Pj4gTUlMTElERUdSRUVfUEVSX0RFR1JFRTsKPj4+ICsKPj4+ICvCoMKg wqDCoMKgwqDCoHBlY2lfc2Vuc29yX21hcmtfdXBkYXRlZCgmcHJpdi0+ZGltbVtkaW1tX25vXS50 ZW1wLnN0YXRlKTsKPj4+ICsKPj4+ICtza2lwX3VwZGF0ZToKPj4+ICvCoMKgwqDCoMKgwqDCoCp2 YWwgPSBwcml2LT5kaW1tW2RpbW1fbm9dLnRlbXAudmFsdWU7Cj4+Cj4+IHVubG9jazoKPj4+ICvC oMKgwqDCoMKgwqDCoG11dGV4X3VubG9jaygmcHJpdi0+ZGltbVtkaW1tX25vXS50ZW1wLnN0YXRl LmxvY2spOwo+Pj4gK8KgwqDCoMKgwqDCoMKgcmV0dXJuIDA7Cj4+Cj4+ICDCoMKgwqDCoMKgwqDC oMKgcmV0dXJuIHJldDsKPiAKPiBBY2suCj4gCj4+Cj4+PiArfQo+Pj4gKwo+Pj4gK3N0YXRpYyBp bnQgdXBkYXRlX3RocmVzaG9sZHMoc3RydWN0IHBlY2lfZGltbXRlbXAgKnByaXYsIGludCBkaW1t X25vKQo+Pj4gK3sKPj4+ICvCoMKgwqDCoMKgwqDCoGludCBkaW1tX29yZGVyID0gZGltbV9ubyAl IHByaXYtPmdlbl9pbmZvLT5kaW1tX2lkeF9tYXg7Cj4+PiArwqDCoMKgwqDCoMKgwqBpbnQgY2hh bl9yYW5rID0gZGltbV9ubyAvIHByaXYtPmdlbl9pbmZvLT5kaW1tX2lkeF9tYXg7Cj4+PiArwqDC oMKgwqDCoMKgwqB1MzIgZGF0YTsKPj4+ICvCoMKgwqDCoMKgwqDCoGludCByZXQ7Cj4+PiArCj4+ PiArwqDCoMKgwqDCoMKgwqBpZiAoIXBlY2lfc2Vuc29yX25lZWRfdXBkYXRlKCZwcml2LT5kaW1t W2RpbW1fbm9dLnRocmVzaG9sZHMuc3RhdGUpKQo+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoHJldHVybiAwOwo+Pj4gKwo+Pj4gK8KgwqDCoMKgwqDCoMKgcmV0ID0gcHJpdi0+Z2Vu X2luZm8tPnJlYWRfdGhyZXNob2xkcyhwcml2LCBkaW1tX29yZGVyLCBjaGFuX3JhbmssCj4+PiAm ZGF0YSk7Cj4+PiArwqDCoMKgwqDCoMKgwqBpZiAocmV0ID09IC1FTk9EQVRBKSAvKiBVc2UgZGVm YXVsdCBvciBwcmV2aW91cyB2YWx1ZSAqLwo+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoHJldHVybiAwOwo+Pj4gK8KgwqDCoMKgwqDCoMKgaWYgKHJldCkKPj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqByZXR1cm4gcmV0Owo+Pj4gKwo+Pj4gK8KgwqDCoMKgwqDCoMKg cHJpdi0+ZGltbVtkaW1tX25vXS50aHJlc2hvbGRzLnRlbXBfbWF4ID0gR0VUX1RFTVBfTUFYKGRh dGEpICoKPj4+IE1JTExJREVHUkVFX1BFUl9ERUdSRUU7Cj4+PiArwqDCoMKgwqDCoMKgwqBwcml2 LT5kaW1tW2RpbW1fbm9dLnRocmVzaG9sZHMudGVtcF9jcml0ID0gR0VUX1RFTVBfQ1JJVChkYXRh KSAqCj4+PiBNSUxMSURFR1JFRV9QRVJfREVHUkVFOwo+Pj4gKwo+Pj4gK8KgwqDCoMKgwqDCoMKg cGVjaV9zZW5zb3JfbWFya191cGRhdGVkKCZwcml2LT5kaW1tW2RpbW1fbm9dLnRocmVzaG9sZHMu c3RhdGUpOwo+Pj4gKwo+Pj4gK8KgwqDCoMKgwqDCoMKgcmV0dXJuIDA7Cj4+PiArfQo+Pj4gKwo+ Pj4gK3N0YXRpYyBpbnQgZ2V0X2RpbW1fdGhyZXNob2xkcyhzdHJ1Y3QgcGVjaV9kaW1tdGVtcCAq cHJpdiwgZW51bQo+Pj4gcGVjaV9kaW1tX3RocmVzaG9sZF90eXBlIHR5cGUsCj4+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpbnQg ZGltbV9ubywgbG9uZyAqdmFsKQo+Pj4gK3sKPj4+ICvCoMKgwqDCoMKgwqDCoGludCByZXQ7Cj4+ PiArCj4+PiArwqDCoMKgwqDCoMKgwqBtdXRleF9sb2NrKCZwcml2LT5kaW1tW2RpbW1fbm9dLnRo cmVzaG9sZHMuc3RhdGUubG9jayk7Cj4+PiArwqDCoMKgwqDCoMKgwqByZXQgPSB1cGRhdGVfdGhy ZXNob2xkcyhwcml2LCBkaW1tX25vKTsKPj4+ICvCoMKgwqDCoMKgwqDCoGlmIChyZXQpCj4+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgZ290byB1bmxvY2s7Cj4+PiArCj4+PiArwqDC oMKgwqDCoMKgwqBzd2l0Y2ggKHR5cGUpIHsKPj4+ICvCoMKgwqDCoMKgwqDCoGNhc2UgdGVtcF9t YXhfdHlwZToKPj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAqdmFsID0gcHJpdi0+ ZGltbVtkaW1tX25vXS50aHJlc2hvbGRzLnRlbXBfbWF4Owo+Pj4gK8KgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoGJyZWFrOwo+Pj4gK8KgwqDCoMKgwqDCoMKgY2FzZSB0ZW1wX2NyaXRfdHlw ZToKPj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAqdmFsID0gcHJpdi0+ZGltbVtk aW1tX25vXS50aHJlc2hvbGRzLnRlbXBfY3JpdDsKPj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqBicmVhazsKPj4+ICvCoMKgwqDCoMKgwqDCoGRlZmF1bHQ6Cj4+PiArwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgcmV0ID0gLUVPUE5PVFNVUFA7Cj4+PiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgYnJlYWs7Cj4+PiArwqDCoMKgwqDCoMKgwqB9Cj4+PiArdW5sb2Nr Ogo+Pj4gK8KgwqDCoMKgwqDCoMKgbXV0ZXhfdW5sb2NrKCZwcml2LT5kaW1tW2RpbW1fbm9dLnRo cmVzaG9sZHMuc3RhdGUubG9jayk7Cj4+PiArCj4+PiArwqDCoMKgwqDCoMKgwqByZXR1cm4gcmV0 Owo+Pj4gK30KPj4+ICsKPj4+ICtzdGF0aWMgaW50IGRpbW10ZW1wX3JlYWRfc3RyaW5nKHN0cnVj dCBkZXZpY2UgKmRldiwKPj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGVudW0gaHdtb25fc2Vuc29yX3R5cGVzIHR5cGUsCj4+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqB1MzIgYXR0ciwgaW50IGNoYW5uZWwsIGNvbnN0IGNoYXIgKipzdHIpCj4+PiArewo+ Pj4gK8KgwqDCoMKgwqDCoMKgc3RydWN0IHBlY2lfZGltbXRlbXAgKnByaXYgPSBkZXZfZ2V0X2Ry dmRhdGEoZGV2KTsKPj4+ICsKPj4+ICvCoMKgwqDCoMKgwqDCoGlmIChhdHRyICE9IGh3bW9uX3Rl bXBfbGFiZWwpCj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgcmV0dXJuIC1FT1BO T1RTVVBQOwo+Pj4gKwo+Pj4gK8KgwqDCoMKgwqDCoMKgKnN0ciA9IChjb25zdCBjaGFyICopcHJp di0+ZGltbXRlbXBfbGFiZWxbY2hhbm5lbF07Cj4+PiArCj4+PiArwqDCoMKgwqDCoMKgwqByZXR1 cm4gMDsKPj4+ICt9Cj4+PiArCj4+PiArc3RhdGljIGludCBkaW1tdGVtcF9yZWFkKHN0cnVjdCBk ZXZpY2UgKmRldiwgZW51bSBod21vbl9zZW5zb3JfdHlwZXMgdHlwZSwKPj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHUzMiBhdHRyLCBpbnQgY2hhbm5l bCwgbG9uZyAqdmFsKQo+Pj4gK3sKPj4+ICvCoMKgwqDCoMKgwqDCoHN0cnVjdCBwZWNpX2RpbW10 ZW1wICpwcml2ID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4+PiArCj4+PiArwqDCoMKgwqDCoMKg wqBzd2l0Y2ggKGF0dHIpIHsKPj4+ICvCoMKgwqDCoMKgwqDCoGNhc2UgaHdtb25fdGVtcF9pbnB1 dDoKPj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqByZXR1cm4gZ2V0X2RpbW1fdGVt cChwcml2LCBjaGFubmVsLCB2YWwpOwo+Pj4gK8KgwqDCoMKgwqDCoMKgY2FzZSBod21vbl90ZW1w X21heDoKPj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqByZXR1cm4gZ2V0X2RpbW1f dGhyZXNob2xkcyhwcml2LCB0ZW1wX21heF90eXBlLCBjaGFubmVsLAo+Pj4gdmFsKTsKPj4+ICvC oMKgwqDCoMKgwqDCoGNhc2UgaHdtb25fdGVtcF9jcml0Ogo+Pj4gK8KgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoHJldHVybiBnZXRfZGltbV90aHJlc2hvbGRzKHByaXYsIHRlbXBfY3JpdF90 eXBlLCBjaGFubmVsLAo+Pj4gdmFsKTsKPj4+ICvCoMKgwqDCoMKgwqDCoGRlZmF1bHQ6Cj4+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgYnJlYWs7Cj4+PiArwqDCoMKgwqDCoMKgwqB9 Cj4+PiArCj4+PiArwqDCoMKgwqDCoMKgwqByZXR1cm4gLUVPUE5PVFNVUFA7Cj4+PiArfQo+Pj4g Kwo+Pj4gK3N0YXRpYyB1bW9kZV90IGRpbW10ZW1wX2lzX3Zpc2libGUoY29uc3Qgdm9pZCAqZGF0 YSwgZW51bQo+Pj4gaHdtb25fc2Vuc29yX3R5cGVzIHR5cGUsCj4+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHUzMiBh dHRyLCBpbnQgY2hhbm5lbCkKPj4+ICt7Cj4+PiArwqDCoMKgwqDCoMKgwqBjb25zdCBzdHJ1Y3Qg cGVjaV9kaW1tdGVtcCAqcHJpdiA9IGRhdGE7Cj4+PiArCj4+PiArwqDCoMKgwqDCoMKgwqBpZiAo dGVzdF9iaXQoY2hhbm5lbCwgcHJpdi0+ZGltbV9tYXNrKSkKPj4+ICvCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqByZXR1cm4gMDQ0NDsKPj4+ICsKPj4+ICvCoMKgwqDCoMKgwqDCoHJldHVy biAwOwo+Pj4gK30KPj4+ICsKPj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGh3bW9uX29wcyBwZWNp X2RpbW10ZW1wX29wcyA9IHsKPj4+ICvCoMKgwqDCoMKgwqDCoC5pc192aXNpYmxlID0gZGltbXRl bXBfaXNfdmlzaWJsZSwKPj4+ICvCoMKgwqDCoMKgwqDCoC5yZWFkX3N0cmluZyA9IGRpbW10ZW1w X3JlYWRfc3RyaW5nLAo+Pj4gK8KgwqDCoMKgwqDCoMKgLnJlYWQgPSBkaW1tdGVtcF9yZWFkLAo+ Pj4gK307Cj4+PiArCj4+PiArc3RhdGljIGludCBjaGVja19wb3B1bGF0ZWRfZGltbXMoc3RydWN0 IHBlY2lfZGltbXRlbXAgKnByaXYpCj4+PiArewo+Pj4gK8KgwqDCoMKgwqDCoMKgaW50IGNoYW5f cmFua19tYXggPSBwcml2LT5nZW5faW5mby0+Y2hhbl9yYW5rX21heDsKPj4+ICvCoMKgwqDCoMKg wqDCoGludCBkaW1tX2lkeF9tYXggPSBwcml2LT5nZW5faW5mby0+ZGltbV9pZHhfbWF4Owo+Pj4g K8KgwqDCoMKgwqDCoMKgdTMyIGNoYW5fcmFua19lbXB0eSA9IDA7Cj4+PiArwqDCoMKgwqDCoMKg wqB1NjQgZGltbV9tYXNrID0gMDsKPj4+ICvCoMKgwqDCoMKgwqDCoGludCBjaGFuX3JhbmssIGRp bW1faWR4LCByZXQ7Cj4+PiArwqDCoMKgwqDCoMKgwqB1MzIgcGNzOwo+Pj4gKwo+Pj4gK8KgwqDC oMKgwqDCoMKgQlVJTERfQlVHX09OKENIQU5fUkFOS19NQVggPiAzMik7Cj4+PiArwqDCoMKgwqDC oMKgwqBCVUlMRF9CVUdfT04oRElNTV9OVU1TX01BWCA+IDY0KTsKPj4KPj4gSSBkb24ndCBpbW1l ZGlhdGVseSBzZWUgdGhlIHZhbHVlIG9mIHRob3NlIGJ1aWxkIGJ1Z3MuIFdoYXQgaGFwcGVucyBp Zgo+PiBDSEFOX1JBTktfTUFYID4gMzIgb3IgRElNTV9OVU1TX01BWCA+IDY0ID8gV2hlcmUgZG8g dGhvc2UgbGltaXRzIGNvbWUKPj4gZnJvbSA/Cj4gCj4gU3VwcG9ydGVkIEhXIGRvZXNuJ3QgY29t ZSBuZWFyIHRoZSBsaW1pdCBmb3Igbm93IC0gaXQncyBqdXN0IGFuICJhcnRpZmljaWFsIgo+IGxp bWl0IGltcG9zZWQgYnkgdmFyaWFibGVzIHdlJ3JlIHVzaW5nICh1NjQgZm9yIGRpbW1fbWFzayBh bmQgdTMyIGZvcgo+IGNoYW5fcmFua19lbXB0eSkuCj4gCgpQbGVhc2UgdXNlIGEgdmFsdWUgZGVy aXZlZCBmcm9tIHRoZSBzaXplIG9mIHRob3NlIHZhcmlhYmxlcyBmb3IgdGhlIGNoZWNrCnRvIGNs YXJpZnkgYW5kIGV4cGxhaW4gdGhlIGNvbnN0cmFpbnRzLgoKVGhhbmtzLApHdWVudGVyCgpfX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2Vy bmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0 cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVs Cg==