From patchwork Mon May 15 21:21:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 9727985 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 80CD660386 for ; Mon, 15 May 2017 21:21:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8987B28414 for ; Mon, 15 May 2017 21:21:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7D15B289B9; Mon, 15 May 2017 21:21:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 946A128414 for ; Mon, 15 May 2017 21:21:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758272AbdEOVVG (ORCPT ); Mon, 15 May 2017 17:21:06 -0400 Received: from vern.gendns.com ([206.190.152.46]:57480 "EHLO vern.gendns.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758294AbdEOVVF (ORCPT ); Mon, 15 May 2017 17:21:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lechnology.com; s=default; h=Message-Id:Date:Subject:Cc:To:From:Sender: Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=LrXrFFXskKm7dwdb9Q3cBJq05pB0RjCigZa91JJMuFs=; b=i1KyIUzz+8Yy3VOscFx26m9896 oNHvl+Tou0TgSt9Qs2t/3opqnVuOpvOK/HRyF2OzowboV5l5Wgc3SmgNnw4S/uar7gWcRYwcSZSop w7JOEQ+Mr1RKpyaR9VyBA8FijWSt4G6CPt+JEMh5YOQxCVeZK1iASgRXmxGBfCnlsyBhNGxsR7WN7 nCarl9pBitCXzHxJ2ovkARMky2FpWToidvNTRKrCylzLn3tZkjsukqXaOQdtOABO6OiTnVa0WiuLu YkNj0Lh/Pes2KVyR10ZpDYiVSaV8Qem3GB7y9TwJKcr+b2Yw5sFfOGrFqUjytOTAy/szjzGgS9bFW x/GaYTEA==; Received: from 108-198-5-147.lightspeed.okcbok.sbcglobal.net ([108.198.5.147]:54094 helo=freyr.lechnology.com) by vern.gendns.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-SHA256:128) (Exim 4.89) (envelope-from ) id 1dANPk-003jvc-Df; Mon, 15 May 2017 17:20:26 -0400 From: David Lechner To: linux-pm@vger.kernel.org Cc: David Lechner , Sebastian Reichel , linux-kernel@vger.kernel.org Subject: [RESEND PATCH] power: supply: sysfs: parse string as enum when writing property Date: Mon, 15 May 2017 16:21:15 -0500 Message-Id: <1494883275-9867-1-git-send-email-david@lechnology.com> X-Mailer: git-send-email 2.7.4 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - vern.gendns.com X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - lechnology.com X-Get-Message-Sender-Via: vern.gendns.com: authenticated_id: davidmain+lechnology.com/only user confirmed/virtual account not confirmed X-Authenticated-Sender: vern.gendns.com: davidmain@lechnology.com X-Source: X-Source-Args: X-Source-Dir: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This fixes the TODO to parse strings and convert them to enum values when writing to a power_supply class property sysfs attribute. There is at least one driver that has a writable enum property that previously could only be written as an integer, so a fallback to writing enums as integers instead of strings is provided so we don't break existing userspace programs. Signed-off-by: David Lechner --- Resend now that 4.12-rc1 has been tagged per https://patchwork.kernel.org/patch/9660499/ drivers/power/supply/power_supply_sysfs.c | 124 ++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 39 deletions(-) diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index bcde8d1..b2002b4 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -40,35 +40,42 @@ static struct device_attribute power_supply_attrs[]; +static const char * const power_supply_type_text[] = { + "Unknown", "Battery", "UPS", "Mains", "USB", + "USB_DCP", "USB_CDP", "USB_ACA", "USB_C", + "USB_PD", "USB_PD_DRP" +}; + +static const char * const power_supply_status_text[] = { + "Unknown", "Charging", "Discharging", "Not charging", "Full" +}; + +static const char * const power_supply_charge_type_text[] = { + "Unknown", "N/A", "Trickle", "Fast" +}; + +static const char * const power_supply_health_text[] = { + "Unknown", "Good", "Overheat", "Dead", "Over voltage", + "Unspecified failure", "Cold", "Watchdog timer expire", + "Safety timer expire" +}; + +static const char * const power_supply_technology_text[] = { + "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd", + "LiMn" +}; + +static const char * const power_supply_capacity_level_text[] = { + "Unknown", "Critical", "Low", "Normal", "High", "Full" +}; + +static const char * const power_supply_scope_text[] = { + "Unknown", "System", "Device" +}; + static ssize_t power_supply_show_property(struct device *dev, struct device_attribute *attr, char *buf) { - static char *type_text[] = { - "Unknown", "Battery", "UPS", "Mains", "USB", - "USB_DCP", "USB_CDP", "USB_ACA", "USB_C", - "USB_PD", "USB_PD_DRP" - }; - static char *status_text[] = { - "Unknown", "Charging", "Discharging", "Not charging", "Full" - }; - static char *charge_type[] = { - "Unknown", "N/A", "Trickle", "Fast" - }; - static char *health_text[] = { - "Unknown", "Good", "Overheat", "Dead", "Over voltage", - "Unspecified failure", "Cold", "Watchdog timer expire", - "Safety timer expire" - }; - static char *technology_text[] = { - "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd", - "LiMn" - }; - static char *capacity_level_text[] = { - "Unknown", "Critical", "Low", "Normal", "High", "Full" - }; - static char *scope_text[] = { - "Unknown", "System", "Device" - }; ssize_t ret = 0; struct power_supply *psy = dev_get_drvdata(dev); const ptrdiff_t off = attr - power_supply_attrs; @@ -91,19 +98,26 @@ static ssize_t power_supply_show_property(struct device *dev, } if (off == POWER_SUPPLY_PROP_STATUS) - return sprintf(buf, "%s\n", status_text[value.intval]); + return sprintf(buf, "%s\n", + power_supply_status_text[value.intval]); else if (off == POWER_SUPPLY_PROP_CHARGE_TYPE) - return sprintf(buf, "%s\n", charge_type[value.intval]); + return sprintf(buf, "%s\n", + power_supply_charge_type_text[value.intval]); else if (off == POWER_SUPPLY_PROP_HEALTH) - return sprintf(buf, "%s\n", health_text[value.intval]); + return sprintf(buf, "%s\n", + power_supply_health_text[value.intval]); else if (off == POWER_SUPPLY_PROP_TECHNOLOGY) - return sprintf(buf, "%s\n", technology_text[value.intval]); + return sprintf(buf, "%s\n", + power_supply_technology_text[value.intval]); else if (off == POWER_SUPPLY_PROP_CAPACITY_LEVEL) - return sprintf(buf, "%s\n", capacity_level_text[value.intval]); + return sprintf(buf, "%s\n", + power_supply_capacity_level_text[value.intval]); else if (off == POWER_SUPPLY_PROP_TYPE) - return sprintf(buf, "%s\n", type_text[value.intval]); + return sprintf(buf, "%s\n", + power_supply_type_text[value.intval]); else if (off == POWER_SUPPLY_PROP_SCOPE) - return sprintf(buf, "%s\n", scope_text[value.intval]); + return sprintf(buf, "%s\n", + power_supply_scope_text[value.intval]); else if (off >= POWER_SUPPLY_PROP_MODEL_NAME) return sprintf(buf, "%s\n", value.strval); @@ -117,14 +131,46 @@ static ssize_t power_supply_store_property(struct device *dev, struct power_supply *psy = dev_get_drvdata(dev); const ptrdiff_t off = attr - power_supply_attrs; union power_supply_propval value; - long long_val; - /* TODO: support other types than int */ - ret = kstrtol(buf, 10, &long_val); - if (ret < 0) - return ret; + /* maybe it is a enum property? */ + switch (off) { + case POWER_SUPPLY_PROP_STATUS: + ret = sysfs_match_string(power_supply_status_text, buf); + break; + case POWER_SUPPLY_PROP_CHARGE_TYPE: + ret = sysfs_match_string(power_supply_charge_type_text, buf); + break; + case POWER_SUPPLY_PROP_HEALTH: + ret = sysfs_match_string(power_supply_health_text, buf); + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + ret = sysfs_match_string(power_supply_technology_text, buf); + break; + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + ret = sysfs_match_string(power_supply_capacity_level_text, buf); + break; + case POWER_SUPPLY_PROP_SCOPE: + ret = sysfs_match_string(power_supply_scope_text, buf); + break; + default: + ret = -EINVAL; + } + + /* + * If no match was found, then check to see if it is an integer. + * Integer values are valid for enums in addition to the text value. + */ + if (ret < 0) { + long long_val; + + ret = kstrtol(buf, 10, &long_val); + if (ret < 0) + return ret; + + ret = long_val; + } - value.intval = long_val; + value.intval = ret; ret = power_supply_set_property(psy, off, &value); if (ret < 0)