From patchwork Tue Feb 24 09:54:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Krzysztof Kozlowski X-Patchwork-Id: 5871211 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C0C839F373 for ; Tue, 24 Feb 2015 09:59:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B696220652 for ; Tue, 24 Feb 2015 09:59:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8687C2044C for ; Tue, 24 Feb 2015 09:59:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753280AbbBXJ7M (ORCPT ); Tue, 24 Feb 2015 04:59:12 -0500 Received: from mailout3.w1.samsung.com ([210.118.77.13]:33484 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751812AbbBXJy4 (ORCPT ); Tue, 24 Feb 2015 04:54:56 -0500 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NK900DACT2AMB60@mailout3.w1.samsung.com>; Tue, 24 Feb 2015 09:58:58 +0000 (GMT) X-AuditID: cbfec7f4-b7f126d000001e9a-c5-54ec49dcd235 Received: from eusync2.samsung.com ( [203.254.199.212]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id A9.E7.07834.CD94CE45; Tue, 24 Feb 2015 09:52:28 +0000 (GMT) Received: from AMDC1943.digital.local ([106.116.151.171]) by eusync2.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0NK900GYNSVEJ350@eusync2.samsung.com>; Tue, 24 Feb 2015 09:54:54 +0000 (GMT) From: Krzysztof Kozlowski To: Sebastian Reichel , Dmitry Eremin-Solenikov , David Woodhouse , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Krzysztof Kozlowski Subject: [PATCH 1/5] power_supply: max77693: Properly handle error conditions Date: Tue, 24 Feb 2015 10:54:43 +0100 Message-id: <1424771687-7976-1-git-send-email-k.kozlowski@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrOJMWRmVeSWpSXmKPExsVy+t/xK7p3PN+EGKw5YWMx6cl7ZouJKycz W7x+YWhxedccNovPvUcYLU7vLnFg89g56y67x+YVWh6bVnWyefRtWcXo8XmTXABrFJdNSmpO Zllqkb5dAlfGihnXWAt+2VS8fvOErYFxsVEXIyeHhICJROulhawQtpjEhXvr2boYuTiEBJYy Sry+sIEdwuljktg6ZQ0LSBWbgLHE5uVLwKpEBHYzSkyYuhwswSxgKPHz3R92EFtYwFdi9u7f TCA2i4CqxMMzT8BsXgE3iRkXbrJBrJOTOHlsMusERu4FjAyrGEVTS5MLipPScw31ihNzi0vz 0vWS83M3MUIC48sOxsXHrA4xCnAwKvHwPih7FSLEmlhWXJl7iFGCg1lJhHeB7ZsQId6UxMqq 1KL8+KLSnNTiQ4xMHJxSDYyNpt43FNb0CB8PVvYyd+fedbp0Rn9myG7fqYtffNg9M0TgT6Jd 06oFr3e1Paxp/jB10bdsvTyVzj86Yt8OrL7/UHHJgVk7s4QOrDWwZbmsyHhc+DzX/+V2D/m2 Bl/da6Y47/zO90LOrFtSvZov57YJ/f3d+XdSyCkJjU4hhxlFWea37mxyP/JIiaU4I9FQi7mo OBEA/0iez+oBAAA= Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Re-work and fix handling of errors when retrieving power supply properties: 1. Return errno values directly from get_property() instead of storing 'unknown' as intval for given property. 2. Handle regmap_read() errors when getting 'online' and 'present' proprties and return errno code. Previously the regmap_read() return code was ignored so an uninitialized value from the stack could be used for calculating the property. Signed-off-by: Krzysztof Kozlowski --- drivers/power/max77693_charger.c | 99 ++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c index b042970fdeaf..ca52e7d15b95 100644 --- a/drivers/power/max77693_charger.c +++ b/drivers/power/max77693_charger.c @@ -38,13 +38,14 @@ struct max77693_charger { u32 charge_input_threshold_volt; }; -static int max77693_get_charger_state(struct regmap *regmap) +static int max77693_get_charger_state(struct regmap *regmap, int *val) { - int state; + int ret; unsigned int data; - if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0) - return POWER_SUPPLY_STATUS_UNKNOWN; + ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data); + if (ret < 0) + return ret; data &= CHG_DETAILS_01_CHG_MASK; data >>= CHG_DETAILS_01_CHG_SHIFT; @@ -56,35 +57,36 @@ static int max77693_get_charger_state(struct regmap *regmap) case MAX77693_CHARGING_TOP_OFF: /* In high temp the charging current is reduced, but still charging */ case MAX77693_CHARGING_HIGH_TEMP: - state = POWER_SUPPLY_STATUS_CHARGING; + *val = POWER_SUPPLY_STATUS_CHARGING; break; case MAX77693_CHARGING_DONE: - state = POWER_SUPPLY_STATUS_FULL; + *val = POWER_SUPPLY_STATUS_FULL; break; case MAX77693_CHARGING_TIMER_EXPIRED: case MAX77693_CHARGING_THERMISTOR_SUSPEND: - state = POWER_SUPPLY_STATUS_NOT_CHARGING; + *val = POWER_SUPPLY_STATUS_NOT_CHARGING; break; case MAX77693_CHARGING_OFF: case MAX77693_CHARGING_OVER_TEMP: case MAX77693_CHARGING_WATCHDOG_EXPIRED: - state = POWER_SUPPLY_STATUS_DISCHARGING; + *val = POWER_SUPPLY_STATUS_DISCHARGING; break; case MAX77693_CHARGING_RESERVED: default: - state = POWER_SUPPLY_STATUS_UNKNOWN; + *val = POWER_SUPPLY_STATUS_UNKNOWN; } - return state; + return 0; } -static int max77693_get_charge_type(struct regmap *regmap) +static int max77693_get_charge_type(struct regmap *regmap, int *val) { - int state; + int ret; unsigned int data; - if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0) - return POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; + ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data); + if (ret < 0) + return ret; data &= CHG_DETAILS_01_CHG_MASK; data >>= CHG_DETAILS_01_CHG_SHIFT; @@ -96,13 +98,13 @@ static int max77693_get_charge_type(struct regmap *regmap) * 100 and 250 mA. It is higher than prequalification current. */ case MAX77693_CHARGING_TOP_OFF: - state = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; + *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; break; case MAX77693_CHARGING_FAST_CONST_CURRENT: case MAX77693_CHARGING_FAST_CONST_VOLTAGE: /* In high temp the charging current is reduced, but still charging */ case MAX77693_CHARGING_HIGH_TEMP: - state = POWER_SUPPLY_CHARGE_TYPE_FAST; + *val = POWER_SUPPLY_CHARGE_TYPE_FAST; break; case MAX77693_CHARGING_DONE: case MAX77693_CHARGING_TIMER_EXPIRED: @@ -110,14 +112,14 @@ static int max77693_get_charge_type(struct regmap *regmap) case MAX77693_CHARGING_OFF: case MAX77693_CHARGING_OVER_TEMP: case MAX77693_CHARGING_WATCHDOG_EXPIRED: - state = POWER_SUPPLY_CHARGE_TYPE_NONE; + *val = POWER_SUPPLY_CHARGE_TYPE_NONE; break; case MAX77693_CHARGING_RESERVED: default: - state = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; + *val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; } - return state; + return 0; } /* @@ -129,69 +131,78 @@ static int max77693_get_charge_type(struct regmap *regmap) * - POWER_SUPPLY_HEALTH_UNKNOWN * - POWER_SUPPLY_HEALTH_UNSPEC_FAILURE */ -static int max77693_get_battery_health(struct regmap *regmap) +static int max77693_get_battery_health(struct regmap *regmap, int *val) { - int state; + int ret; unsigned int data; - if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0) - return POWER_SUPPLY_HEALTH_UNKNOWN; + ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data); + if (ret < 0) + return ret; data &= CHG_DETAILS_01_BAT_MASK; data >>= CHG_DETAILS_01_BAT_SHIFT; switch (data) { case MAX77693_BATTERY_NOBAT: - state = POWER_SUPPLY_HEALTH_DEAD; + *val = POWER_SUPPLY_HEALTH_DEAD; break; case MAX77693_BATTERY_PREQUALIFICATION: case MAX77693_BATTERY_GOOD: case MAX77693_BATTERY_LOWVOLTAGE: - state = POWER_SUPPLY_HEALTH_GOOD; + *val = POWER_SUPPLY_HEALTH_GOOD; break; case MAX77693_BATTERY_TIMER_EXPIRED: /* * Took longer to charge than expected, charging suspended. * Damaged battery? */ - state = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; + *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; break; case MAX77693_BATTERY_OVERVOLTAGE: - state = POWER_SUPPLY_HEALTH_OVERVOLTAGE; + *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE; break; case MAX77693_BATTERY_OVERCURRENT: - state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; + *val = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; break; case MAX77693_BATTERY_RESERVED: default: - state = POWER_SUPPLY_HEALTH_UNKNOWN; + *val = POWER_SUPPLY_HEALTH_UNKNOWN; break; } - return state; + return 0; } -static int max77693_get_present(struct regmap *regmap) +static int max77693_get_present(struct regmap *regmap, int *val) { unsigned int data; + int ret; /* * Read CHG_INT_OK register. High DETBAT bit here should be * equal to value 0x0 in CHG_DETAILS_01/BAT field. */ - regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); - if (data & CHG_INT_OK_DETBAT_MASK) - return 0; - return 1; + ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); + if (ret < 0) + return ret; + + *val = (data & CHG_INT_OK_DETBAT_MASK) ? 0 : 1; + + return 0; } -static int max77693_get_online(struct regmap *regmap) +static int max77693_get_online(struct regmap *regmap, int *val) { unsigned int data; + int ret; + + ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); + if (ret < 0) + return ret; + + *val = (data & CHG_INT_OK_CHGIN_MASK) ? 1 : 0; - regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data); - if (data & CHG_INT_OK_CHGIN_MASK) - return 1; return 0; } @@ -217,19 +228,19 @@ static int max77693_charger_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_STATUS: - val->intval = max77693_get_charger_state(regmap); + ret = max77693_get_charger_state(regmap, &val->intval); break; case POWER_SUPPLY_PROP_CHARGE_TYPE: - val->intval = max77693_get_charge_type(regmap); + ret = max77693_get_charge_type(regmap, &val->intval); break; case POWER_SUPPLY_PROP_HEALTH: - val->intval = max77693_get_battery_health(regmap); + ret = max77693_get_battery_health(regmap, &val->intval); break; case POWER_SUPPLY_PROP_PRESENT: - val->intval = max77693_get_present(regmap); + ret = max77693_get_present(regmap, &val->intval); break; case POWER_SUPPLY_PROP_ONLINE: - val->intval = max77693_get_online(regmap); + ret = max77693_get_online(regmap, &val->intval); break; case POWER_SUPPLY_PROP_MODEL_NAME: val->strval = max77693_charger_model;