Received: by 10.223.185.116 with SMTP id b49csp591302wrg; Fri, 23 Feb 2018 03:47:51 -0800 (PST) X-Google-Smtp-Source: AH8x225ZtRNUQ9gsBle5I5jBN8KfYz4LLowuiL2CNK8v5zS4BH3NYY8ZfLLowVr+xnJUnc0avEnE X-Received: by 10.101.65.203 with SMTP id b11mr1253640pgq.118.1519386470960; Fri, 23 Feb 2018 03:47:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519386470; cv=none; d=google.com; s=arc-20160816; b=X9o6xN7GPntAsYGOtgCx0JoO3aazYce7U6PsQRfASMs9PmtL1jrAHOXdL8OW7FCsao EknI8rDAAZrXlUkGu0rzsqhUrPM0Xw8FZ5WGWVxQbg/m2uMqAjWxrRm/vDytxH700zj9 ypU9rswsHAAndfS5ZgT1fB9DwkDHBrGw1fe9aCOTG8jtFf21m//1CVxKA78EhKk+KV1y 0WmhE/Qyj5nQg4dd+WpF1Y7XvLnNryZbL6PO1imWJmz69fx9beGB4Aw+DHdVyWDwr5Ue CutKUXxJ2xp9P/lFrkqlAnOQcAnc+cWd2rv6aEZ2sx07WKhAnL94GEm+dyaU1W/0xJBa IoBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:in-reply-to :mime-version:user-agent:date:message-id:from:cc:references:to :subject:arc-authentication-results; bh=av1utIvHNUBZT+yVtdLOGoIKvRZk8Nbly33asP7Htmg=; b=cMN+AbuuLVLUtyJ31R267pyntnTk7D86R5dk/CBseYyJbi8r3mN+jizEq4cEYGvJfH d34A5G6K2DluJntNhOHmRh1nfpXbMdJOlQyieHgCkBCC8suriS1eluAN9iYU8r8Q4qQ/ XZEEbPp3Su2Zps4PjPV5rXTYGZkcwE9kvjkvwT94NjpbHOBf3yTvGqZe1CvUJ5H4eMbi KEuS1+fn039fh8DKe2zRykQpHRYUDz4DIX45/gNTbHSd7cGtXv5Bf1bcbzHCDEE8W0Ee i5Xfqypep/Gfg6Bst3yr8nQXkbKqQ378TXy7bETrjGh5g+ud5zGXGfIAgp6HYWT0CM9O 2FyQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c12-v6si1689918plo.278.2018.02.23.03.47.36; Fri, 23 Feb 2018 03:47:50 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751547AbeBWLqH (ORCPT + 99 others); Fri, 23 Feb 2018 06:46:07 -0500 Received: from hqemgate15.nvidia.com ([216.228.121.64]:11126 "EHLO hqemgate15.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750827AbeBWLqD (ORCPT ); Fri, 23 Feb 2018 06:46:03 -0500 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate15.nvidia.com id ; Fri, 23 Feb 2018 03:46:08 -0800 Received: from HQMAIL101.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Fri, 23 Feb 2018 03:46:02 -0800 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Fri, 23 Feb 2018 03:46:02 -0800 Received: from BGMAIL103.nvidia.com (10.25.59.12) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Fri, 23 Feb 2018 11:45:57 +0000 Received: from [10.19.65.123] (10.19.65.123) by bgmail103.nvidia.com (10.25.59.12) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Fri, 23 Feb 2018 11:45:29 +0000 Subject: Re: [PATCH 05/10] hwmon: generic-pwm-tachometer: Add generic PWM based tachometer To: Guenter Roeck , Mikko Perttunen References: <1519196339-9377-1-git-send-email-rrajk@nvidia.com> <1519196339-9377-6-git-send-email-rrajk@nvidia.com> <20180221160833.GA8063@roeck-us.net> CC: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , From: RAJKUMAR Message-ID: Date: Fri, 23 Feb 2018 17:15:26 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <20180221160833.GA8063@roeck-us.net> X-Originating-IP: [10.19.65.123] X-ClientProxiedBy: BGMAIL103.nvidia.com (10.25.59.12) To bgmail103.nvidia.com (10.25.59.12) Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wednesday 21 February 2018 09:38 PM, Guenter Roeck wrote: > On Wed, Feb 21, 2018 at 05:20:29PM +0200, Mikko Perttunen wrote: >> On 21.02.2018 16:46, Guenter Roeck wrote: >>> On 02/20/2018 11:15 PM, Mikko Perttunen wrote: >>>> AIUI, the PWM framework already exposes a sysfs node with period >>>> information. We should just use that instead of adding a new driver >>>> for this. >>>> >>> I am kind of lost. Please explain. >>> >>> Are you saying that we should drop the pwm-fan driver as well (which goes >>> the opposite way), as well as any other drivers doing anything with pwm >>> signals, >>> because after all those signals are already exposed to userspace a sysfs >>> attributes, >>> and a kernel driver to abstract those values is thus not needed ? >> The only thing this driver does is do a constant division in kernelspace. >> I'm not really seeing why that couldn't be done in userspace. But if you >> think it's appropriate to do the RPM conversion in kernelspace then I'm not >> greatly opposed to that. >> > Isn't that true for any conversion from and to pwm values ? Voltages, > for example ? Should those be handled in userspace as well ? > > Note that I am not entirely convinced that the approach suggested in this > patch series makes sense. Patch 4 seems to move the notion of a tachometer > into the pwm subsystem. I am not really convinced that this makes sense > (maybe all that code should be in the hwmon driver instead, or in a thermal > driver if the author prefers). But that is a different issue. The question > you raised is if there should be any abstraction to or from raw pwm values > in the kernel. Since tachometer driver implements PWM capture callback feature, I have added it under pwm driver as pwm-tegra-tachometer.c driver. If the best approach is to have this tachometer driver under hwmon driver then I will move it to hwmon driver. > >>>> In any case, we cannot add something like this to device tree since >>>> it's not a hardware device. >>>> >>> So you are saying there is no means to express in devicetree that >>> a pwm input is connected to a fan ? How is that not hardware ? >>> >>> If so, how do you express in devicetree that a pwm signal is connected >>> to anything ? >> If we want to describe that the tachometer is connected to a fan, then we >> should have a fan node in the board's device tree. We don't have a chip that >> has a thing called "generic-pwm-tachometer" attached to it. (We have chips >> that have a "nvidia,tegra186-tachometer", so it's proper to have that.) >> > So you are concerned about the property name ? I don't really care how > it is called. > > Guenter > >> Thanks, >> Mikko >> >>> Guenter >>> >>>> Mikko >>>> >>>> On 21.02.2018 08:58, Rajkumar Rampelli wrote: >>>>> Add generic PWM based tachometer driver via HWMON interface >>>>> to report the RPM of motor. This drivers get the period/duty >>>>> cycle from PWM IP which captures the motor PWM output. >>>>> >>>>> This driver implements a simple interface for monitoring the speed of >>>>> a fan and exposes it in roatations per minute (RPM) to the user space >>>>> by using the hwmon's sysfs interface >>>>> >>>>> Signed-off-by: Rajkumar Rampelli >>>>> --- >>>>> Documentation/hwmon/generic-pwm-tachometer | 17 +++++ >>>>> drivers/hwmon/Kconfig | 10 +++ >>>>> drivers/hwmon/Makefile | 1 + >>>>> drivers/hwmon/generic-pwm-tachometer.c | 112 >>>>> +++++++++++++++++++++++++++++ >>>>> 4 files changed, 140 insertions(+) >>>>> create mode 100644 Documentation/hwmon/generic-pwm-tachometer >>>>> create mode 100644 drivers/hwmon/generic-pwm-tachometer.c >>>>> >>>>> diff --git a/Documentation/hwmon/generic-pwm-tachometer >>>>> b/Documentation/hwmon/generic-pwm-tachometer >>>>> new file mode 100644 >>>>> index 0000000..e0713ee >>>>> --- /dev/null >>>>> +++ b/Documentation/hwmon/generic-pwm-tachometer >>>>> @@ -0,0 +1,17 @@ >>>>> +Kernel driver generic-pwm-tachometer >>>>> +==================================== >>>>> + >>>>> +This driver enables the use of a PWM module to monitor a fan. It >>>>> uses the >>>>> +generic PWM interface and can be used on SoCs as along as the SoC >>>>> supports >>>>> +Tachometer controller that moniors the Fan speed in periods. >>>>> + >>>>> +Author: Rajkumar Rampelli >>>>> + >>>>> +Description >>>>> +----------- >>>>> + >>>>> +The driver implements a simple interface for monitoring the Fan >>>>> speed using >>>>> +PWM module and Tachometer controller. It requests period value >>>>> through PWM >>>>> +capture interface to Tachometer and measures the Rotations per >>>>> minute using >>>>> +received period value. It exposes the Fan speed in RPM to the user >>>>> space by >>>>> +using the hwmon's sysfs interface. >>>>> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig >>>>> index ef23553..8912dcb 100644 >>>>> --- a/drivers/hwmon/Kconfig >>>>> +++ b/drivers/hwmon/Kconfig >>>>> @@ -1878,6 +1878,16 @@ config SENSORS_XGENE >>>>> If you say yes here you get support for the temperature >>>>> and power sensors for APM X-Gene SoC. >>>>> >>>>> +config GENERIC_PWM_TACHOMETER >>>>> + tristate "Generic PWM based tachometer driver" >>>>> + depends on PWM >>>>> + help >>>>> + Enables a driver to use PWM signal from motor to use >>>>> + for measuring the motor speed. The RPM is captured by >>>>> + PWM modules which has PWM capture capability and this >>>>> + drivers reads the captured data from PWM IP to convert >>>>> + it to speed in RPM. >>>>> + >>>>> if ACPI >>>>> >>>>> comment "ACPI drivers" >>>>> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile >>>>> index f814b4a..9dcc374 100644 >>>>> --- a/drivers/hwmon/Makefile >>>>> +++ b/drivers/hwmon/Makefile >>>>> @@ -175,6 +175,7 @@ obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o >>>>> obj-$(CONFIG_SENSORS_XGENE) += xgene-hwmon.o >>>>> >>>>> obj-$(CONFIG_PMBUS) += pmbus/ >>>>> +obj-$(CONFIG_GENERIC_PWM_TACHOMETER) += generic-pwm-tachometer.o >>>>> >>>>> ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG >>>>> >>>>> diff --git a/drivers/hwmon/generic-pwm-tachometer.c >>>>> b/drivers/hwmon/generic-pwm-tachometer.c >>>>> new file mode 100644 >>>>> index 0000000..9354d43 >>>>> --- /dev/null >>>>> +++ b/drivers/hwmon/generic-pwm-tachometer.c >>>>> @@ -0,0 +1,112 @@ >>>>> +/* >>>>> + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. >>>>> + * >>>>> + * This program is free software; you can redistribute it and/or >>>>> modify it >>>>> + * under the terms and conditions of the GNU General Public License, >>>>> + * version 2, as published by the Free Software Foundation. >>>>> + * >>>>> + * This program is distributed in the hope it will be useful, but >>>>> WITHOUT >>>>> + * ANY WARRANTY; without even the implied warranty of >>>>> MERCHANTABILITY or >>>>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public >>>>> License for >>>>> + * more details. >>>>> + * >>>>> + */ >>>>> + >>>>> +#include >>>>> +#include >>>>> +#include >>>>> +#include >>>>> +#include >>>>> +#include >>>>> + >>>>> +struct pwm_hwmon_tach { >>>>> + struct device *dev; >>>>> + struct pwm_device *pwm; >>>>> + struct device *hwmon; >>>>> +}; >>>>> + >>>>> +static ssize_t show_rpm(struct device *dev, struct device_attribute >>>>> *attr, >>>>> + char *buf) >>>>> +{ >>>>> + struct pwm_hwmon_tach *ptt = dev_get_drvdata(dev); >>>>> + struct pwm_device *pwm = ptt->pwm; >>>>> + struct pwm_capture result; >>>>> + int err; >>>>> + unsigned int rpm = 0; >>>>> + >>>>> + err = pwm_capture(pwm, &result, 0); >>>>> + if (err < 0) { >>>>> + dev_err(ptt->dev, "Failed to capture PWM: %d\n", err); >>>>> + return err; >>>>> + } >>>>> + >>>>> + if (result.period) >>>>> + rpm = DIV_ROUND_CLOSEST_ULL(60ULL * NSEC_PER_SEC, >>>>> + result.period); >>>>> + >>>>> + return sprintf(buf, "%u\n", rpm); >>>>> +} >>>>> + >>>>> +static SENSOR_DEVICE_ATTR(rpm, 0444, show_rpm, NULL, 0); >>>>> + >>>>> +static struct attribute *pwm_tach_attrs[] = { >>>>> + &sensor_dev_attr_rpm.dev_attr.attr, >>>>> + NULL, >>>>> +}; >>>>> + >>>>> +ATTRIBUTE_GROUPS(pwm_tach); >>>>> + >>>>> +static int pwm_tach_probe(struct platform_device *pdev) >>>>> +{ >>>>> + struct pwm_hwmon_tach *ptt; >>>>> + int err; >>>>> + >>>>> + ptt = devm_kzalloc(&pdev->dev, sizeof(*ptt), GFP_KERNEL); >>>>> + if (!ptt) >>>>> + return -ENOMEM; >>>>> + >>>>> + ptt->dev = &pdev->dev; >>>>> + >>>>> + platform_set_drvdata(pdev, ptt); >>>>> + dev_set_drvdata(&pdev->dev, ptt); >>>>> + >>>>> + ptt->pwm = devm_of_pwm_get(&pdev->dev, pdev->dev.of_node, NULL); >>>>> + if (IS_ERR(ptt->pwm)) { >>>>> + err = PTR_ERR(ptt->pwm); >>>>> + dev_err(&pdev->dev, "Failed to get pwm handle, err: %d\n", >>>>> + err); >>>>> + return err; >>>>> + } >>>>> + >>>>> + ptt->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, >>>>> + "pwm_tach", ptt, pwm_tach_groups); >>>>> + if (IS_ERR(ptt->hwmon)) { >>>>> + err = PTR_ERR_OR_ZERO(ptt->hwmon); >>>>> + dev_err(&pdev->dev, "Failed to register hwmon device: %d\n", >>>>> + err); >>>>> + return err; >>>>> + } >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +static const struct of_device_id pwm_tach_of_match[] = { >>>>> + { .compatible = "generic-pwm-tachometer" }, >>>>> + {} >>>>> +}; >>>>> +MODULE_DEVICE_TABLE(of, pwm_tach_of_match); >>>>> + >>>>> +static struct platform_driver pwm_tach_driver = { >>>>> + .driver = { >>>>> + .name = "generic-pwm-tachometer", >>>>> + .of_match_table = pwm_tach_of_match, >>>>> + }, >>>>> + .probe = pwm_tach_probe, >>>>> +}; >>>>> + >>>>> +module_platform_driver(pwm_tach_driver); >>>>> + >>>>> +MODULE_DESCRIPTION("PWM based Generic Tachometer driver"); >>>>> +MODULE_AUTHOR("Laxman Dewangan "); >>>>> +MODULE_AUTHOR("Rajkumar Rampelli "); >>>>> +MODULE_LICENSE("GPL v2"); >>>>>