From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on archive.lwn.net X-Spam-Level: X-Spam-Status: No, score=-5.6 required=5.0 tests=DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by archive.lwn.net (Postfix) with ESMTP id 204E27DF8D for ; Fri, 25 May 2018 19:38:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S967858AbeEYThr (ORCPT ); Fri, 25 May 2018 15:37:47 -0400 Received: from bh-25.webhostbox.net ([208.91.199.152]:50384 "EHLO bh-25.webhostbox.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S967951AbeEYTh1 (ORCPT ); Fri, 25 May 2018 15:37:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=roeck-us.net; s=default; h=In-Reply-To:Content-Transfer-Encoding: Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date: Sender:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=kAnUa/m+O/zSYv0JNqoaRsm4OYxU4EaU2ZVKgjeVnl4=; b=vjb2wnqfJkNdX8qJnUU5cXT5u2 1gbmXrXaAtznXJMSDY109dp23Uo+QFGRwDq5R0jI66nYV5fx/TVuHoQ+YxyVuhexEYs+hOJpMKesY gEGWGpUSvpROhUV+U35BImYIWXgpIs0bc2aMmM5nrucIJkciXRVLOWgV5XfPbCH07VCA6IP+CvZNM b/T1m8Hv4DQdMdN6OuaUZdWmvfHhOzQ8UY7xPjpato0e04ZyoALjvt56y5A3ArJjxLhhTc28vSsM8 bjefyGYiN6VHYLLFi2HdhHtiN7PqkQz/0wKFaNUAnf80YyOq0doSK+t0hFXwj10sv075G7lQGda/o uCRIrAcQ==; Received: from 108-223-40-66.lightspeed.sntcca.sbcglobal.net ([108.223.40.66]:43644 helo=localhost) by bh-25.webhostbox.net with esmtpa (Exim 4.89) (envelope-from ) id 1fMIWh-001n5z-P4; Fri, 25 May 2018 19:37:24 +0000 Date: Fri, 25 May 2018 12:37:17 -0700 From: Guenter Roeck To: Stefan Wahren Cc: Jean Delvare , Jonathan Corbet , Eric Anholt , Florian Fainelli , Ray Jui , Scott Branden , Phil Elwell , bcm-kernel-feedback-list@broadcom.com, linux-arm-kernel@lists.infradead.org, linux-rpi-kernel@lists.infradead.org, linux-hwmon@vger.kernel.org, linux-doc@vger.kernel.org, Noralf =?iso-8859-1?Q?Tr=F8nnes?= Subject: Re: [PATCH V3 2/6] hwmon: Add support for RPi voltage sensor Message-ID: <20180525193717.GA24967@roeck-us.net> References: <1527276279-23876-1-git-send-email-stefan.wahren@i2se.com> <1527276279-23876-3-git-send-email-stefan.wahren@i2se.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1527276279-23876-3-git-send-email-stefan.wahren@i2se.com> User-Agent: Mutt/1.5.24 (2015-08-30) X-Authenticated_sender: guenter@roeck-us.net X-OutGoing-Spam-Status: No, score=-1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - bh-25.webhostbox.net X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - roeck-us.net X-Get-Message-Sender-Via: bh-25.webhostbox.net: authenticated_id: guenter@roeck-us.net X-Authenticated-Sender: bh-25.webhostbox.net: guenter@roeck-us.net X-Source: X-Source-Args: X-Source-Dir: Sender: linux-doc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-doc@vger.kernel.org On Fri, May 25, 2018 at 09:24:35PM +0200, Stefan Wahren wrote: > Currently there is no easy way to detect undervoltage conditions on a > remote Raspberry Pi. This hwmon driver retrieves the state of the > undervoltage sensor via mailbox interface. The handling based on > Noralf's modifications to the downstream firmware driver. In case of > an undervoltage condition only an entry is written to the kernel log. > > CC: "Noralf Trønnes" > Signed-off-by: Stefan Wahren Acked-by: Guenter Roeck ... assuming this will go through some arm tree. > --- > Documentation/hwmon/raspberrypi-hwmon | 22 +++++ > drivers/hwmon/Kconfig | 10 ++ > drivers/hwmon/Makefile | 1 + > drivers/hwmon/raspberrypi-hwmon.c | 166 ++++++++++++++++++++++++++++++++++ > 4 files changed, 199 insertions(+) > create mode 100644 Documentation/hwmon/raspberrypi-hwmon > create mode 100644 drivers/hwmon/raspberrypi-hwmon.c > > diff --git a/Documentation/hwmon/raspberrypi-hwmon b/Documentation/hwmon/raspberrypi-hwmon > new file mode 100644 > index 0000000..3c92e2c > --- /dev/null > +++ b/Documentation/hwmon/raspberrypi-hwmon > @@ -0,0 +1,22 @@ > +Kernel driver raspberrypi-hwmon > +=============================== > + > +Supported boards: > + * Raspberry Pi A+ (via GPIO on SoC) > + * Raspberry Pi B+ (via GPIO on SoC) > + * Raspberry Pi 2 B (via GPIO on SoC) > + * Raspberry Pi 3 B (via GPIO on port expander) > + * Raspberry Pi 3 B+ (via PMIC) > + > +Author: Stefan Wahren > + > +Description > +----------- > + > +This driver periodically polls a mailbox property of the VC4 firmware to detect > +undervoltage conditions. > + > +Sysfs entries > +------------- > + > +in0_lcrit_alarm Undervoltage alarm > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > index f10840a..fdaab82 100644 > --- a/drivers/hwmon/Kconfig > +++ b/drivers/hwmon/Kconfig > @@ -1298,6 +1298,16 @@ config SENSORS_PWM_FAN > This driver can also be built as a module. If so, the module > will be called pwm-fan. > > +config SENSORS_RASPBERRYPI_HWMON > + tristate "Raspberry Pi voltage monitor" > + depends on RASPBERRYPI_FIRMWARE || COMPILE_TEST > + help > + If you say yes here you get support for voltage sensor on the > + Raspberry Pi. > + > + This driver can also be built as a module. If so, the module > + will be called raspberrypi-hwmon. > + > config SENSORS_SHT15 > tristate "Sensiron humidity and temperature sensors. SHT15 and compat." > depends on GPIOLIB || COMPILE_TEST > diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile > index e7d52a3..a929770 100644 > --- a/drivers/hwmon/Makefile > +++ b/drivers/hwmon/Makefile > @@ -141,6 +141,7 @@ obj-$(CONFIG_SENSORS_PC87427) += pc87427.o > obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o > obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o > obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o > +obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o > obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o > obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o > obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o > diff --git a/drivers/hwmon/raspberrypi-hwmon.c b/drivers/hwmon/raspberrypi-hwmon.c > new file mode 100644 > index 0000000..fb4e4a6 > --- /dev/null > +++ b/drivers/hwmon/raspberrypi-hwmon.c > @@ -0,0 +1,166 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Raspberry Pi voltage sensor driver > + * > + * Based on firmware/raspberrypi.c by Noralf Trønnes > + * > + * Copyright (C) 2018 Stefan Wahren > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define UNDERVOLTAGE_STICKY_BIT BIT(16) > + > +struct rpi_hwmon_data { > + struct device *hwmon_dev; > + struct rpi_firmware *fw; > + u32 last_throttled; > + struct delayed_work get_values_poll_work; > +}; > + > +static void rpi_firmware_get_throttled(struct rpi_hwmon_data *data) > +{ > + u32 new_uv, old_uv, value; > + int ret; > + > + /* Request firmware to clear sticky bits */ > + value = 0xffff; > + > + ret = rpi_firmware_property(data->fw, RPI_FIRMWARE_GET_THROTTLED, > + &value, sizeof(value)); > + if (ret) { > + dev_err_once(data->hwmon_dev, "Failed to get throttled (%d)\n", > + ret); > + return; > + } > + > + new_uv = value & UNDERVOLTAGE_STICKY_BIT; > + old_uv = data->last_throttled & UNDERVOLTAGE_STICKY_BIT; > + data->last_throttled = value; > + > + if (new_uv == old_uv) > + return; > + > + if (new_uv) > + dev_crit(data->hwmon_dev, "Undervoltage detected!\n"); > + else > + dev_info(data->hwmon_dev, "Voltage normalised\n"); > + > + sysfs_notify(&data->hwmon_dev->kobj, NULL, "in0_lcrit_alarm"); > +} > + > +static void get_values_poll(struct work_struct *work) > +{ > + struct rpi_hwmon_data *data; > + > + data = container_of(work, struct rpi_hwmon_data, > + get_values_poll_work.work); > + > + rpi_firmware_get_throttled(data); > + > + /* > + * We can't run faster than the sticky shift (100ms) since we get > + * flipping in the sticky bits that are cleared. > + */ > + schedule_delayed_work(&data->get_values_poll_work, 2 * HZ); > +} > + > +static int rpi_read(struct device *dev, enum hwmon_sensor_types type, > + u32 attr, int channel, long *val) > +{ > + struct rpi_hwmon_data *data = dev_get_drvdata(dev); > + > + *val = !!(data->last_throttled & UNDERVOLTAGE_STICKY_BIT); > + return 0; > +} > + > +static umode_t rpi_is_visible(const void *_data, enum hwmon_sensor_types type, > + u32 attr, int channel) > +{ > + return 0444; > +} > + > +static const u32 rpi_in_config[] = { > + HWMON_I_LCRIT_ALARM, > + 0 > +}; > + > +static const struct hwmon_channel_info rpi_in = { > + .type = hwmon_in, > + .config = rpi_in_config, > +}; > + > +static const struct hwmon_channel_info *rpi_info[] = { > + &rpi_in, > + NULL > +}; > + > +static const struct hwmon_ops rpi_hwmon_ops = { > + .is_visible = rpi_is_visible, > + .read = rpi_read, > +}; > + > +static const struct hwmon_chip_info rpi_chip_info = { > + .ops = &rpi_hwmon_ops, > + .info = rpi_info, > +}; > + > +static int rpi_hwmon_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct rpi_hwmon_data *data; > + int ret; > + > + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); > + if (!data) > + return -ENOMEM; > + > + /* Parent driver assure that firmware is correct */ > + data->fw = dev_get_drvdata(dev->parent); > + > + /* Init throttled */ > + ret = rpi_firmware_property(data->fw, RPI_FIRMWARE_GET_THROTTLED, > + &data->last_throttled, > + sizeof(data->last_throttled)); > + > + data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "rpi_volt", > + data, > + &rpi_chip_info, > + NULL); > + > + INIT_DELAYED_WORK(&data->get_values_poll_work, get_values_poll); > + platform_set_drvdata(pdev, data); > + > + if (!PTR_ERR_OR_ZERO(data->hwmon_dev)) > + schedule_delayed_work(&data->get_values_poll_work, 2 * HZ); > + > + return PTR_ERR_OR_ZERO(data->hwmon_dev); > +} > + > +static int rpi_hwmon_remove(struct platform_device *pdev) > +{ > + struct rpi_hwmon_data *data = platform_get_drvdata(pdev); > + > + cancel_delayed_work_sync(&data->get_values_poll_work); > + > + return 0; > +} > + > +static struct platform_driver rpi_hwmon_driver = { > + .probe = rpi_hwmon_probe, > + .remove = rpi_hwmon_remove, > + .driver = { > + .name = "raspberrypi-hwmon", > + }, > +}; > +module_platform_driver(rpi_hwmon_driver); > + > +MODULE_AUTHOR("Stefan Wahren "); > +MODULE_DESCRIPTION("Raspberry Pi voltage sensor driver"); > +MODULE_LICENSE("GPL v2"); > -- > 2.7.4 > -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html