From patchwork Fri Sep 20 21:52:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Kucheria X-Patchwork-Id: 174159 Delivered-To: patch@linaro.org Received: by 2002:a92:7e96:0:0:0:0:0 with SMTP id q22csp3031701ill; Fri, 20 Sep 2019 14:52:53 -0700 (PDT) X-Google-Smtp-Source: APXvYqzmGDRrwq9M4DR5YHsLBxKmFrLVgUd9a6ydg8365Nxq0tqQ9kaV91npZdAwbxVP44X6xkyi X-Received: by 2002:a05:6402:2cb:: with SMTP id b11mr24647788edx.285.1569016372895; Fri, 20 Sep 2019 14:52:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569016372; cv=none; d=google.com; s=arc-20160816; b=giSNKRboYWbtgUaC9yzJeEHcywsuq/9xsmtyfettttXUM/GHR/CnD1pw2B9PesBEAt 8ki77B36rXZosgzUNqOyGc3hhs4CIUoK4UOGr+IBm2eTuqdeNZ4OcxisDxIEXOt3iSKg V8FrX6+oFEajhWUqBg9PpNoDMjQhbF+dmroPpG0XJiinX/jH8ihySXddh9fVzPCYRICl yzJeKtoM7oO+YISDVhoXEb+pQTbW4/jfxc6eb+QqQC4R7ntU0jFTWA9+AV2wmXWE05hq UVf86PBumhX/GJZglVpjy9Xu/hdwQEBruzV3nRrOZ/TVL3j9sMWohKWSySQqiWe9FoKT zWBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=GhiEdPc2a74wJTsECxjn5PPZJWIyvNu4x7DC2dya90E=; b=luTq3KPV4Tm/bpLTqg1XhsCA2u8Eh5H0ca/6fcfIZIyC/NYR00cCnLFlImgjDE1Vbc dP2xB6Hu1rLAkW0Nm/dRkM/bYNpTTRcpcUelcM6j4OUm3OSOMPEjRNCuSxroWvjwlWuE bvPTB+q3+Hg0aBPyAydIP+gm7TNaaT9WgJtf71+zpQEE+elUAmCHOK13Px/XFFVGtBuh hY8VpJprRGIqEdxZyDXJlMls1CzoNkGRw+zLiUcPqq5ZNGVEounzsiGowN6QEcBqOUfF snYWzs6A4be+g77df8bEYzWUXEIWptX7yOO73bkahRFTETD/b8v0zBcu17V2LdiAmzAD C71g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UKLkJ3WY; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d17si2225527eda.213.2019.09.20.14.52.52; Fri, 20 Sep 2019 14:52:52 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UKLkJ3WY; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727684AbfITVwu (ORCPT + 15 others); Fri, 20 Sep 2019 17:52:50 -0400 Received: from mail-pl1-f194.google.com ([209.85.214.194]:44112 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727538AbfITVwu (ORCPT ); Fri, 20 Sep 2019 17:52:50 -0400 Received: by mail-pl1-f194.google.com with SMTP id q15so3783939pll.11 for ; Fri, 20 Sep 2019 14:52:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=GhiEdPc2a74wJTsECxjn5PPZJWIyvNu4x7DC2dya90E=; b=UKLkJ3WYsXhAlSM108Xru6zTxfGn7hTvCIUzDAgh9Vc2t6Sfma/G9QNdG/ssvEUVA4 nlVvBgGkIp9r+CwA4dwuCr3MK9B2sstK3BISpG/gc09UFkQX4QS0WE2N5rYW4OHOEpq+ fDjkVg7qEIEBPJ1ehuugfxHmSs4wZJ7tAo/k3xjwZpKP4VsXZau+9Kxlh/FEnSOuaH8p wCcJ5FdkDG3MMpDo9eItxPHELRp9Bjxw1Ag0VBaAeuCVDHgWLtlqngL0uPIhPeqFeaLy TL1QL+ZTM1eAYUwRTo+nP8zzFtCoFMjJmihxaPtGm+/q824Q4hxc5coYL3nCrEnOBMv8 IbqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=GhiEdPc2a74wJTsECxjn5PPZJWIyvNu4x7DC2dya90E=; b=KuFiH+RaqHrKYMCT8GrO2Kh8pNeg0lJpS/oCnujvVc7tUFle31TgMbE5hP9hSEqQGL TNAaEm5YTvSg8H1s1Lud+W6gvphb8oe+TXyAtaNhtU1OwCnW952/WVDzn8o1oXOMo5Mb PL+7Op16kdiTDSzrH09zNuR3AZU4fFGepZ3QR0/Jut1/9cCcmQgoCC2uRFePn5f2KY+1 U6wdnqw+QYQ+efGPj61ZsC/6HFGo1mP4Nf3exliKiHPhUzdJ42UU/1bhqJYqjf30SLml FL22snZio3167vm9UYV4rkUbWX8D9VVrdJYTGNcWEpUk6Fd0ZENNChz/3q8x4CF15NjZ YCjw== X-Gm-Message-State: APjAAAVFpuQi8TiLKTWWwJfcFD+8duHnnvtj/mGfJh9EPkxUeLCez4EI Li48Kx6YAQwMuN4w5ms2rQuIEg== X-Received: by 2002:a17:902:820f:: with SMTP id x15mr19893535pln.130.1569016369090; Fri, 20 Sep 2019 14:52:49 -0700 (PDT) Received: from localhost (wsip-98-175-107-49.sd.sd.cox.net. [98.175.107.49]) by smtp.gmail.com with ESMTPSA id r23sm2893785pjo.22.2019.09.20.14.52.48 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 20 Sep 2019 14:52:48 -0700 (PDT) From: Amit Kucheria To: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, bjorn.andersson@linaro.org, edubezval@gmail.com, agross@kernel.org, masneyb@onstation.org, swboyd@chromium.org, Daniel Lezcano , Mark Rutland , Rob Herring , Zhang Rui Cc: linux-pm@vger.kernel.org Subject: [PATCH v4 04/15] drivers: thermal: tsens: Add debugfs support Date: Fri, 20 Sep 2019 14:52:19 -0700 Message-Id: X-Mailer: git-send-email 2.17.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Dump some basic version info and sensor details into debugfs. Example from qcs404 below: --(/sys/kernel/debug) $ ls tsens/ 4a9000.thermal-sensor version --(/sys/kernel/debug) $ cat tsens/version 1.4.0 --(/sys/kernel/debug) $ cat tsens/4a9000.thermal-sensor/sensors max: 11 num: 10 id slope offset ------------------------ 0 3200 404000 1 3200 404000 2 3200 404000 3 3200 404000 4 3200 404000 5 3200 404000 6 3200 404000 7 3200 404000 8 3200 404000 9 3200 404000 Signed-off-by: Amit Kucheria Reviewed-by: Stephen Boyd --- drivers/thermal/qcom/tsens-common.c | 83 +++++++++++++++++++++++++++++ drivers/thermal/qcom/tsens.c | 2 + drivers/thermal/qcom/tsens.h | 6 +++ 3 files changed, 91 insertions(+) -- 2.17.1 diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c index 7437bfe196e5..ea2c46cc6a66 100644 --- a/drivers/thermal/qcom/tsens-common.c +++ b/drivers/thermal/qcom/tsens-common.c @@ -3,6 +3,7 @@ * Copyright (c) 2015, The Linux Foundation. All rights reserved. */ +#include #include #include #include @@ -139,6 +140,77 @@ int get_temp_common(struct tsens_sensor *s, int *temp) return 0; } +#ifdef CONFIG_DEBUG_FS +static int dbg_sensors_show(struct seq_file *s, void *data) +{ + struct platform_device *pdev = s->private; + struct tsens_priv *priv = platform_get_drvdata(pdev); + int i; + + seq_printf(s, "max: %2d\nnum: %2d\n\n", + priv->feat->max_sensors, priv->num_sensors); + + seq_puts(s, " id slope offset\n--------------------------\n"); + for (i = 0; i < priv->num_sensors; i++) { + seq_printf(s, "%8d %8d %8d\n", priv->sensor[i].hw_id, + priv->sensor[i].slope, priv->sensor[i].offset); + } + + return 0; +} + +static int dbg_version_show(struct seq_file *s, void *data) +{ + struct platform_device *pdev = s->private; + struct tsens_priv *priv = platform_get_drvdata(pdev); + u32 maj_ver, min_ver, step_ver; + int ret; + + if (tsens_ver(priv) > VER_0_1) { + ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver); + if (ret) + return ret; + ret = regmap_field_read(priv->rf[VER_MINOR], &min_ver); + if (ret) + return ret; + ret = regmap_field_read(priv->rf[VER_STEP], &step_ver); + if (ret) + return ret; + seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver); + } else { + seq_puts(s, "0.1.0\n"); + } + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(dbg_version); +DEFINE_SHOW_ATTRIBUTE(dbg_sensors); + +static void tsens_debug_init(struct platform_device *pdev) +{ + struct tsens_priv *priv = platform_get_drvdata(pdev); + struct dentry *root, *file; + + root = debugfs_lookup("tsens", NULL); + if (!root) + priv->debug_root = debugfs_create_dir("tsens", NULL); + else + priv->debug_root = root; + + file = debugfs_lookup("version", priv->debug_root); + if (!file) + debugfs_create_file("version", 0444, priv->debug_root, + pdev, &dbg_version_fops); + + /* A directory for each instance of the TSENS IP */ + priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root); + debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops); +} +#else +static inline void tsens_debug_init(struct platform_device *pdev) {} +#endif + static const struct regmap_config tsens_config = { .name = "tm", .reg_bits = 32, @@ -199,6 +271,15 @@ int __init init_common(struct tsens_priv *priv) goto err_put_device; } + if (tsens_ver(priv) > VER_0_1) { + for (i = VER_MAJOR; i <= VER_STEP; i++) { + priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map, + priv->fields[i]); + if (IS_ERR(priv->rf[i])) + return PTR_ERR(priv->rf[i]); + } + } + priv->rf[TSENS_EN] = devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_EN]); if (IS_ERR(priv->rf[TSENS_EN])) { @@ -238,6 +319,8 @@ int __init init_common(struct tsens_priv *priv) } } + tsens_debug_init(op); + return 0; err_put_device: diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 06c6bbd69a1a..772aa76b50e1 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -3,6 +3,7 @@ * Copyright (c) 2015, The Linux Foundation. All rights reserved. */ +#include #include #include #include @@ -176,6 +177,7 @@ static int tsens_remove(struct platform_device *pdev) { struct tsens_priv *priv = platform_get_drvdata(pdev); + debugfs_remove_recursive(priv->debug_root); if (priv->ops->disable) priv->ops->disable(priv); diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index d022e726d074..e1d6af71b2b9 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -292,6 +292,8 @@ struct tsens_context { * @feat: features of the IP * @fields: bitfield locations * @ops: pointer to list of callbacks supported by this device + * @debug_root: pointer to debugfs dentry for all tsens + * @debug: pointer to debugfs dentry for tsens controller * @sensor: list of sensors attached to this device */ struct tsens_priv { @@ -305,6 +307,10 @@ struct tsens_priv { const struct tsens_features *feat; const struct reg_field *fields; const struct tsens_ops *ops; + + struct dentry *debug_root; + struct dentry *debug; + struct tsens_sensor sensor[0]; }; From patchwork Fri Sep 20 21:52:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Kucheria X-Patchwork-Id: 174162 Delivered-To: patch@linaro.org Received: by 2002:a92:7e96:0:0:0:0:0 with SMTP id q22csp3031964ill; Fri, 20 Sep 2019 14:53:06 -0700 (PDT) X-Google-Smtp-Source: APXvYqwWjoBvNOP5m53csYDJUWzq9k2ISBxdhHLV6f/MV1jrKWeukpXflPUMhSDXEUxd8MmsXCc+ X-Received: by 2002:a50:b884:: with SMTP id l4mr24409171ede.295.1569016386449; Fri, 20 Sep 2019 14:53:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569016386; cv=none; d=google.com; s=arc-20160816; b=oSP1NGo/VNc2kl3gDkMyM1Us1njFZ6kT1dVSq15stTqZgYt+Pzo/iVzoMtdqNS5SHB JtpiQfOwpoqR+mHHoClFW6j+NhzWrH05NmwmNm9Fwkk7XJj7ipWJ9/vztovFg3ISmMwU 3VaXPu77LN00oZo/VuFlMet/EchtfK0/UvenseUUh9f4bzxKTInf8PYxsSIaZYnXtklv IfVxX8dW5sGH7HVW8v6/N0HPFjfHfI9HMeB1XYazJTkfVYtsKcUWeSuHDw6HxIe8bsAr d8/rykhUwPibx0KVQgWRyF06YIqp596nOG4runlCs1mjEIiO9j3RcAhh8mKlFKzVfkY4 hlYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=ZwCxmgUQhS9SSaQKkkkSIJsmLTrN1BacMY6pM2O/8bI=; b=pAJo1xV0c07EvB2l0aPI4vIzD205NpS75Rhqv7TBJUsE5G9ZHwRU6UFlUZxZe65vG8 pPAXyydaPkDlIXTCA2skF/nvhUY3Kp/HKRRCn+waqZGFbvkrU0hhCJUZCdc2bc9qrYqx g/SbgOws1rKInhxlJA/TbGUX5TCbbnT9LYL1SecMw3k/Jpw9bG8jVXgdVQqXMtxjVP6Q NT9ZSVeFB3hlkB4WqTXA3pCSC/8+qmBhHHUtgJ4y432A/s6vG5saCxpoTUxX0sCJXwDQ D9Z4rEZHBhfHswbeLQ+/SQHSEc26zoEK7ddQUDiERUsvKIdlbOt8AApoZwsKjGqN4rFP rbuA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=sHrR167d; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z55si2241928edz.254.2019.09.20.14.53.06; Fri, 20 Sep 2019 14:53:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=sHrR167d; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729997AbfITVxC (ORCPT + 15 others); Fri, 20 Sep 2019 17:53:02 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:43663 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729629AbfITVxB (ORCPT ); Fri, 20 Sep 2019 17:53:01 -0400 Received: by mail-pg1-f195.google.com with SMTP id d4so1472329pgd.10 for ; Fri, 20 Sep 2019 14:53:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=ZwCxmgUQhS9SSaQKkkkSIJsmLTrN1BacMY6pM2O/8bI=; b=sHrR167docCdJXHVTdDaf03xJf2yw4xV+1F6MU8K8Q0HAGV7REGkH1/XmSo2VA1BsN Ijn7d02eUll0eobiBr74IcbvRpYheIA77RgwfW6gj5nVtHe0NrphY+w+F+3XjQ/j+nfV oLsS/eucdmOtM4s5NzDB8GKZJ03rYdxkWyFxqO2TwZu1Ji02YjSuahNYSQSp6Ew4EPK9 So6NQaAIzqEo7bY9MotYb95MhF8OGUmavXd5uu70ysyA1/Mx7QESgHrvHxJcL08wtpl7 RArdT4jmauDpu4spqfsUMYmPt84Jbt6z+tFaoqiBChbUne3iPI2smoKpKGEVF1M6w6n9 eYoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=ZwCxmgUQhS9SSaQKkkkSIJsmLTrN1BacMY6pM2O/8bI=; b=Q6HXsVdbm5ISDuLA4QBIdnV9Y457a6qPbOmwlGJ4jhWbvJ/Eh4V2J5uijr+HQpOMEG 5Szhx2ReCX79A+kf6+Pq2nOnDlVPH5h4BrD8bpePRxsmiPSVTax9VEu4DRU6N4gWRk48 KasPKnaXmFdJWm1IRt6nfFE5RI42LkDSt9UJhQleCfZdyXsCMAUqHBMhJlII3bSBKYaz jRzyCQR7+lVjp0D5GEfsJLD0ypDFXIJnh4Qk/QTkr+37dpjm9w0U+GYCbmpp0d6TZJ+H 88CZcxU4qSYvbpUKlpzAKzUaCZIoS2ygr7NHqZm8cY9HeZjxZRvN8Bx5tLU+ague3Znr tMuw== X-Gm-Message-State: APjAAAU42bB5WNG4xN1qquctnv/3l7VVqCZtdGr7OEPoiC57lotEahCx bauZCr/HSaBpshOqo1QxUZ4RxRJiSK8cKQ== X-Received: by 2002:a63:501:: with SMTP id 1mr17148626pgf.290.1569016380014; Fri, 20 Sep 2019 14:53:00 -0700 (PDT) Received: from localhost (wsip-98-175-107-49.sd.sd.cox.net. [98.175.107.49]) by smtp.gmail.com with ESMTPSA id 127sm2662448pgi.46.2019.09.20.14.52.59 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 20 Sep 2019 14:52:59 -0700 (PDT) From: Amit Kucheria To: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, bjorn.andersson@linaro.org, edubezval@gmail.com, agross@kernel.org, masneyb@onstation.org, swboyd@chromium.org, Daniel Lezcano , Mark Rutland , Rob Herring , Zhang Rui Cc: devicetree@vger.kernel.org Subject: [PATCH v4 09/15] arm64: dts: msm8996: thermal: Add interrupt support Date: Fri, 20 Sep 2019 14:52:24 -0700 Message-Id: X-Mailer: git-send-email 2.17.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Register upper-lower interrupts for each of the two tsens controllers. Signed-off-by: Amit Kucheria --- arch/arm64/boot/dts/qcom/msm8996.dtsi | 60 ++++++++++++++------------- 1 file changed, 32 insertions(+), 28 deletions(-) -- 2.17.1 diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 96c0a481f454..bb763b362c16 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -175,8 +175,8 @@ thermal-zones { cpu0-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens0 3>; @@ -196,8 +196,8 @@ }; cpu1-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens0 5>; @@ -217,8 +217,8 @@ }; cpu2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens0 8>; @@ -238,8 +238,8 @@ }; cpu3-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens0 10>; @@ -259,8 +259,8 @@ }; gpu-thermal-top { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens1 6>; @@ -274,8 +274,8 @@ }; gpu-thermal-bottom { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens1 7>; @@ -289,8 +289,8 @@ }; m4m-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens0 1>; @@ -304,8 +304,8 @@ }; l3-or-venus-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens0 2>; @@ -319,8 +319,8 @@ }; cluster0-l2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens0 7>; @@ -334,8 +334,8 @@ }; cluster1-l2-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens0 12>; @@ -349,8 +349,8 @@ }; camera-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens1 1>; @@ -364,8 +364,8 @@ }; q6-dsp-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens1 2>; @@ -379,8 +379,8 @@ }; mem-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens1 3>; @@ -394,8 +394,8 @@ }; modemtx-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens1 4>; @@ -591,6 +591,8 @@ reg = <0x4a9000 0x1000>, /* TM */ <0x4a8000 0x1000>; /* SROT */ #qcom,sensors = <13>; + interrupts = ; + interrupt-names = "uplow"; #thermal-sensor-cells = <1>; }; @@ -599,6 +601,8 @@ reg = <0x4ad000 0x1000>, /* TM */ <0x4ac000 0x1000>; /* SROT */ #qcom,sensors = <8>; + interrupts = ; + interrupt-names = "uplow"; #thermal-sensor-cells = <1>; }; From patchwork Fri Sep 20 21:52:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Kucheria X-Patchwork-Id: 174165 Delivered-To: patch@linaro.org Received: by 2002:a92:7e96:0:0:0:0:0 with SMTP id q22csp3032048ill; Fri, 20 Sep 2019 14:53:12 -0700 (PDT) X-Google-Smtp-Source: APXvYqy/RxzdiXUVLYCYcfCyfk66xNydLU4nTDZhlJNjNmsTyAFEkonzy06PCW34xr3bCx4ll5DB X-Received: by 2002:a50:8d5e:: with SMTP id t30mr24592630edt.112.1569016392240; Fri, 20 Sep 2019 14:53:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569016392; cv=none; d=google.com; s=arc-20160816; b=Nnx1q6BmneyglvqnWGsgiog3rtrG5ZcKL99tjoAdsO4HHyRtBF8lnoByVUb+NMYQUE daYCKt3yYC1PFXjK5J0WLKZE35GTgh4STRh3ivaIHpZ4wz4XQ0eUG3pw09v6OEMLjVe7 IozUTYY2EWbnvA2qveq3y9R+A5xTh9OujTKXwOfzVM7zNJlKyhaXCd7KYwXbkTFdRY3b cnhXCD6Qp4l1WgcBAcxL03xu3YfqNMkCkqtUwB6KQr28VArvvqnDDwnR57BnBKlkoUCG oF+hGp+j+Qm/sOmSavDnoRUjk3CHwLLYiqAYqsgNRpC08GRTbdmnUNroO5EfI5TeEP7P GeQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=VrMMAxmAWCoF+Z0mK+KREcF/roJedPfia4jPAm5aT6w=; b=juAatS2PejG9VBgvu6h2QsWYdGWKrJzAkrehBBlWO1bsNSOxHIhoDz9bH0CaZViMK2 VmpKe3mccHSX0qP5fbVzaKKQ4id1N5V2QBW9kanljzis7MPdbqPDXoaXPy3QzhHSmIoO rrBymEtn02ec9DbztwmFkFl1Y7/pzFXmSMHST9RAot72dQRcPWJVYWCRb5DkMQNz13tU yj/qIMhWbDvg3vXyLv0PFrjh9iwcDUOKAO3k8bg0kXrTuv+r/5Dka0k0CD24Uo7o85+q udVN+TpO+gyctmRP5uOL9SyZJba2sXwPfMC5jk6BNEWD2gLNL+EdoADz02qU0wZSLNm4 v1yA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=hdTk7Wbn; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y1si1783567ejr.272.2019.09.20.14.53.11; Fri, 20 Sep 2019 14:53:12 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=hdTk7Wbn; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730281AbfITVxI (ORCPT + 15 others); Fri, 20 Sep 2019 17:53:08 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:37493 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730269AbfITVxI (ORCPT ); Fri, 20 Sep 2019 17:53:08 -0400 Received: by mail-pl1-f193.google.com with SMTP id b10so3801115plr.4 for ; Fri, 20 Sep 2019 14:53:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=VrMMAxmAWCoF+Z0mK+KREcF/roJedPfia4jPAm5aT6w=; b=hdTk7WbnOHXiUYbTZwim1OGeWK5A2LQE3v5T+TYfGXALHEHxrDwjzCh1hqE/ERTYgR FdTBcF6j5GvfHYhtuzgU4xG6Sdi0Sy9bTUp4XIvgqNqDSofcArTPULOTd4YlATbCQ2dy glTCi0fnP9Ou0ClR+6FkWVe76hx1AN/MdCwVLDtnfVN7qr1ag7U+i0PyqK9sIh/n/lIU KLYoRRjem3y9H0naE59MoURT6YLYgPoceEOSLTOCKfgWci2CSLlP0r1E5up2nMV9orSw QXuZsnzyROWpe/r8KrrBKnCTPZ1RjJJVWcbm1hV7Dg2es97kjX9AzZjxSm/XZi1kPnFX 3Luw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=VrMMAxmAWCoF+Z0mK+KREcF/roJedPfia4jPAm5aT6w=; b=e6yUVtJCB7SYE7Tui4M07Se8rd7pvkw8GZLu3SXS7judMwYRt5DqTonHE3oUC9H8ab 1S5g8vaxUXucxkpdlgb4lNr69On9GppPbZJ8xq55fv8BvdcZ2h8mPWTS0KJ6XOQpQZI+ /qWNARd9AJETOiSolLttPwsLeBS9bHgxjdfq9UmfgCgj9Pfte/SLB+bsPu+g2DdexAcp vg1L4iTy6ZFTMk2fThAgtabjzH9qheiCuylXaCzMoUWFItT0b6F1dY2jvMGG1UCzYEvv e88gzxFfetzlBwbzHdJ4y5dDUHjAuRP/jggWO3azPfQuQgOCz9ldvSW8YQLnKAncb8/S gqUg== X-Gm-Message-State: APjAAAWX33lmN2fCh87JcvTyP7ixAmkO/Sdw6aVcxUh674o8eoC1e3ZY KpLpG1Y0xVFP2gMoGHnUPv+0Mg== X-Received: by 2002:a17:902:14b:: with SMTP id 69mr18922218plb.286.1569016386832; Fri, 20 Sep 2019 14:53:06 -0700 (PDT) Received: from localhost (wsip-98-175-107-49.sd.sd.cox.net. [98.175.107.49]) by smtp.gmail.com with ESMTPSA id f6sm2910513pga.50.2019.09.20.14.53.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 20 Sep 2019 14:53:06 -0700 (PDT) From: Amit Kucheria To: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, bjorn.andersson@linaro.org, edubezval@gmail.com, agross@kernel.org, masneyb@onstation.org, swboyd@chromium.org, Daniel Lezcano , Mark Rutland , Rob Herring , Zhang Rui Cc: devicetree@vger.kernel.org Subject: [PATCH v4 12/15] arm: dts: msm8974: thermal: Add interrupt support Date: Fri, 20 Sep 2019 14:52:27 -0700 Message-Id: <12ce7db8f17cdaf8fef89ed7f1fce10f08acab57.1569015835.git.amit.kucheria@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Register upper-lower interrupt for the tsens controller. Signed-off-by: Amit Kucheria Tested-by: Brian Masney --- arch/arm/boot/dts/qcom-msm8974.dtsi | 36 +++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) -- 2.17.1 diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index d32f639505f1..290f7c3827d4 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -139,8 +139,8 @@ thermal-zones { cpu-thermal0 { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens 5>; @@ -159,8 +159,8 @@ }; cpu-thermal1 { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens 6>; @@ -179,8 +179,8 @@ }; cpu-thermal2 { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens 7>; @@ -199,8 +199,8 @@ }; cpu-thermal3 { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens 8>; @@ -219,8 +219,8 @@ }; q6-dsp-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens 1>; @@ -234,8 +234,8 @@ }; modemtx-thermal { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens 2>; @@ -250,7 +250,7 @@ video-thermal { polling-delay-passive = <0>; - polling-delay = <1000>; + polling-delay = <0>; thermal-sensors = <&tsens 3>; @@ -279,8 +279,8 @@ }; gpu-thermal-top { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens 9>; @@ -294,8 +294,8 @@ }; gpu-thermal-bottom { - polling-delay-passive = <250>; - polling-delay = <1000>; + polling-delay-passive = <0>; + polling-delay = <0>; thermal-sensors = <&tsens 10>; @@ -531,6 +531,8 @@ nvmem-cells = <&tsens_calib>, <&tsens_backup>; nvmem-cell-names = "calib", "calib_backup"; #qcom,sensors = <11>; + interrupts = ; + interrupt-names = "uplow"; #thermal-sensor-cells = <1>; }; From patchwork Fri Sep 20 21:52:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Kucheria X-Patchwork-Id: 174167 Delivered-To: patch@linaro.org Received: by 2002:a92:7e96:0:0:0:0:0 with SMTP id q22csp3032164ill; Fri, 20 Sep 2019 14:53:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqykEdXelr9Jj4BanH0c0D9bJEFLzjIOVjzFCwCvVZJgo7eiml1GTAgyrTQhzTN4inPM739F X-Received: by 2002:a05:6402:1501:: with SMTP id f1mr24423293edw.76.1569016398681; Fri, 20 Sep 2019 14:53:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1569016398; cv=none; d=google.com; s=arc-20160816; b=izVTwZ83KzCKhqsCO1d48zegKiwD1pKPIZcYH3+fZuoT8JNRlCcS3q+B7NeyFrKz1u qBlwIp+qdeHRMrF0a4LWCA1ymesFe//SvSKjk4oNYTHq873KI3q3NWatwykUfYQJgZTu tGY67Zs6VFV9t5yKYXTxx6Lo4rZiywP+lnJHW/q13R/LYa5wfU/h53a5EhITRxw4cpfh xLAQt8qiKedUxVftQ3cQusWbVAUSqKyxOALqAl17ey9dH1JSpEiK2a1v/qBxoc+z1X1p C2wkBfTdPnASrBaS3MRS9DOPEt3eibmJYGaOAa7OpqGZYd2YsGOSz9DqOZSSRRbYJyWk gadg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=7hw3FKZTspqRIzqc7e4L+D89fN14X6IbGOT4d6UqHuw=; b=09Q+TedMHPwvbcIdArvXHvpqGiDWO4rloX7oC0JLIErCQlwSnisv/c9fgUfP/K8y8s HKKYjs5wDyrNDL7WtEciXK9+MIFtLWcx167SZsem2DH8qtC7YaS0tl4KWfwlVfgol4GZ YgC7GCmaV8ssUuFnzHQvUfynLPZ/MlhVNvAsdEy0nLQ39YreACLf51k5GGbIBXiGKq+w HEvJ7UEIoEHb5APlLsmAkseWQltmJI6Z6gMyHl7oRLGGLyOGdMWkPWTuCK+AfUJswXoT LXK8A7hMPboo/+NuvEpqzstD0aAsSvADqyVpDNUZ73yA5Omt2TX/MRHeOTG9/dPtVd0n 6+Aw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=H0MLcsPA; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x8si2446025edd.282.2019.09.20.14.53.18; Fri, 20 Sep 2019 14:53:18 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=H0MLcsPA; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730334AbfITVxQ (ORCPT + 15 others); Fri, 20 Sep 2019 17:53:16 -0400 Received: from mail-pf1-f195.google.com ([209.85.210.195]:35316 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730323AbfITVxP (ORCPT ); Fri, 20 Sep 2019 17:53:15 -0400 Received: by mail-pf1-f195.google.com with SMTP id 205so5417290pfw.2 for ; Fri, 20 Sep 2019 14:53:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=7hw3FKZTspqRIzqc7e4L+D89fN14X6IbGOT4d6UqHuw=; b=H0MLcsPAC8R9m040qh9bOzWYjUx3F6g5dXf7jHHuj4xbGczsiUKJMZXxs2tSCxigIC ZseVoKz5NtEXPyVrs2xTigGrNOpdmM1nlqNiOmdIGGTWyilCe5sNr/zoE8SswYQDjuuc hvyHoIk2Z+z46yxHd6CmzxTtPq8V/wh3QktNPu2vGmQ10bHmI+tuNwnmlqynwrm6hJeg pFm+j1hkgmIMEUNg63Ozzzbm46hYoA1im+vcpmlM6niQsxAb1OTSOravF3tNSsAIrWLP qmtvDFASOdwH0/a3aVR5qq11zXyewBElthlKONiYsJitrkcD5lZOuYyjj/msJFI74aVk yVIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=7hw3FKZTspqRIzqc7e4L+D89fN14X6IbGOT4d6UqHuw=; b=Jti+wO15MfOzZllIMbz6YLiDdTCma+2ISQdUFwt8h9Pn8O7RorfF+eO2gKSIPPyJ5a AkS/aetfJK1pwTuxz4mawBABwnp8NuPpsGuSRQla7pkMsJpRgmw/B5gEOSZafKZEnOkG emHqxnjuOosaMhakgs/Cg73mPz4ode9rBMGmR8hIgH+zGjg1lj8JzzyFUeJQGAZawyzv 6RKwjnTIoB5kuhvg/nAK20UjqT2TcXKNNawGFTHcXcFw/H4Tvr8oo4kCEFbzRLGwmOya slUViuQI/YGRNSQc9JaaUFs7pgKA3XWS2AZdvCgOjx2MN3CmfWlINvFuDzB6B1zzzkHp ayVQ== X-Gm-Message-State: APjAAAU54s1cW9SdNrkLMw2TVHV1hhtJJaqmNO40b5fv0KnqD3EzXPH/ ZOjr9hzKM6gGSoRdbBA6PYpgcodyXaJ8+g== X-Received: by 2002:a17:90a:1903:: with SMTP id 3mr6954336pjg.80.1569016394018; Fri, 20 Sep 2019 14:53:14 -0700 (PDT) Received: from localhost (wsip-98-175-107-49.sd.sd.cox.net. [98.175.107.49]) by smtp.gmail.com with ESMTPSA id 127sm4117035pfc.115.2019.09.20.14.53.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 20 Sep 2019 14:53:13 -0700 (PDT) From: Amit Kucheria To: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, bjorn.andersson@linaro.org, edubezval@gmail.com, agross@kernel.org, masneyb@onstation.org, swboyd@chromium.org, Daniel Lezcano , Mark Rutland , Rob Herring , Zhang Rui Cc: linux-pm@vger.kernel.org Subject: [PATCH v4 15/15] drivers: thermal: tsens: Add interrupt support Date: Fri, 20 Sep 2019 14:52:30 -0700 Message-Id: X-Mailer: git-send-email 2.17.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Depending on the IP version, TSENS supports upper, lower and critical threshold interrupts. We only add support for upper and lower threshold interrupts for now. TSENSv2 has an irq [status|clear|mask] bit tuple for each sensor while earlier versions only have a single bit per sensor to denote status and clear. These differences are handled transparently by the interrupt handler. At each interrupt, we reprogram the new upper and lower threshold in the .set_trip callback. Signed-off-by: Amit Kucheria --- drivers/thermal/qcom/tsens-common.c | 376 ++++++++++++++++++++++++++-- drivers/thermal/qcom/tsens-v0_1.c | 11 + drivers/thermal/qcom/tsens-v1.c | 29 +++ drivers/thermal/qcom/tsens-v2.c | 13 + drivers/thermal/qcom/tsens.c | 31 ++- drivers/thermal/qcom/tsens.h | 270 ++++++++++++++++---- 6 files changed, 668 insertions(+), 62 deletions(-) -- 2.17.1 Reviewed-by: Stephen Boyd diff --git a/drivers/thermal/qcom/tsens-common.c b/drivers/thermal/qcom/tsens-common.c index 6b6b3841c2d0..03bf1b8133ea 100644 --- a/drivers/thermal/qcom/tsens-common.c +++ b/drivers/thermal/qcom/tsens-common.c @@ -13,6 +13,31 @@ #include #include "tsens.h" +/** + * struct tsens_irq_data - IRQ status and temperature violations + * @up_viol: upper threshold violated + * @up_thresh: upper threshold temperature value + * @up_irq_mask: mask register for upper threshold irqs + * @up_irq_clear: clear register for uppper threshold irqs + * @low_viol: lower threshold violated + * @low_thresh: lower threshold temperature value + * @low_irq_mask: mask register for lower threshold irqs + * @low_irq_clear: clear register for lower threshold irqs + * + * Structure containing data about temperature threshold settings and + * irq status if they were violated. + */ +struct tsens_irq_data { + u32 up_viol; + int up_thresh; + u32 up_irq_mask; + u32 up_irq_clear; + u32 low_viol; + int low_thresh; + u32 low_irq_mask; + u32 low_irq_clear; +}; + char *qfprom_read(struct device *dev, const char *cname) { struct nvmem_cell *cell; @@ -65,6 +90,14 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1, } } +static inline u32 degc_to_code(int degc, const struct tsens_sensor *s) +{ + u64 code = (degc * s->slope + s->offset) / SLOPE_FACTOR; + + pr_debug("%s: raw_code: 0x%llx, degc:%d\n", __func__, code, degc); + return clamp_val(code, THRESHOLD_MIN_ADC_CODE, THRESHOLD_MAX_ADC_CODE); +} + static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s) { int degc, num, den; @@ -117,6 +150,313 @@ static int tsens_hw_to_mC(struct tsens_sensor *s, int field) return sign_extend32(temp, resolution) * 100; } +/** + * tsens_mC_to_hw - Convert temperature to hardware register value + * @s: Pointer to sensor struct + * @temp: temperature in milliCelsius to be programmed to hardware + * + * This function outputs the value to be written to hardware in ADC code + * or deciCelsius depending on IP version. + * + * Return: ADC code or temperature in deciCelsius. + */ +static int tsens_mC_to_hw(struct tsens_sensor *s, int temp) +{ + struct tsens_priv *priv = s->priv; + + /* milliC to adc code */ + if (priv->feat->adc) + return degc_to_code(temp / 1000, s); + + /* milliC to deciC */ + return temp / 100; +} + +static inline enum tsens_ver tsens_version(struct tsens_priv *priv) +{ + return priv->feat->ver_major; +} + +static void tsens_set_interrupt_v1(struct tsens_priv *priv, u32 hw_id, + enum tsens_irq_type irq_type, bool enable) +{ + u32 index; + + switch (irq_type) { + case UPPER: + index = UP_INT_CLEAR_0 + hw_id; + break; + case LOWER: + index = LOW_INT_CLEAR_0 + hw_id; + break; + } + regmap_field_write(priv->rf[index], enable ? 0 : 1); +} + +static void tsens_set_interrupt_v2(struct tsens_priv *priv, u32 hw_id, + enum tsens_irq_type irq_type, bool enable) +{ + u32 index_mask, index_clear; + + /* + * To enable the interrupt flag for a sensor: + * - clear the mask bit + * To disable the interrupt flag for a sensor: + * - Mask further interrupts for this sensor + * - Write 1 followed by 0 to clear the interrupt + */ + switch (irq_type) { + case UPPER: + index_mask = UP_INT_MASK_0 + hw_id; + index_clear = UP_INT_CLEAR_0 + hw_id; + break; + case LOWER: + index_mask = LOW_INT_MASK_0 + hw_id; + index_clear = LOW_INT_CLEAR_0 + hw_id; + break; + } + + if (enable) { + regmap_field_write(priv->rf[index_mask], 0); + } else { + regmap_field_write(priv->rf[index_mask], 1); + regmap_field_write(priv->rf[index_clear], 1); + regmap_field_write(priv->rf[index_clear], 0); + } +} + +/** + * tsens_set_interrupt - Set state of an interrupt + * @priv: Pointer to tsens controller private data + * @hw_id: Hardware ID aka. sensor number + * @irq_type: irq_type from enum tsens_irq_type + * @enable: false = disable, true = enable + * + * Call IP-specific function to set state of an interrupt + * + * Return: void + */ +static void tsens_set_interrupt(struct tsens_priv *priv, u32 hw_id, + enum tsens_irq_type irq_type, bool enable) +{ + dev_dbg(priv->dev, "[%u] %s: %s -> %s\n", hw_id, __func__, + irq_type ? ((irq_type == 1) ? "UP" : "CRITICAL") : "LOW", + enable ? "en" : "dis"); + if (tsens_version(priv) > VER_1_X) + tsens_set_interrupt_v2(priv, hw_id, irq_type, enable); + else + tsens_set_interrupt_v1(priv, hw_id, irq_type, enable); +} + +/** + * tsens_threshold_violated - Check if a sensor temperature violated a preset threshold + * @priv: Pointer to tsens controller private data + * @hw_id: Hardware ID aka. sensor number + * @d: Pointer to irq state data + * + * Return: 0 if threshold was not violated, 1 if it was violated and negative + * errno in case of errors + */ +static int tsens_threshold_violated(struct tsens_priv *priv, u32 hw_id, + struct tsens_irq_data *d) +{ + int ret; + + ret = regmap_field_read(priv->rf[UPPER_STATUS_0 + hw_id], &d->up_viol); + if (ret) + return ret; + ret = regmap_field_read(priv->rf[LOWER_STATUS_0 + hw_id], &d->low_viol); + if (ret) + return ret; + if (d->up_viol || d->low_viol) + return 1; + + return 0; +} + +static int tsens_read_irq_state(struct tsens_priv *priv, u32 hw_id, + struct tsens_sensor *s, struct tsens_irq_data *d) +{ + int ret; + + ret = regmap_field_read(priv->rf[UP_INT_CLEAR_0 + hw_id], &d->up_irq_clear); + if (ret) + return ret; + ret = regmap_field_read(priv->rf[LOW_INT_CLEAR_0 + hw_id], &d->low_irq_clear); + if (ret) + return ret; + if (tsens_version(priv) > VER_1_X) { + ret = regmap_field_read(priv->rf[UP_INT_MASK_0 + hw_id], &d->up_irq_mask); + if (ret) + return ret; + ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask); + if (ret) + return ret; + } else { + /* No mask register on older TSENS */ + d->up_irq_mask = 0; + d->low_irq_mask = 0; + } + + d->up_thresh = tsens_hw_to_mC(s, UP_THRESH_0 + hw_id); + d->low_thresh = tsens_hw_to_mC(s, LOW_THRESH_0 + hw_id); + + dev_dbg(priv->dev, "[%u] %s%s: status(%u|%u) | clr(%u|%u) | mask(%u|%u)\n", + hw_id, __func__, (d->up_viol || d->low_viol) ? "(V)" : "", + d->low_viol, d->up_viol, d->low_irq_clear, d->up_irq_clear, + d->low_irq_mask, d->up_irq_mask); + dev_dbg(priv->dev, "[%u] %s%s: thresh: (%d:%d)\n", hw_id, __func__, + (d->up_viol || d->low_viol) ? "(violation)" : "", + d->low_thresh, d->up_thresh); + + return 0; +} + +static inline u32 masked_irq(u32 hw_id, u32 mask, enum tsens_ver ver) +{ + if (ver > VER_1_X) + return mask & (1 << hw_id); + + /* v1, v0.1 don't have a irq mask register */ + return 0; +} + +/** + * tsens_irq_thread - Threaded interrupt handler for uplow interrupts + * @irq: irq number + * @data: tsens controller private data + * + * Check all sensors to find ones that violated their threshold limits. If the + * temperature is still outside the limits, call thermal_zone_device_update() to + * update the thresholds, else re-enable the interrupts. + * + * The level-triggered interrupt might deassert if the temperature returned to + * within the threshold limits by the time the handler got scheduled. We + * consider the irq to have been handled in that case. + * + * Return: IRQ_HANDLED + */ +irqreturn_t tsens_irq_thread(int irq, void *data) +{ + struct tsens_priv *priv = data; + struct tsens_irq_data d; + bool enable = true, disable = false; + unsigned long flags; + int temp, ret, i; + + for (i = 0; i < priv->num_sensors; i++) { + bool trigger = false; + struct tsens_sensor *s = &priv->sensor[i]; + u32 hw_id = s->hw_id; + + if (IS_ERR(priv->sensor[i].tzd)) + continue; + if (!tsens_threshold_violated(priv, hw_id, &d)) + continue; + ret = get_temp_tsens_valid(s, &temp); + if (ret) { + dev_err(priv->dev, "[%u] %s: error reading sensor\n", hw_id, __func__); + continue; + } + + spin_lock_irqsave(&priv->ul_lock, flags); + + tsens_read_irq_state(priv, hw_id, s, &d); + + if (d.up_viol && + !masked_irq(hw_id, d.up_irq_mask, tsens_version(priv))) { + tsens_set_interrupt(priv, hw_id, UPPER, disable); + if (d.up_thresh > temp) { + dev_dbg(priv->dev, "[%u] %s: re-arm upper\n", + priv->sensor[i].hw_id, __func__); + tsens_set_interrupt(priv, hw_id, UPPER, enable); + } else { + trigger = true; + /* Keep irq masked */ + } + } else if (d.low_viol && + !masked_irq(hw_id, d.low_irq_mask, tsens_version(priv))) { + tsens_set_interrupt(priv, hw_id, LOWER, disable); + if (d.low_thresh < temp) { + dev_dbg(priv->dev, "[%u] %s: re-arm low\n", + priv->sensor[i].hw_id, __func__); + tsens_set_interrupt(priv, hw_id, LOWER, enable); + } else { + trigger = true; + /* Keep irq masked */ + } + } + + spin_unlock_irqrestore(&priv->ul_lock, flags); + + if (trigger) { + dev_dbg(priv->dev, "[%u] %s: TZ update trigger (%d mC)\n", + hw_id, __func__, temp); + thermal_zone_device_update(priv->sensor[i].tzd, + THERMAL_EVENT_UNSPECIFIED); + } else { + dev_dbg(priv->dev, "[%u] %s: no violation: %d\n", + hw_id, __func__, temp); + } + } + + return IRQ_HANDLED; +} + +int tsens_set_trips(void *_sensor, int low, int high) +{ + struct tsens_sensor *s = _sensor; + struct tsens_priv *priv = s->priv; + struct device *dev = priv->dev; + struct tsens_irq_data d; + unsigned long flags; + int high_val, low_val, cl_high, cl_low; + u32 hw_id = s->hw_id; + + dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n", + hw_id, __func__, low, high); + + cl_high = clamp_val(high, -40000, 120000); + cl_low = clamp_val(low, -40000, 120000); + + high_val = tsens_mC_to_hw(s, cl_high); + low_val = tsens_mC_to_hw(s, cl_low); + + spin_lock_irqsave(&priv->ul_lock, flags); + + tsens_read_irq_state(priv, hw_id, s, &d); + + /* Write the new thresholds and clear the status */ + regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val); + regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val); + tsens_set_interrupt(priv, hw_id, LOWER, true); + tsens_set_interrupt(priv, hw_id, UPPER, true); + + spin_unlock_irqrestore(&priv->ul_lock, flags); + + dev_dbg(dev, "[%u] %s: (%d:%d)->(%d:%d)\n", + s->hw_id, __func__, d.low_thresh, d.up_thresh, cl_low, cl_high); + + return 0; +} + +int tsens_enable_irq(struct tsens_priv *priv) +{ + int ret; + int val = tsens_version(priv) > VER_1_X ? 7 : 1; + + ret = regmap_field_write(priv->rf[INT_EN], val); + if (ret < 0) + dev_err(priv->dev, "%s: failed to enable interrupts\n", __func__); + + return ret; +} + +void tsens_disable_irq(struct tsens_priv *priv) +{ + regmap_field_write(priv->rf[INT_EN], 0); +} + int get_temp_tsens_valid(struct tsens_sensor *s, int *temp) { struct tsens_priv *priv = s->priv; @@ -187,7 +527,7 @@ static int dbg_version_show(struct seq_file *s, void *data) u32 maj_ver, min_ver, step_ver; int ret; - if (tsens_ver(priv) > VER_0_1) { + if (tsens_version(priv) > VER_0_1) { ret = regmap_field_read(priv->rf[VER_MAJOR], &maj_ver); if (ret) return ret; @@ -292,7 +632,7 @@ int __init init_common(struct tsens_priv *priv) goto err_put_device; } - if (tsens_ver(priv) > VER_0_1) { + if (tsens_version(priv) > VER_0_1) { for (i = VER_MAJOR; i <= VER_STEP; i++) { priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[i]); @@ -322,25 +662,29 @@ int __init init_common(struct tsens_priv *priv) ret = PTR_ERR(priv->rf[SENSOR_EN]); goto err_put_device; } - /* now alloc regmap_fields in tm_map */ - for (i = 0, j = LAST_TEMP_0; i < priv->feat->max_sensors; i++, j++) { - priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map, - priv->fields[j]); - if (IS_ERR(priv->rf[j])) { - ret = PTR_ERR(priv->rf[j]); - goto err_put_device; - } + priv->rf[INT_EN] = devm_regmap_field_alloc(dev, priv->tm_map, + priv->fields[INT_EN]); + if (IS_ERR(priv->rf[INT_EN])) { + ret = PTR_ERR(priv->rf[INT_EN]); + goto err_put_device; } - for (i = 0, j = VALID_0; i < priv->feat->max_sensors; i++, j++) { - priv->rf[j] = devm_regmap_field_alloc(dev, priv->tm_map, - priv->fields[j]); - if (IS_ERR(priv->rf[j])) { - ret = PTR_ERR(priv->rf[j]); - goto err_put_device; + /* This loop might need changes if enum regfield_ids is reordered */ + for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) { + for (i = 0; i < priv->feat->max_sensors; i++) { + int idx = j + i; + + priv->rf[idx] = devm_regmap_field_alloc(dev, priv->tm_map, + priv->fields[idx]); + if (IS_ERR(priv->rf[idx])) { + ret = PTR_ERR(priv->rf[idx]); + goto err_put_device; + } } } + spin_lock_init(&priv->ul_lock); + tsens_enable_irq(priv); tsens_debug_init(op); return 0; diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c index 6f26fadf4c27..a267b66e61d6 100644 --- a/drivers/thermal/qcom/tsens-v0_1.c +++ b/drivers/thermal/qcom/tsens-v0_1.c @@ -339,9 +339,20 @@ static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = { /* INTERRUPT ENABLE */ [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0), + /* UPPER/LOWER TEMPERATURE THRESHOLDS */ + REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 0, 9), + REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 10, 19), + + /* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */ + REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 20, 20), + REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 21, 21), + + /* NO CRITICAL INTERRUPT SUPPORT on v0.1 */ + /* Sn_STATUS */ REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9), /* No VALID field on v0.1 */ + /* xxx_STATUS bits: 1 == threshold violated */ REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10), REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11), REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12), diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index 10b595d4f619..86259c9821be 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -17,6 +17,8 @@ #define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF 0x0004 #define TM_Sn_STATUS_OFF 0x0044 #define TM_TRDY_OFF 0x0084 +#define TM_HIGH_LOW_INT_STATUS_OFF 0x0088 +#define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090 /* eeprom layout data for qcs404/405 (v1) */ #define BASE0_MASK 0x000007f8 @@ -167,9 +169,36 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = { /* INTERRUPT ENABLE */ [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0), + /* UPPER/LOWER TEMPERATURE THRESHOLDS */ + REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 0, 9), + REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 10, 19), + + /* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */ + REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 20, 20), + REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 21, 21), + [LOW_INT_STATUS_0] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 0, 0), + [LOW_INT_STATUS_1] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 1, 1), + [LOW_INT_STATUS_2] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 2, 2), + [LOW_INT_STATUS_3] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 3, 3), + [LOW_INT_STATUS_4] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 4, 4), + [LOW_INT_STATUS_5] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 5, 5), + [LOW_INT_STATUS_6] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 6, 6), + [LOW_INT_STATUS_7] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 7, 7), + [UP_INT_STATUS_0] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 8, 8), + [UP_INT_STATUS_1] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 9, 9), + [UP_INT_STATUS_2] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 10, 10), + [UP_INT_STATUS_3] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 11, 11), + [UP_INT_STATUS_4] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 12, 12), + [UP_INT_STATUS_5] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 13, 13), + [UP_INT_STATUS_6] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 14, 14), + [UP_INT_STATUS_7] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 15, 15), + + /* NO CRITICAL INTERRUPT SUPPORT on v1 */ + /* Sn_STATUS */ REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9), REG_FIELD_FOR_EACH_SENSOR11(VALID, TM_Sn_STATUS_OFF, 14, 14), + /* xxx_STATUS bits: 1 == threshold violated */ REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10), REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11), REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12), diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c index 0a4f2b8fcab6..a4d15e1abfdd 100644 --- a/drivers/thermal/qcom/tsens-v2.c +++ b/drivers/thermal/qcom/tsens-v2.c @@ -50,9 +50,22 @@ static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = { /* v2 has separate enables for UPPER/LOWER/CRITICAL interrupts */ [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 2), + /* TEMPERATURE THRESHOLDS */ + REG_FIELD_FOR_EACH_SENSOR16(LOW_THRESH, TM_Sn_UPPER_LOWER_THRESHOLD_OFF, 0, 11), + REG_FIELD_FOR_EACH_SENSOR16(UP_THRESH, TM_Sn_UPPER_LOWER_THRESHOLD_OFF, 12, 23), + + /* INTERRUPTS [CLEAR/STATUS/MASK] */ + REG_FIELD_SPLIT_BITS_0_15(LOW_INT_STATUS, TM_UPPER_LOWER_INT_STATUS_OFF), + REG_FIELD_SPLIT_BITS_0_15(LOW_INT_CLEAR, TM_UPPER_LOWER_INT_CLEAR_OFF), + REG_FIELD_SPLIT_BITS_0_15(LOW_INT_MASK, TM_UPPER_LOWER_INT_MASK_OFF), + REG_FIELD_SPLIT_BITS_16_31(UP_INT_STATUS, TM_UPPER_LOWER_INT_STATUS_OFF), + REG_FIELD_SPLIT_BITS_16_31(UP_INT_CLEAR, TM_UPPER_LOWER_INT_CLEAR_OFF), + REG_FIELD_SPLIT_BITS_16_31(UP_INT_MASK, TM_UPPER_LOWER_INT_MASK_OFF), + /* Sn_STATUS */ REG_FIELD_FOR_EACH_SENSOR16(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 11), REG_FIELD_FOR_EACH_SENSOR16(VALID, TM_Sn_STATUS_OFF, 21, 21), + /* xxx_STATUS bits: 1 == threshold violated */ REG_FIELD_FOR_EACH_SENSOR16(MIN_STATUS, TM_Sn_STATUS_OFF, 16, 16), REG_FIELD_FOR_EACH_SENSOR16(LOWER_STATUS, TM_Sn_STATUS_OFF, 17, 17), REG_FIELD_FOR_EACH_SENSOR16(UPPER_STATUS, TM_Sn_STATUS_OFF, 18, 18), diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 772aa76b50e1..eeb68dd261b3 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -78,12 +79,14 @@ MODULE_DEVICE_TABLE(of, tsens_table); static const struct thermal_zone_of_device_ops tsens_of_ops = { .get_temp = tsens_get_temp, .get_trend = tsens_get_trend, + .set_trips = tsens_set_trips, }; static int tsens_register(struct tsens_priv *priv) { - int i; + int i, ret, irq; struct thermal_zone_device *tzd; + struct platform_device *pdev; for (i = 0; i < priv->num_sensors; i++) { priv->sensor[i].priv = priv; @@ -96,7 +99,32 @@ static int tsens_register(struct tsens_priv *priv) if (priv->ops->enable) priv->ops->enable(priv, i); } + + pdev = of_find_device_by_node(priv->dev->of_node); + if (!pdev) + return -ENODEV; + + irq = platform_get_irq_byname(pdev, "uplow"); + if (irq < 0) { + ret = irq; + goto err_put_device; + } + + ret = devm_request_threaded_irq(&pdev->dev, irq, + NULL, tsens_irq_thread, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + dev_name(&pdev->dev), priv); + if (ret) { + dev_err(&pdev->dev, "%s: failed to get irq\n", __func__); + goto err_put_device; + } + + enable_irq_wake(irq); return 0; + +err_put_device: + put_device(&pdev->dev); + return ret; } static int tsens_probe(struct platform_device *pdev) @@ -178,6 +206,7 @@ static int tsens_remove(struct platform_device *pdev) struct tsens_priv *priv = platform_get_drvdata(pdev); debugfs_remove_recursive(priv->debug_root); + tsens_disable_irq(priv); if (priv->ops->disable) priv->ops->disable(priv); diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index e1d6af71b2b9..39b816a8a688 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -13,8 +13,10 @@ #define CAL_DEGC_PT2 120 #define SLOPE_FACTOR 1000 #define SLOPE_DEFAULT 3200 +#define THRESHOLD_MAX_ADC_CODE 0x3ff +#define THRESHOLD_MIN_ADC_CODE 0x0 - +#include #include #include @@ -26,6 +28,11 @@ enum tsens_ver { VER_2_X, }; +enum tsens_irq_type { + LOWER, + UPPER, +}; + /** * struct tsens_sensor - data for each sensor connected to the tsens device * @priv: tsens device instance that this sensor is connected to @@ -99,22 +106,66 @@ struct tsens_ops { [_name##_##14] = REG_FIELD(_offset + 56, _startbit, _stopbit), \ [_name##_##15] = REG_FIELD(_offset + 60, _startbit, _stopbit) -/* reg_field IDs to use as an index into an array */ +#define REG_FIELD_SPLIT_BITS_0_15(_name, _offset) \ + [_name##_##0] = REG_FIELD(_offset, 0, 0), \ + [_name##_##1] = REG_FIELD(_offset, 1, 1), \ + [_name##_##2] = REG_FIELD(_offset, 2, 2), \ + [_name##_##3] = REG_FIELD(_offset, 3, 3), \ + [_name##_##4] = REG_FIELD(_offset, 4, 4), \ + [_name##_##5] = REG_FIELD(_offset, 5, 5), \ + [_name##_##6] = REG_FIELD(_offset, 6, 6), \ + [_name##_##7] = REG_FIELD(_offset, 7, 7), \ + [_name##_##8] = REG_FIELD(_offset, 8, 8), \ + [_name##_##9] = REG_FIELD(_offset, 9, 9), \ + [_name##_##10] = REG_FIELD(_offset, 10, 10), \ + [_name##_##11] = REG_FIELD(_offset, 11, 11), \ + [_name##_##12] = REG_FIELD(_offset, 12, 12), \ + [_name##_##13] = REG_FIELD(_offset, 13, 13), \ + [_name##_##14] = REG_FIELD(_offset, 14, 14), \ + [_name##_##15] = REG_FIELD(_offset, 15, 15) + +#define REG_FIELD_SPLIT_BITS_16_31(_name, _offset) \ + [_name##_##0] = REG_FIELD(_offset, 16, 16), \ + [_name##_##1] = REG_FIELD(_offset, 17, 17), \ + [_name##_##2] = REG_FIELD(_offset, 18, 18), \ + [_name##_##3] = REG_FIELD(_offset, 19, 19), \ + [_name##_##4] = REG_FIELD(_offset, 20, 20), \ + [_name##_##5] = REG_FIELD(_offset, 21, 21), \ + [_name##_##6] = REG_FIELD(_offset, 22, 22), \ + [_name##_##7] = REG_FIELD(_offset, 23, 23), \ + [_name##_##8] = REG_FIELD(_offset, 24, 24), \ + [_name##_##9] = REG_FIELD(_offset, 25, 25), \ + [_name##_##10] = REG_FIELD(_offset, 26, 26), \ + [_name##_##11] = REG_FIELD(_offset, 27, 27), \ + [_name##_##12] = REG_FIELD(_offset, 28, 28), \ + [_name##_##13] = REG_FIELD(_offset, 29, 29), \ + [_name##_##14] = REG_FIELD(_offset, 30, 30), \ + [_name##_##15] = REG_FIELD(_offset, 31, 31) + +/* + * reg_field IDs to use as an index into an array + * If you change the order of the entries, check the devm_regmap_field_alloc() + * calls in init_common() + */ enum regfield_ids { /* ----- SROT ------ */ /* HW_VER */ - VER_MAJOR = 0, + VER_MAJOR, VER_MINOR, VER_STEP, /* CTRL_OFFSET */ - TSENS_EN = 3, + TSENS_EN, TSENS_SW_RST, SENSOR_EN, CODE_OR_TEMP, /* ----- TM ------ */ + /* TRDY */ + TRDY, + /* INTERRUPT ENABLE */ + INT_EN, /* v2+ has separate enables for crit, upper and lower irq */ /* STATUS */ - LAST_TEMP_0 = 7, /* Last temperature reading */ + LAST_TEMP_0, /* Last temperature reading */ LAST_TEMP_1, LAST_TEMP_2, LAST_TEMP_3, @@ -130,7 +181,7 @@ enum regfield_ids { LAST_TEMP_13, LAST_TEMP_14, LAST_TEMP_15, - VALID_0 = 23, /* VALID reading or not */ + VALID_0, /* VALID reading or not */ VALID_1, VALID_2, VALID_3, @@ -146,38 +197,6 @@ enum regfield_ids { VALID_13, VALID_14, VALID_15, - MIN_STATUS_0, /* MIN threshold violated */ - MIN_STATUS_1, - MIN_STATUS_2, - MIN_STATUS_3, - MIN_STATUS_4, - MIN_STATUS_5, - MIN_STATUS_6, - MIN_STATUS_7, - MIN_STATUS_8, - MIN_STATUS_9, - MIN_STATUS_10, - MIN_STATUS_11, - MIN_STATUS_12, - MIN_STATUS_13, - MIN_STATUS_14, - MIN_STATUS_15, - MAX_STATUS_0, /* MAX threshold violated */ - MAX_STATUS_1, - MAX_STATUS_2, - MAX_STATUS_3, - MAX_STATUS_4, - MAX_STATUS_5, - MAX_STATUS_6, - MAX_STATUS_7, - MAX_STATUS_8, - MAX_STATUS_9, - MAX_STATUS_10, - MAX_STATUS_11, - MAX_STATUS_12, - MAX_STATUS_13, - MAX_STATUS_14, - MAX_STATUS_15, LOWER_STATUS_0, /* LOWER threshold violated */ LOWER_STATUS_1, LOWER_STATUS_2, @@ -194,6 +213,70 @@ enum regfield_ids { LOWER_STATUS_13, LOWER_STATUS_14, LOWER_STATUS_15, + LOW_INT_STATUS_0, /* LOWER interrupt status */ + LOW_INT_STATUS_1, + LOW_INT_STATUS_2, + LOW_INT_STATUS_3, + LOW_INT_STATUS_4, + LOW_INT_STATUS_5, + LOW_INT_STATUS_6, + LOW_INT_STATUS_7, + LOW_INT_STATUS_8, + LOW_INT_STATUS_9, + LOW_INT_STATUS_10, + LOW_INT_STATUS_11, + LOW_INT_STATUS_12, + LOW_INT_STATUS_13, + LOW_INT_STATUS_14, + LOW_INT_STATUS_15, + LOW_INT_CLEAR_0, /* LOWER interrupt clear */ + LOW_INT_CLEAR_1, + LOW_INT_CLEAR_2, + LOW_INT_CLEAR_3, + LOW_INT_CLEAR_4, + LOW_INT_CLEAR_5, + LOW_INT_CLEAR_6, + LOW_INT_CLEAR_7, + LOW_INT_CLEAR_8, + LOW_INT_CLEAR_9, + LOW_INT_CLEAR_10, + LOW_INT_CLEAR_11, + LOW_INT_CLEAR_12, + LOW_INT_CLEAR_13, + LOW_INT_CLEAR_14, + LOW_INT_CLEAR_15, + LOW_INT_MASK_0, /* LOWER interrupt mask */ + LOW_INT_MASK_1, + LOW_INT_MASK_2, + LOW_INT_MASK_3, + LOW_INT_MASK_4, + LOW_INT_MASK_5, + LOW_INT_MASK_6, + LOW_INT_MASK_7, + LOW_INT_MASK_8, + LOW_INT_MASK_9, + LOW_INT_MASK_10, + LOW_INT_MASK_11, + LOW_INT_MASK_12, + LOW_INT_MASK_13, + LOW_INT_MASK_14, + LOW_INT_MASK_15, + LOW_THRESH_0, /* LOWER threshold values */ + LOW_THRESH_1, + LOW_THRESH_2, + LOW_THRESH_3, + LOW_THRESH_4, + LOW_THRESH_5, + LOW_THRESH_6, + LOW_THRESH_7, + LOW_THRESH_8, + LOW_THRESH_9, + LOW_THRESH_10, + LOW_THRESH_11, + LOW_THRESH_12, + LOW_THRESH_13, + LOW_THRESH_14, + LOW_THRESH_15, UPPER_STATUS_0, /* UPPER threshold violated */ UPPER_STATUS_1, UPPER_STATUS_2, @@ -210,6 +293,70 @@ enum regfield_ids { UPPER_STATUS_13, UPPER_STATUS_14, UPPER_STATUS_15, + UP_INT_STATUS_0, /* UPPER interrupt status */ + UP_INT_STATUS_1, + UP_INT_STATUS_2, + UP_INT_STATUS_3, + UP_INT_STATUS_4, + UP_INT_STATUS_5, + UP_INT_STATUS_6, + UP_INT_STATUS_7, + UP_INT_STATUS_8, + UP_INT_STATUS_9, + UP_INT_STATUS_10, + UP_INT_STATUS_11, + UP_INT_STATUS_12, + UP_INT_STATUS_13, + UP_INT_STATUS_14, + UP_INT_STATUS_15, + UP_INT_CLEAR_0, /* UPPER interrupt clear */ + UP_INT_CLEAR_1, + UP_INT_CLEAR_2, + UP_INT_CLEAR_3, + UP_INT_CLEAR_4, + UP_INT_CLEAR_5, + UP_INT_CLEAR_6, + UP_INT_CLEAR_7, + UP_INT_CLEAR_8, + UP_INT_CLEAR_9, + UP_INT_CLEAR_10, + UP_INT_CLEAR_11, + UP_INT_CLEAR_12, + UP_INT_CLEAR_13, + UP_INT_CLEAR_14, + UP_INT_CLEAR_15, + UP_INT_MASK_0, /* UPPER interrupt mask */ + UP_INT_MASK_1, + UP_INT_MASK_2, + UP_INT_MASK_3, + UP_INT_MASK_4, + UP_INT_MASK_5, + UP_INT_MASK_6, + UP_INT_MASK_7, + UP_INT_MASK_8, + UP_INT_MASK_9, + UP_INT_MASK_10, + UP_INT_MASK_11, + UP_INT_MASK_12, + UP_INT_MASK_13, + UP_INT_MASK_14, + UP_INT_MASK_15, + UP_THRESH_0, /* UPPER threshold values */ + UP_THRESH_1, + UP_THRESH_2, + UP_THRESH_3, + UP_THRESH_4, + UP_THRESH_5, + UP_THRESH_6, + UP_THRESH_7, + UP_THRESH_8, + UP_THRESH_9, + UP_THRESH_10, + UP_THRESH_11, + UP_THRESH_12, + UP_THRESH_13, + UP_THRESH_14, + UP_THRESH_15, CRITICAL_STATUS_0, /* CRITICAL threshold violated */ CRITICAL_STATUS_1, CRITICAL_STATUS_2, @@ -226,13 +373,38 @@ enum regfield_ids { CRITICAL_STATUS_13, CRITICAL_STATUS_14, CRITICAL_STATUS_15, - /* TRDY */ - TRDY, - /* INTERRUPT ENABLE */ - INT_EN, /* Pre-V1, V1.x */ - LOW_INT_EN, /* V2.x */ - UP_INT_EN, /* V2.x */ - CRIT_INT_EN, /* V2.x */ + MIN_STATUS_0, /* MIN threshold violated */ + MIN_STATUS_1, + MIN_STATUS_2, + MIN_STATUS_3, + MIN_STATUS_4, + MIN_STATUS_5, + MIN_STATUS_6, + MIN_STATUS_7, + MIN_STATUS_8, + MIN_STATUS_9, + MIN_STATUS_10, + MIN_STATUS_11, + MIN_STATUS_12, + MIN_STATUS_13, + MIN_STATUS_14, + MIN_STATUS_15, + MAX_STATUS_0, /* MAX threshold violated */ + MAX_STATUS_1, + MAX_STATUS_2, + MAX_STATUS_3, + MAX_STATUS_4, + MAX_STATUS_5, + MAX_STATUS_6, + MAX_STATUS_7, + MAX_STATUS_8, + MAX_STATUS_9, + MAX_STATUS_10, + MAX_STATUS_11, + MAX_STATUS_12, + MAX_STATUS_13, + MAX_STATUS_14, + MAX_STATUS_15, /* Keep last */ MAX_REGFIELDS @@ -302,6 +474,10 @@ struct tsens_priv { struct regmap *tm_map; struct regmap *srot_map; u32 tm_offset; + + /* lock for upper/lower threshold interrupts */ + spinlock_t ul_lock; + struct regmap_field *rf[MAX_REGFIELDS]; struct tsens_context ctx; const struct tsens_features *feat; @@ -319,6 +495,10 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mo int init_common(struct tsens_priv *priv); int get_temp_tsens_valid(struct tsens_sensor *s, int *temp); int get_temp_common(struct tsens_sensor *s, int *temp); +int tsens_enable_irq(struct tsens_priv *priv); +void tsens_disable_irq(struct tsens_priv *priv); +int tsens_set_trips(void *_sensor, int low, int high); +irqreturn_t tsens_irq_thread(int irq, void *data); /* TSENS target */ extern const struct tsens_plat_data data_8960;