Message ID | 20221018-up-i350-thermal-bringup-v6-4-c87b9f75550b@baylibre.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp367344wrs; Wed, 19 Oct 2022 07:46:51 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7GuBAKw7szGK3OwNpQHOMaOzS++6kV2pp9A4lsUCs5C2lTp79jvfqrcuk6A6CbaoJ3/6bt X-Received: by 2002:a17:907:320a:b0:741:72ee:8f3 with SMTP id xg10-20020a170907320a00b0074172ee08f3mr7154970ejb.168.1666190811584; Wed, 19 Oct 2022 07:46:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666190811; cv=none; d=google.com; s=arc-20160816; b=XtneLsNJktkV78bdLTpdULedO1YUbOT2wtsbXVCyIfkmzeI7XMzp1ax3zvV5DhFfto hSV59fHIffyD0hOC0s1rALaU3xvQ3i9tn2WhSjcG9cm/u7f7Nt4k3uZO9fZWByPN3jZH fx2DzdCmdlWwbEV0DyTqqg2yESJWhCgnh3Yc44dYNxQmwgOMiZp8qn+8XI22ogtr0uDv hjfq+WDcoBSrhyXWijUhugQ+nNfSbDHHncfzBIBy3+2afHu1HK/lXP6xab5Z+4gGppF8 F3P9sgJrjaedkY8sxMmrwcACUQzHZaRn4JxxO5ZkUjd8hzrFKibWUCeTGfBcef5riE5/ xAgw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:in-reply-to:references:message-id :content-transfer-encoding:mime-version:subject:date:from :dkim-signature; bh=r1PrDZfmYougOsxckNxrQ+xzuB0k8iiqOh0Bd1vtSCc=; b=eW3UwZwiIQz99GqAXKH5aEWn5FuYnAWizR0ZWf6ieG7Ogj6AuTejXvQcRjRnv/oxSZ kduaePlNpLXv99x2B0qZGEwFjv4e+hJ6XEPwszs0I1HyKPXykbIoILMcJWURyUK5lOKP 7OLN/h+4DeJFPvlmg8rGPvaka2iyxoIyW900wWYfQ9WLYrPtB3u/s/uetng34Z5j5LHd n84iQiEEJaOpaYor8WP10WPudkUcYfZu/IxLtz//rJLkcaWu21JIPjwf07mo4sT1oM/k 8Cq+ROetKV0GipRFyzaYz/TGfBkQ1mp/PPm3GdUHPasQ/3MDa70QGYCMBFA7rbVK4R7c irew== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baylibre-com.20210112.gappssmtp.com header.s=20210112 header.b=crf2NXyI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id d15-20020a05640208cf00b0045895823388si13037523edz.87.2022.10.19.07.46.25; Wed, 19 Oct 2022 07:46:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@baylibre-com.20210112.gappssmtp.com header.s=20210112 header.b=crf2NXyI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230055AbiJSOeQ (ORCPT <rfc822;samuel.l.nystrom@gmail.com> + 99 others); Wed, 19 Oct 2022 10:34:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230335AbiJSOda (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 19 Oct 2022 10:33:30 -0400 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2DBD81DB261 for <linux-kernel@vger.kernel.org>; Wed, 19 Oct 2022 07:18:13 -0700 (PDT) Received: by mail-wr1-x436.google.com with SMTP id bu30so29382337wrb.8 for <linux-kernel@vger.kernel.org>; Wed, 19 Oct 2022 07:18:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=r1PrDZfmYougOsxckNxrQ+xzuB0k8iiqOh0Bd1vtSCc=; b=crf2NXyIHNERe/g40V/74dQ2TcrFy04yDb7Z6j173hLda7PrrzE8Hog47MMmX38b4I p+zvmiYQQY8f1OT4DZgszfe3SlmHT/gf1p/cKhIeAWcjkV3Ae+uNN0gTIB2+J0/eEwkD +/gu52wzFP15Gj7k6hZzX3IcnualSrPnQNDugsgM+naSeSpPXre+epWpMkeGv2zWsPBs SfaL0lhBgHV6NDMAQ6t8UuRVKHJQEsn3rGu5ONutkqe5SdHaIKnQopR/PbMblmW2y79y DwS5R9Xs4OZaqchL0hTwDHv5Oi8/bHDHq5yaZcTQgrISf0ZF1Ee23vrwzk0fgZesuKJM OAHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=r1PrDZfmYougOsxckNxrQ+xzuB0k8iiqOh0Bd1vtSCc=; b=tiMgammSJNyQZdgfQxL6QvQse1eIVy3fEUnxVwuVNV0yBrU2A8GspOS7KAWHqgzQmt TsfgvzON42zrWUBt+cDoMv5ITGamipxOXUzYJx0b5UGZKD4iDvtSuSvLyQq4wPX44rw9 GSMu6TqGbPDF3zb7PpzN4jhIBmXucYuLW6hwMypMsg1gCfVOhOwQOnqr8w68NZ31BxbZ QWv5AA/nFNz8QF62YuWK+trKPcSjdx0z4G1QQjsMZg4arehOdrStPQYi2ABXgp/qf2rS DiBIexKp+Lc5F3m6i4/s6VqoBmNhm4KFvKTvItyA+XUSGVl7uosjh2yNCQMKDqjmb4iX /5SA== X-Gm-Message-State: ACrzQf3RBtwlwz1AJ0kwlgli2WO4fVd6gzIaW/npulBOy4po6/cAupaw ft1R82BmCCHYIi2LOy6eSGX+3Q== X-Received: by 2002:a5d:47c2:0:b0:22e:4911:6925 with SMTP id o2-20020a5d47c2000000b0022e49116925mr5339604wrc.403.1666189080951; Wed, 19 Oct 2022 07:18:00 -0700 (PDT) Received: from [127.0.1.1] (rtr.23.90.200.126.unyc.it. [23.90.200.126]) by smtp.googlemail.com with ESMTPSA id n9-20020a05600c3b8900b003b4ff30e566sm2126577wms.3.2022.10.19.07.18.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Oct 2022 07:18:00 -0700 (PDT) From: Amjad Ouled-Ameur <aouledameur@baylibre.com> Date: Wed, 19 Oct 2022 16:17:57 +0200 Subject: [PATCH v6 4/4] thermal: mediatek: add another get_temp ops for thermal sensors MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Message-Id: <20221018-up-i350-thermal-bringup-v6-4-c87b9f75550b@baylibre.com> References: <20221018-up-i350-thermal-bringup-v6-0-c87b9f75550b@baylibre.com> In-Reply-To: <20221018-up-i350-thermal-bringup-v6-0-c87b9f75550b@baylibre.com> To: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>, Zhang Rui <rui.zhang@intel.com>, Amit Kucheria <amitk@kernel.org>, Rob Herring <robh+dt@kernel.org>, "Rafael J. Wysocki" <rafael@kernel.org>, Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Fabien Parent <fparent@baylibre.com>, linux-mediatek@lists.infradead.org, Rob Herring <robh@kernel.org>, Markus Schneider-Pargmann <msp@baylibre.com>, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>, Michael Kao <michael.kao@mediatek.com>, Hsin-Yi Wang <hsinyi@chromium.org>, Amjad Ouled-Ameur <aouledameur@baylibre.com>, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Matthias Brugger <matthias.bgg@gmail.com> X-Mailer: b4 0.10.1 X-Developer-Signature: v=1; a=ed25519-sha256; t=1666189076; l=5964; i=aouledameur@baylibre.com; s=20220920; h=from:subject:message-id; bh=PvZXnHsGezp4LZF6C3Dyxbe0D+0mUeauPzu2u+WwTJc=; b=mN12SgEKRbCMQ8J43HF0rMCxcYPMfYBZmq1IrycQ0tHL/y41ovLGQ3dNTGgXY8s8Q9yZ+3awDmcB 2AdC/id3A6pdrLQwfJbcFda3VLuZY4sTB5+Q7cxgdtso+O8UzYwJ X-Developer-Key: i=aouledameur@baylibre.com; a=ed25519; pk=HgYWawSL4qLGPx+RzJ+Cuu+V8Pi/KQnDDm1wjWPMOFE= X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747127696067633514?= X-GMAIL-MSGID: =?utf-8?q?1747127696067633514?= |
Series |
thermal: mediatek: Add support for MT8365 SoC
|
|
Commit Message
Amjad Ouled-Ameur
Oct. 19, 2022, 2:17 p.m. UTC
Provide thermal zone to read thermal sensor in the SoC. We can read all the thermal sensors value in the SoC by the node /sys/class/thermal/ In mtk_thermal_bank_temperature, return -EAGAIN instead of -EACCESS on the first read of sensor that often are bogus values. This can avoid following warning on boot: thermal thermal_zone6: failed to read out thermal zone (-13) Signed-off-by: Michael Kao <michael.kao@mediatek.com> Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org> Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> --- drivers/thermal/mtk_thermal.c | 104 ++++++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 25 deletions(-)
Comments
On 19/10/2022 16:17, Amjad Ouled-Ameur wrote: > Provide thermal zone to read thermal sensor in the SoC. We can read all the > thermal sensors value in the SoC by the node /sys/class/thermal/ > > In mtk_thermal_bank_temperature, return -EAGAIN instead of -EACCESS > on the first read of sensor that often are bogus values. > This can avoid following warning on boot: > > thermal thermal_zone6: failed to read out thermal zone (-13) > > Signed-off-by: Michael Kao <michael.kao@mediatek.com> > Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org> > Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com> > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Overall the series looks good to me, however there is a couple of things to fix. See below > --- > drivers/thermal/mtk_thermal.c | 104 ++++++++++++++++++++++++++++++++---------- > 1 file changed, 79 insertions(+), 25 deletions(-) > > diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c > index 3a5df1440822..311ad611fdab 100644 > --- a/drivers/thermal/mtk_thermal.c > +++ b/drivers/thermal/mtk_thermal.c > @@ -259,6 +259,11 @@ enum mtk_thermal_version { > > struct mtk_thermal; > > +struct mtk_thermal_zone { > + struct mtk_thermal *mt; > + int id; > +}; Do you really need to create a new structure for that ? > struct thermal_bank_cfg { > unsigned int num_sensors; > const int *sensors; > @@ -307,6 +312,8 @@ struct mtk_thermal { > > const struct mtk_thermal_data *conf; > struct mtk_thermal_bank banks[MAX_NUM_ZONES]; > + > + int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw); > }; > > /* MT8183 thermal sensor data */ > @@ -709,6 +716,29 @@ static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank) > mutex_unlock(&mt->lock); > } > > +static int _get_sensor_temp(struct mtk_thermal *mt, int id) > +{ > + u32 raw; > + int temp; > + > + const struct mtk_thermal_data *conf = mt->conf; > + > + raw = readl(mt->thermal_base + conf->msr[id]); > + > + temp = mt->raw_to_mcelsius(mt, id, raw); > + > + /* > + * The first read of a sensor often contains very high bogus > + * temperature value. Filter these out so that the system does > + * not immediately shut down. > + */ > + > + if (temp > 200000) > + return -EAGAIN; > + else > + return temp; > +} > + > /** > * mtk_thermal_bank_temperature - get the temperature of a bank > * @bank: The bank > @@ -721,26 +751,9 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) > struct mtk_thermal *mt = bank->mt; > const struct mtk_thermal_data *conf = mt->conf; > int i, temp = INT_MIN, max = INT_MIN; > - u32 raw; > > for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) { > - raw = readl(mt->thermal_base + conf->msr[i]); > - > - if (mt->conf->version == MTK_THERMAL_V1) { > - temp = raw_to_mcelsius_v1( > - mt, conf->bank_data[bank->id].sensors[i], raw); > - } else { > - temp = raw_to_mcelsius_v2( > - mt, conf->bank_data[bank->id].sensors[i], raw); > - } > - > - /* > - * The first read of a sensor often contains very high bogus > - * temperature value. Filter these out so that the system does > - * not immediately shut down. > - */ > - if (temp > 200000) > - temp = 0; > + temp = _get_sensor_temp(mt, i); > > if (temp > max) > max = temp; > @@ -749,9 +762,10 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) > return max; > } > > -static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) > +static int mtk_read_temp(struct thermal_zone_device *tzdev, int *temperature) > { > - struct mtk_thermal *mt = tz->devdata; > + struct mtk_thermal_zone *tz = tzdev->devdata; > + struct mtk_thermal *mt = tz->mt; > int i; > int tempmax = INT_MIN; > > @@ -770,10 +784,28 @@ static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) > return 0; > } > > +static int mtk_read_sensor_temp(struct thermal_zone_device *tzdev, int *temperature) > +{ > + struct mtk_thermal_zone *tz = tzdev->devdata; > + struct mtk_thermal *mt = tz->mt; > + int id = tz->id - 1; > + > + if (id < 0) > + return -EACCES; > + > + *temperature = _get_sensor_temp(mt, id); > + > + return 0; > +} > + > static const struct thermal_zone_device_ops mtk_thermal_ops = { > .get_temp = mtk_read_temp, > }; > > +static const struct thermal_zone_device_ops mtk_thermal_sensor_ops = { > + .get_temp = mtk_read_sensor_temp, > +}; > + > static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num, > u32 apmixed_phys_base, u32 auxadc_phys_base, > int ctrl_id) > @@ -1072,6 +1104,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) > u64 auxadc_phys_base, apmixed_phys_base; > struct thermal_zone_device *tzdev; > void __iomem *apmixed_base, *auxadc_base; > + struct mtk_thermal_zone *tz; > > mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); > if (!mt) > @@ -1150,6 +1183,9 @@ static int mtk_thermal_probe(struct platform_device *pdev) > > mtk_thermal_turn_on_buffer(mt, apmixed_base); > > + mt->raw_to_mcelsius = (mt->conf->version == MTK_THERMAL_V1) ? > + raw_to_mcelsius_v1 : raw_to_mcelsius_v2; > + > if (mt->conf->version == MTK_THERMAL_V2) { > mtk_thermal_release_periodic_ts(mt, auxadc_base); > } > @@ -1161,11 +1197,29 @@ static int mtk_thermal_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, mt); > > - tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt, > - &mtk_thermal_ops); > - if (IS_ERR(tzdev)) { > - ret = PTR_ERR(tzdev); > - goto err_disable_clk_peri_therm; > + for (i = 0; i < mt->conf->num_sensors + 1; i++) { > + tz = devm_kmalloc(&pdev->dev, sizeof(*tz), GFP_KERNEL); > + if (!tz) > + return -ENOMEM; > + > + tz->mt = mt; > + tz->id = i; > + > + tzdev = devm_thermal_of_zone_register(&pdev->dev, i, tz, (i == 0) ? > + &mtk_thermal_ops : > + &mtk_thermal_sensor_ops); We want to prevent the aggregation from the different sensors within a driver. I know there is already a function doing that for the previous sensor version but that is something we don't want to continue. Using mtk_thermal_ops tries to overcome this. Also, the userspace needs to know to which device a thermal zone is related to. Here all the thermal zones have the same name so the userspace does not know if it is the GPU, the CPU, the chassis, the NPU, ... > + > + if (IS_ERR(tzdev)) { > + if (PTR_ERR(tzdev) == -ENODEV) { > + dev_warn(&pdev->dev, > + "sensor %d not registered in thermal zone in dt\n", i); ENODEV is not considered an error, so the warning can be removed > + continue; > + } > + if (PTR_ERR(tzdev) == -EACCES) { When devm_thermal_of_zone_register() returns -EACCES ? > + ret = PTR_ERR(tzdev); > + goto err_disable_clk_peri_therm; > + } > + } > } > > ret = devm_thermal_add_hwmon_sysfs(tzdev); >
Hi Daniel, Thank you for the review. On 10/22/22 19:03, Daniel Lezcano wrote: > On 19/10/2022 16:17, Amjad Ouled-Ameur wrote: >> Provide thermal zone to read thermal sensor in the SoC. We can read all the >> thermal sensors value in the SoC by the node /sys/class/thermal/ >> >> In mtk_thermal_bank_temperature, return -EAGAIN instead of -EACCESS >> on the first read of sensor that often are bogus values. >> This can avoid following warning on boot: >> >> thermal thermal_zone6: failed to read out thermal zone (-13) >> >> Signed-off-by: Michael Kao <michael.kao@mediatek.com> >> Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org> >> Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com> >> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > > Overall the series looks good to me, however there is a couple of things to fix. See below > >> --- >> drivers/thermal/mtk_thermal.c | 104 ++++++++++++++++++++++++++++++++---------- >> 1 file changed, 79 insertions(+), 25 deletions(-) >> >> diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c >> index 3a5df1440822..311ad611fdab 100644 >> --- a/drivers/thermal/mtk_thermal.c >> +++ b/drivers/thermal/mtk_thermal.c >> @@ -259,6 +259,11 @@ enum mtk_thermal_version { >> struct mtk_thermal; >> +struct mtk_thermal_zone { >> + struct mtk_thermal *mt; >> + int id; >> +}; > > Do you really need to create a new structure for that ? We need to store the sensor index in the private data, along with mtk_thermal. Aside from having this new structure, I don't see how .get_temp() can tell which sensor index to read. > >> struct thermal_bank_cfg { >> unsigned int num_sensors; >> const int *sensors; >> @@ -307,6 +312,8 @@ struct mtk_thermal { >> const struct mtk_thermal_data *conf; >> struct mtk_thermal_bank banks[MAX_NUM_ZONES]; >> + >> + int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw); >> }; >> /* MT8183 thermal sensor data */ >> @@ -709,6 +716,29 @@ static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank) >> mutex_unlock(&mt->lock); >> } >> +static int _get_sensor_temp(struct mtk_thermal *mt, int id) >> +{ >> + u32 raw; >> + int temp; >> + >> + const struct mtk_thermal_data *conf = mt->conf; >> + >> + raw = readl(mt->thermal_base + conf->msr[id]); >> + >> + temp = mt->raw_to_mcelsius(mt, id, raw); >> + >> + /* >> + * The first read of a sensor often contains very high bogus >> + * temperature value. Filter these out so that the system does >> + * not immediately shut down. >> + */ >> + >> + if (temp > 200000) >> + return -EAGAIN; >> + else >> + return temp; >> +} >> + >> /** >> * mtk_thermal_bank_temperature - get the temperature of a bank >> * @bank: The bank >> @@ -721,26 +751,9 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) >> struct mtk_thermal *mt = bank->mt; >> const struct mtk_thermal_data *conf = mt->conf; >> int i, temp = INT_MIN, max = INT_MIN; >> - u32 raw; >> for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) { >> - raw = readl(mt->thermal_base + conf->msr[i]); >> - >> - if (mt->conf->version == MTK_THERMAL_V1) { >> - temp = raw_to_mcelsius_v1( >> - mt, conf->bank_data[bank->id].sensors[i], raw); >> - } else { >> - temp = raw_to_mcelsius_v2( >> - mt, conf->bank_data[bank->id].sensors[i], raw); >> - } >> - >> - /* >> - * The first read of a sensor often contains very high bogus >> - * temperature value. Filter these out so that the system does >> - * not immediately shut down. >> - */ >> - if (temp > 200000) >> - temp = 0; >> + temp = _get_sensor_temp(mt, i); >> if (temp > max) >> max = temp; >> @@ -749,9 +762,10 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) >> return max; >> } >> -static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) >> +static int mtk_read_temp(struct thermal_zone_device *tzdev, int *temperature) >> { >> - struct mtk_thermal *mt = tz->devdata; >> + struct mtk_thermal_zone *tz = tzdev->devdata; >> + struct mtk_thermal *mt = tz->mt; >> int i; >> int tempmax = INT_MIN; >> @@ -770,10 +784,28 @@ static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) >> return 0; >> } >> +static int mtk_read_sensor_temp(struct thermal_zone_device *tzdev, int *temperature) >> +{ >> + struct mtk_thermal_zone *tz = tzdev->devdata; >> + struct mtk_thermal *mt = tz->mt; >> + int id = tz->id - 1; >> + >> + if (id < 0) >> + return -EACCES; >> + >> + *temperature = _get_sensor_temp(mt, id); >> + >> + return 0; >> +} >> + >> static const struct thermal_zone_device_ops mtk_thermal_ops = { >> .get_temp = mtk_read_temp, >> }; >> +static const struct thermal_zone_device_ops mtk_thermal_sensor_ops = { >> + .get_temp = mtk_read_sensor_temp, >> +}; >> + >> static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num, >> u32 apmixed_phys_base, u32 auxadc_phys_base, >> int ctrl_id) >> @@ -1072,6 +1104,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) >> u64 auxadc_phys_base, apmixed_phys_base; >> struct thermal_zone_device *tzdev; >> void __iomem *apmixed_base, *auxadc_base; >> + struct mtk_thermal_zone *tz; >> mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); >> if (!mt) >> @@ -1150,6 +1183,9 @@ static int mtk_thermal_probe(struct platform_device *pdev) >> mtk_thermal_turn_on_buffer(mt, apmixed_base); >> + mt->raw_to_mcelsius = (mt->conf->version == MTK_THERMAL_V1) ? >> + raw_to_mcelsius_v1 : raw_to_mcelsius_v2; >> + >> if (mt->conf->version == MTK_THERMAL_V2) { >> mtk_thermal_release_periodic_ts(mt, auxadc_base); >> } >> @@ -1161,11 +1197,29 @@ static int mtk_thermal_probe(struct platform_device *pdev) >> platform_set_drvdata(pdev, mt); >> - tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt, >> - &mtk_thermal_ops); >> - if (IS_ERR(tzdev)) { >> - ret = PTR_ERR(tzdev); >> - goto err_disable_clk_peri_therm; >> + for (i = 0; i < mt->conf->num_sensors + 1; i++) { >> + tz = devm_kmalloc(&pdev->dev, sizeof(*tz), GFP_KERNEL); >> + if (!tz) >> + return -ENOMEM; >> + >> + tz->mt = mt; >> + tz->id = i; >> + >> + tzdev = devm_thermal_of_zone_register(&pdev->dev, i, tz, (i == 0) ? >> + &mtk_thermal_ops : >> + &mtk_thermal_sensor_ops); > > We want to prevent the aggregation from the different sensors within a driver. I know there is already a function doing that for the previous sensor version but that is something we don't want to continue. > > Using mtk_thermal_ops tries to overcome this. > So would it be more proper to have to distinct thermal drivers for each sensor ? Or relatively to the above implementation, I think it might be better to have only one thermal_zone_device_ops, with storing the right get_temp callback in mtk_thermal_zone structure. > Also, the userspace needs to know to which device a thermal zone is related to. Here all the thermal zones have the same name so the userspace does not know if it is the GPU, the CPU, the chassis, the NPU, ... Which names are you referring to ? In case it is "sys/class/thermal/*/type", it is based on DT thermal nodes, the first sensor is marked as CPU-related, The others are used for debugging purposes only. > > >> + >> + if (IS_ERR(tzdev)) { >> + if (PTR_ERR(tzdev) == -ENODEV) { >> + dev_warn(&pdev->dev, >> + "sensor %d not registered in thermal zone in dt\n", i); > > ENODEV is not considered an error, so the warning can be removed Agreed, will drop this. > >> + continue; >> + } >> + if (PTR_ERR(tzdev) == -EACCES) { > > When devm_thermal_of_zone_register() returns -EACCES ? Right, I verified the code, -EACCES is never returned by devm_thermal_of_zone_register(). Regards, Amjad > >> + ret = PTR_ERR(tzdev); >> + goto err_disable_clk_peri_therm; >> + } >> + } >> } >> ret = devm_thermal_add_hwmon_sysfs(tzdev); >> >
Hi Daniel, Do you have any feedback about my comments on your review before I send V7 ? Regards, Amjad On 11/3/22 15:26, Amjad Ouled-Ameur wrote: > Hi Daniel, > > Thank you for the review. > > On 10/22/22 19:03, Daniel Lezcano wrote: >> On 19/10/2022 16:17, Amjad Ouled-Ameur wrote: >>> Provide thermal zone to read thermal sensor in the SoC. We can read all the >>> thermal sensors value in the SoC by the node /sys/class/thermal/ >>> >>> In mtk_thermal_bank_temperature, return -EAGAIN instead of -EACCESS >>> on the first read of sensor that often are bogus values. >>> This can avoid following warning on boot: >>> >>> thermal thermal_zone6: failed to read out thermal zone (-13) >>> >>> Signed-off-by: Michael Kao <michael.kao@mediatek.com> >>> Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org> >>> Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com> >>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> >> >> Overall the series looks good to me, however there is a couple of things to fix. See below >> >>> --- >>> drivers/thermal/mtk_thermal.c | 104 ++++++++++++++++++++++++++++++++---------- >>> 1 file changed, 79 insertions(+), 25 deletions(-) >>> >>> diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c >>> index 3a5df1440822..311ad611fdab 100644 >>> --- a/drivers/thermal/mtk_thermal.c >>> +++ b/drivers/thermal/mtk_thermal.c >>> @@ -259,6 +259,11 @@ enum mtk_thermal_version { >>> struct mtk_thermal; >>> +struct mtk_thermal_zone { >>> + struct mtk_thermal *mt; >>> + int id; >>> +}; >> >> Do you really need to create a new structure for that ? > > We need to store the sensor index in the private data, along with mtk_thermal. > > Aside from having this new structure, I don't see how .get_temp() can tell which > > sensor index to read. > >> >>> struct thermal_bank_cfg { >>> unsigned int num_sensors; >>> const int *sensors; >>> @@ -307,6 +312,8 @@ struct mtk_thermal { >>> const struct mtk_thermal_data *conf; >>> struct mtk_thermal_bank banks[MAX_NUM_ZONES]; >>> + >>> + int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw); >>> }; >>> /* MT8183 thermal sensor data */ >>> @@ -709,6 +716,29 @@ static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank) >>> mutex_unlock(&mt->lock); >>> } >>> +static int _get_sensor_temp(struct mtk_thermal *mt, int id) >>> +{ >>> + u32 raw; >>> + int temp; >>> + >>> + const struct mtk_thermal_data *conf = mt->conf; >>> + >>> + raw = readl(mt->thermal_base + conf->msr[id]); >>> + >>> + temp = mt->raw_to_mcelsius(mt, id, raw); >>> + >>> + /* >>> + * The first read of a sensor often contains very high bogus >>> + * temperature value. Filter these out so that the system does >>> + * not immediately shut down. >>> + */ >>> + >>> + if (temp > 200000) >>> + return -EAGAIN; >>> + else >>> + return temp; >>> +} >>> + >>> /** >>> * mtk_thermal_bank_temperature - get the temperature of a bank >>> * @bank: The bank >>> @@ -721,26 +751,9 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) >>> struct mtk_thermal *mt = bank->mt; >>> const struct mtk_thermal_data *conf = mt->conf; >>> int i, temp = INT_MIN, max = INT_MIN; >>> - u32 raw; >>> for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) { >>> - raw = readl(mt->thermal_base + conf->msr[i]); >>> - >>> - if (mt->conf->version == MTK_THERMAL_V1) { >>> - temp = raw_to_mcelsius_v1( >>> - mt, conf->bank_data[bank->id].sensors[i], raw); >>> - } else { >>> - temp = raw_to_mcelsius_v2( >>> - mt, conf->bank_data[bank->id].sensors[i], raw); >>> - } >>> - >>> - /* >>> - * The first read of a sensor often contains very high bogus >>> - * temperature value. Filter these out so that the system does >>> - * not immediately shut down. >>> - */ >>> - if (temp > 200000) >>> - temp = 0; >>> + temp = _get_sensor_temp(mt, i); >>> if (temp > max) >>> max = temp; >>> @@ -749,9 +762,10 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) >>> return max; >>> } >>> -static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) >>> +static int mtk_read_temp(struct thermal_zone_device *tzdev, int *temperature) >>> { >>> - struct mtk_thermal *mt = tz->devdata; >>> + struct mtk_thermal_zone *tz = tzdev->devdata; >>> + struct mtk_thermal *mt = tz->mt; >>> int i; >>> int tempmax = INT_MIN; >>> @@ -770,10 +784,28 @@ static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) >>> return 0; >>> } >>> +static int mtk_read_sensor_temp(struct thermal_zone_device *tzdev, int *temperature) >>> +{ >>> + struct mtk_thermal_zone *tz = tzdev->devdata; >>> + struct mtk_thermal *mt = tz->mt; >>> + int id = tz->id - 1; >>> + >>> + if (id < 0) >>> + return -EACCES; >>> + >>> + *temperature = _get_sensor_temp(mt, id); >>> + >>> + return 0; >>> +} >>> + >>> static const struct thermal_zone_device_ops mtk_thermal_ops = { >>> .get_temp = mtk_read_temp, >>> }; >>> +static const struct thermal_zone_device_ops mtk_thermal_sensor_ops = { >>> + .get_temp = mtk_read_sensor_temp, >>> +}; >>> + >>> static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num, >>> u32 apmixed_phys_base, u32 auxadc_phys_base, >>> int ctrl_id) >>> @@ -1072,6 +1104,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) >>> u64 auxadc_phys_base, apmixed_phys_base; >>> struct thermal_zone_device *tzdev; >>> void __iomem *apmixed_base, *auxadc_base; >>> + struct mtk_thermal_zone *tz; >>> mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); >>> if (!mt) >>> @@ -1150,6 +1183,9 @@ static int mtk_thermal_probe(struct platform_device *pdev) >>> mtk_thermal_turn_on_buffer(mt, apmixed_base); >>> + mt->raw_to_mcelsius = (mt->conf->version == MTK_THERMAL_V1) ? >>> + raw_to_mcelsius_v1 : raw_to_mcelsius_v2; >>> + >>> if (mt->conf->version == MTK_THERMAL_V2) { >>> mtk_thermal_release_periodic_ts(mt, auxadc_base); >>> } >>> @@ -1161,11 +1197,29 @@ static int mtk_thermal_probe(struct platform_device *pdev) >>> platform_set_drvdata(pdev, mt); >>> - tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt, >>> - &mtk_thermal_ops); >>> - if (IS_ERR(tzdev)) { >>> - ret = PTR_ERR(tzdev); >>> - goto err_disable_clk_peri_therm; >>> + for (i = 0; i < mt->conf->num_sensors + 1; i++) { >>> + tz = devm_kmalloc(&pdev->dev, sizeof(*tz), GFP_KERNEL); >>> + if (!tz) >>> + return -ENOMEM; >>> + >>> + tz->mt = mt; >>> + tz->id = i; >>> + >>> + tzdev = devm_thermal_of_zone_register(&pdev->dev, i, tz, (i == 0) ? >>> + &mtk_thermal_ops : >>> + &mtk_thermal_sensor_ops); >> >> We want to prevent the aggregation from the different sensors within a driver. I know there is already a function doing that for the previous sensor version but that is something we don't want to continue. >> >> Using mtk_thermal_ops tries to overcome this. >> > So would it be more proper to have to distinct thermal drivers for each sensor ? Or relatively to the above implementation, > > I think it might be better to have only one thermal_zone_device_ops, with storing the right get_temp callback in mtk_thermal_zone structure. > > >> Also, the userspace needs to know to which device a thermal zone is related to. Here all the thermal zones have the same name so the userspace does not know if it is the GPU, the CPU, the chassis, the NPU, ... > > Which names are you referring to ? In case it is "sys/class/thermal/*/type", it is based on DT thermal nodes, the first sensor is marked as CPU-related, > > The others are used for debugging purposes only. > >> >> >>> + >>> + if (IS_ERR(tzdev)) { >>> + if (PTR_ERR(tzdev) == -ENODEV) { >>> + dev_warn(&pdev->dev, >>> + "sensor %d not registered in thermal zone in dt\n", i); >> >> ENODEV is not considered an error, so the warning can be removed > Agreed, will drop this. >> >>> + continue; >>> + } >>> + if (PTR_ERR(tzdev) == -EACCES) { >> >> When devm_thermal_of_zone_register() returns -EACCES ? > > Right, I verified the code, -EACCES is never returned by devm_thermal_of_zone_register(). > > > Regards, > > Amjad > >> >>> + ret = PTR_ERR(tzdev); >>> + goto err_disable_clk_peri_therm; >>> + } >>> + } >>> } >>> ret = devm_thermal_add_hwmon_sysfs(tzdev); >>> >>
Hi Amjad, On Wed, Oct 19, 2022 at 10:17 PM Amjad Ouled-Ameur <aouledameur@baylibre.com> wrote: > > Provide thermal zone to read thermal sensor in the SoC. We can read all the > thermal sensors value in the SoC by the node /sys/class/thermal/ > > In mtk_thermal_bank_temperature, return -EAGAIN instead of -EACCESS > on the first read of sensor that often are bogus values. > This can avoid following warning on boot: > > thermal thermal_zone6: failed to read out thermal zone (-13) > > Signed-off-by: Michael Kao <michael.kao@mediatek.com> > Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org> > Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com> > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> > --- > drivers/thermal/mtk_thermal.c | 104 ++++++++++++++++++++++++++++++++---------- > 1 file changed, 79 insertions(+), 25 deletions(-) > > diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c > index 3a5df1440822..311ad611fdab 100644 > --- a/drivers/thermal/mtk_thermal.c > +++ b/drivers/thermal/mtk_thermal.c > @@ -259,6 +259,11 @@ enum mtk_thermal_version { > > struct mtk_thermal; > > +struct mtk_thermal_zone { > + struct mtk_thermal *mt; > + int id; > +}; > + > struct thermal_bank_cfg { > unsigned int num_sensors; > const int *sensors; > @@ -307,6 +312,8 @@ struct mtk_thermal { > > const struct mtk_thermal_data *conf; > struct mtk_thermal_bank banks[MAX_NUM_ZONES]; > + > + int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw); > }; > > /* MT8183 thermal sensor data */ > @@ -709,6 +716,29 @@ static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank) > mutex_unlock(&mt->lock); > } > > +static int _get_sensor_temp(struct mtk_thermal *mt, int id) > +{ > + u32 raw; > + int temp; > + > + const struct mtk_thermal_data *conf = mt->conf; > + > + raw = readl(mt->thermal_base + conf->msr[id]); > + > + temp = mt->raw_to_mcelsius(mt, id, raw); > + > + /* > + * The first read of a sensor often contains very high bogus > + * temperature value. Filter these out so that the system does > + * not immediately shut down. > + */ > + > + if (temp > 200000) > + return -EAGAIN; > + else > + return temp; > +} > + > /** > * mtk_thermal_bank_temperature - get the temperature of a bank > * @bank: The bank > @@ -721,26 +751,9 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) > struct mtk_thermal *mt = bank->mt; > const struct mtk_thermal_data *conf = mt->conf; > int i, temp = INT_MIN, max = INT_MIN; > - u32 raw; > > for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) { > - raw = readl(mt->thermal_base + conf->msr[i]); > - > - if (mt->conf->version == MTK_THERMAL_V1) { > - temp = raw_to_mcelsius_v1( > - mt, conf->bank_data[bank->id].sensors[i], raw); > - } else { > - temp = raw_to_mcelsius_v2( > - mt, conf->bank_data[bank->id].sensors[i], raw); > - } > - > - /* > - * The first read of a sensor often contains very high bogus > - * temperature value. Filter these out so that the system does > - * not immediately shut down. > - */ > - if (temp > 200000) > - temp = 0; > + temp = _get_sensor_temp(mt, i); > > if (temp > max) > max = temp; > @@ -749,9 +762,10 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) > return max; > } > > -static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) > +static int mtk_read_temp(struct thermal_zone_device *tzdev, int *temperature) > { > - struct mtk_thermal *mt = tz->devdata; > + struct mtk_thermal_zone *tz = tzdev->devdata; > + struct mtk_thermal *mt = tz->mt; > int i; > int tempmax = INT_MIN; > > @@ -770,10 +784,28 @@ static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) > return 0; > } > > +static int mtk_read_sensor_temp(struct thermal_zone_device *tzdev, int *temperature) > +{ > + struct mtk_thermal_zone *tz = tzdev->devdata; > + struct mtk_thermal *mt = tz->mt; > + int id = tz->id - 1; > + > + if (id < 0) > + return -EACCES; > + > + *temperature = _get_sensor_temp(mt, id); > + > + return 0; > +} > + > static const struct thermal_zone_device_ops mtk_thermal_ops = { > .get_temp = mtk_read_temp, > }; > > +static const struct thermal_zone_device_ops mtk_thermal_sensor_ops = { > + .get_temp = mtk_read_sensor_temp, > +}; > + > static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num, > u32 apmixed_phys_base, u32 auxadc_phys_base, > int ctrl_id) > @@ -1072,6 +1104,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) > u64 auxadc_phys_base, apmixed_phys_base; > struct thermal_zone_device *tzdev; > void __iomem *apmixed_base, *auxadc_base; > + struct mtk_thermal_zone *tz; > > mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); > if (!mt) > @@ -1150,6 +1183,9 @@ static int mtk_thermal_probe(struct platform_device *pdev) > > mtk_thermal_turn_on_buffer(mt, apmixed_base); > > + mt->raw_to_mcelsius = (mt->conf->version == MTK_THERMAL_V1) ? > + raw_to_mcelsius_v1 : raw_to_mcelsius_v2; > + > if (mt->conf->version == MTK_THERMAL_V2) { > mtk_thermal_release_periodic_ts(mt, auxadc_base); > } > @@ -1161,11 +1197,29 @@ static int mtk_thermal_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, mt); > > - tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt, > - &mtk_thermal_ops); > - if (IS_ERR(tzdev)) { > - ret = PTR_ERR(tzdev); > - goto err_disable_clk_peri_therm; > + for (i = 0; i < mt->conf->num_sensors + 1; i++) { > + tz = devm_kmalloc(&pdev->dev, sizeof(*tz), GFP_KERNEL); > + if (!tz) > + return -ENOMEM; > + > + tz->mt = mt; > + tz->id = i; > + > + tzdev = devm_thermal_of_zone_register(&pdev->dev, i, tz, (i == 0) ? > + &mtk_thermal_ops : > + &mtk_thermal_sensor_ops); > + > + if (IS_ERR(tzdev)) { > + if (PTR_ERR(tzdev) == -ENODEV) { > + dev_warn(&pdev->dev, > + "sensor %d not registered in thermal zone in dt\n", i); > + continue; > + } > + if (PTR_ERR(tzdev) == -EACCES) { > + ret = PTR_ERR(tzdev); > + goto err_disable_clk_peri_therm; > + } > + } > } > > ret = devm_thermal_add_hwmon_sysfs(tzdev); tzdev can be an error pointer here. I think we should move the line into the loop above, so hwmon sysfs is not added when IS_ERR(tzdev) == true. Regards, Pin-yen
Hi Pin-yen, On 11/15/22 11:49, Pin-yen Lin wrote: > Hi Amjad, > > On Wed, Oct 19, 2022 at 10:17 PM Amjad Ouled-Ameur > <aouledameur@baylibre.com> wrote: >> Provide thermal zone to read thermal sensor in the SoC. We can read all the >> thermal sensors value in the SoC by the node /sys/class/thermal/ >> >> In mtk_thermal_bank_temperature, return -EAGAIN instead of -EACCESS >> on the first read of sensor that often are bogus values. >> This can avoid following warning on boot: >> >> thermal thermal_zone6: failed to read out thermal zone (-13) >> >> Signed-off-by: Michael Kao <michael.kao@mediatek.com> >> Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org> >> Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com> >> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> >> --- >> drivers/thermal/mtk_thermal.c | 104 ++++++++++++++++++++++++++++++++---------- >> 1 file changed, 79 insertions(+), 25 deletions(-) >> >> diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c >> index 3a5df1440822..311ad611fdab 100644 >> --- a/drivers/thermal/mtk_thermal.c >> +++ b/drivers/thermal/mtk_thermal.c >> @@ -259,6 +259,11 @@ enum mtk_thermal_version { >> >> struct mtk_thermal; >> >> +struct mtk_thermal_zone { >> + struct mtk_thermal *mt; >> + int id; >> +}; >> + >> struct thermal_bank_cfg { >> unsigned int num_sensors; >> const int *sensors; >> @@ -307,6 +312,8 @@ struct mtk_thermal { >> >> const struct mtk_thermal_data *conf; >> struct mtk_thermal_bank banks[MAX_NUM_ZONES]; >> + >> + int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw); >> }; >> >> /* MT8183 thermal sensor data */ >> @@ -709,6 +716,29 @@ static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank) >> mutex_unlock(&mt->lock); >> } >> >> +static int _get_sensor_temp(struct mtk_thermal *mt, int id) >> +{ >> + u32 raw; >> + int temp; >> + >> + const struct mtk_thermal_data *conf = mt->conf; >> + >> + raw = readl(mt->thermal_base + conf->msr[id]); >> + >> + temp = mt->raw_to_mcelsius(mt, id, raw); >> + >> + /* >> + * The first read of a sensor often contains very high bogus >> + * temperature value. Filter these out so that the system does >> + * not immediately shut down. >> + */ >> + >> + if (temp > 200000) >> + return -EAGAIN; >> + else >> + return temp; >> +} >> + >> /** >> * mtk_thermal_bank_temperature - get the temperature of a bank >> * @bank: The bank >> @@ -721,26 +751,9 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) >> struct mtk_thermal *mt = bank->mt; >> const struct mtk_thermal_data *conf = mt->conf; >> int i, temp = INT_MIN, max = INT_MIN; >> - u32 raw; >> >> for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) { >> - raw = readl(mt->thermal_base + conf->msr[i]); >> - >> - if (mt->conf->version == MTK_THERMAL_V1) { >> - temp = raw_to_mcelsius_v1( >> - mt, conf->bank_data[bank->id].sensors[i], raw); >> - } else { >> - temp = raw_to_mcelsius_v2( >> - mt, conf->bank_data[bank->id].sensors[i], raw); >> - } >> - >> - /* >> - * The first read of a sensor often contains very high bogus >> - * temperature value. Filter these out so that the system does >> - * not immediately shut down. >> - */ >> - if (temp > 200000) >> - temp = 0; >> + temp = _get_sensor_temp(mt, i); >> >> if (temp > max) >> max = temp; >> @@ -749,9 +762,10 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) >> return max; >> } >> >> -static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) >> +static int mtk_read_temp(struct thermal_zone_device *tzdev, int *temperature) >> { >> - struct mtk_thermal *mt = tz->devdata; >> + struct mtk_thermal_zone *tz = tzdev->devdata; >> + struct mtk_thermal *mt = tz->mt; >> int i; >> int tempmax = INT_MIN; >> >> @@ -770,10 +784,28 @@ static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) >> return 0; >> } >> >> +static int mtk_read_sensor_temp(struct thermal_zone_device *tzdev, int *temperature) >> +{ >> + struct mtk_thermal_zone *tz = tzdev->devdata; >> + struct mtk_thermal *mt = tz->mt; >> + int id = tz->id - 1; >> + >> + if (id < 0) >> + return -EACCES; >> + >> + *temperature = _get_sensor_temp(mt, id); >> + >> + return 0; >> +} >> + >> static const struct thermal_zone_device_ops mtk_thermal_ops = { >> .get_temp = mtk_read_temp, >> }; >> >> +static const struct thermal_zone_device_ops mtk_thermal_sensor_ops = { >> + .get_temp = mtk_read_sensor_temp, >> +}; >> + >> static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num, >> u32 apmixed_phys_base, u32 auxadc_phys_base, >> int ctrl_id) >> @@ -1072,6 +1104,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) >> u64 auxadc_phys_base, apmixed_phys_base; >> struct thermal_zone_device *tzdev; >> void __iomem *apmixed_base, *auxadc_base; >> + struct mtk_thermal_zone *tz; >> >> mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); >> if (!mt) >> @@ -1150,6 +1183,9 @@ static int mtk_thermal_probe(struct platform_device *pdev) >> >> mtk_thermal_turn_on_buffer(mt, apmixed_base); >> >> + mt->raw_to_mcelsius = (mt->conf->version == MTK_THERMAL_V1) ? >> + raw_to_mcelsius_v1 : raw_to_mcelsius_v2; >> + >> if (mt->conf->version == MTK_THERMAL_V2) { >> mtk_thermal_release_periodic_ts(mt, auxadc_base); >> } >> @@ -1161,11 +1197,29 @@ static int mtk_thermal_probe(struct platform_device *pdev) >> >> platform_set_drvdata(pdev, mt); >> >> - tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt, >> - &mtk_thermal_ops); >> - if (IS_ERR(tzdev)) { >> - ret = PTR_ERR(tzdev); >> - goto err_disable_clk_peri_therm; >> + for (i = 0; i < mt->conf->num_sensors + 1; i++) { >> + tz = devm_kmalloc(&pdev->dev, sizeof(*tz), GFP_KERNEL); >> + if (!tz) >> + return -ENOMEM; >> + >> + tz->mt = mt; >> + tz->id = i; >> + >> + tzdev = devm_thermal_of_zone_register(&pdev->dev, i, tz, (i == 0) ? >> + &mtk_thermal_ops : >> + &mtk_thermal_sensor_ops); >> + >> + if (IS_ERR(tzdev)) { >> + if (PTR_ERR(tzdev) == -ENODEV) { >> + dev_warn(&pdev->dev, >> + "sensor %d not registered in thermal zone in dt\n", i); >> + continue; >> + } >> + if (PTR_ERR(tzdev) == -EACCES) { >> + ret = PTR_ERR(tzdev); >> + goto err_disable_clk_peri_therm; >> + } >> + } >> } >> >> ret = devm_thermal_add_hwmon_sysfs(tzdev); > tzdev can be an error pointer here. I think we should move the line > into the loop above, so hwmon sysfs is not added when IS_ERR(tzdev) == > true. Good catch, will fix this in next rev. Regards, Amjad > Regards, > Pin-yen
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 3a5df1440822..311ad611fdab 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -259,6 +259,11 @@ enum mtk_thermal_version { struct mtk_thermal; +struct mtk_thermal_zone { + struct mtk_thermal *mt; + int id; +}; + struct thermal_bank_cfg { unsigned int num_sensors; const int *sensors; @@ -307,6 +312,8 @@ struct mtk_thermal { const struct mtk_thermal_data *conf; struct mtk_thermal_bank banks[MAX_NUM_ZONES]; + + int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw); }; /* MT8183 thermal sensor data */ @@ -709,6 +716,29 @@ static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank) mutex_unlock(&mt->lock); } +static int _get_sensor_temp(struct mtk_thermal *mt, int id) +{ + u32 raw; + int temp; + + const struct mtk_thermal_data *conf = mt->conf; + + raw = readl(mt->thermal_base + conf->msr[id]); + + temp = mt->raw_to_mcelsius(mt, id, raw); + + /* + * The first read of a sensor often contains very high bogus + * temperature value. Filter these out so that the system does + * not immediately shut down. + */ + + if (temp > 200000) + return -EAGAIN; + else + return temp; +} + /** * mtk_thermal_bank_temperature - get the temperature of a bank * @bank: The bank @@ -721,26 +751,9 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) struct mtk_thermal *mt = bank->mt; const struct mtk_thermal_data *conf = mt->conf; int i, temp = INT_MIN, max = INT_MIN; - u32 raw; for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) { - raw = readl(mt->thermal_base + conf->msr[i]); - - if (mt->conf->version == MTK_THERMAL_V1) { - temp = raw_to_mcelsius_v1( - mt, conf->bank_data[bank->id].sensors[i], raw); - } else { - temp = raw_to_mcelsius_v2( - mt, conf->bank_data[bank->id].sensors[i], raw); - } - - /* - * The first read of a sensor often contains very high bogus - * temperature value. Filter these out so that the system does - * not immediately shut down. - */ - if (temp > 200000) - temp = 0; + temp = _get_sensor_temp(mt, i); if (temp > max) max = temp; @@ -749,9 +762,10 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) return max; } -static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) +static int mtk_read_temp(struct thermal_zone_device *tzdev, int *temperature) { - struct mtk_thermal *mt = tz->devdata; + struct mtk_thermal_zone *tz = tzdev->devdata; + struct mtk_thermal *mt = tz->mt; int i; int tempmax = INT_MIN; @@ -770,10 +784,28 @@ static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature) return 0; } +static int mtk_read_sensor_temp(struct thermal_zone_device *tzdev, int *temperature) +{ + struct mtk_thermal_zone *tz = tzdev->devdata; + struct mtk_thermal *mt = tz->mt; + int id = tz->id - 1; + + if (id < 0) + return -EACCES; + + *temperature = _get_sensor_temp(mt, id); + + return 0; +} + static const struct thermal_zone_device_ops mtk_thermal_ops = { .get_temp = mtk_read_temp, }; +static const struct thermal_zone_device_ops mtk_thermal_sensor_ops = { + .get_temp = mtk_read_sensor_temp, +}; + static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num, u32 apmixed_phys_base, u32 auxadc_phys_base, int ctrl_id) @@ -1072,6 +1104,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) u64 auxadc_phys_base, apmixed_phys_base; struct thermal_zone_device *tzdev; void __iomem *apmixed_base, *auxadc_base; + struct mtk_thermal_zone *tz; mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); if (!mt) @@ -1150,6 +1183,9 @@ static int mtk_thermal_probe(struct platform_device *pdev) mtk_thermal_turn_on_buffer(mt, apmixed_base); + mt->raw_to_mcelsius = (mt->conf->version == MTK_THERMAL_V1) ? + raw_to_mcelsius_v1 : raw_to_mcelsius_v2; + if (mt->conf->version == MTK_THERMAL_V2) { mtk_thermal_release_periodic_ts(mt, auxadc_base); } @@ -1161,11 +1197,29 @@ static int mtk_thermal_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mt); - tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt, - &mtk_thermal_ops); - if (IS_ERR(tzdev)) { - ret = PTR_ERR(tzdev); - goto err_disable_clk_peri_therm; + for (i = 0; i < mt->conf->num_sensors + 1; i++) { + tz = devm_kmalloc(&pdev->dev, sizeof(*tz), GFP_KERNEL); + if (!tz) + return -ENOMEM; + + tz->mt = mt; + tz->id = i; + + tzdev = devm_thermal_of_zone_register(&pdev->dev, i, tz, (i == 0) ? + &mtk_thermal_ops : + &mtk_thermal_sensor_ops); + + if (IS_ERR(tzdev)) { + if (PTR_ERR(tzdev) == -ENODEV) { + dev_warn(&pdev->dev, + "sensor %d not registered in thermal zone in dt\n", i); + continue; + } + if (PTR_ERR(tzdev) == -EACCES) { + ret = PTR_ERR(tzdev); + goto err_disable_clk_peri_therm; + } + } } ret = devm_thermal_add_hwmon_sysfs(tzdev);