From patchwork Tue Aug 15 20:04:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 9902485 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 B273960230 for ; Tue, 15 Aug 2017 20:08:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A6A1B288FC for ; Tue, 15 Aug 2017 20:08:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9B36728911; Tue, 15 Aug 2017 20:08:10 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable 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 4EC1B288FC for ; Tue, 15 Aug 2017 20:08:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753342AbdHOUGD (ORCPT ); Tue, 15 Aug 2017 16:06:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:13485 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753114AbdHOUGB (ORCPT ); Tue, 15 Aug 2017 16:06:01 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A5E2E90903; Tue, 15 Aug 2017 20:06:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A5E2E90903 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=hdegoede@redhat.com Received: from dhcp-45-79.space.revspace.nl.com (ovpn-112-17.ams2.redhat.com [10.36.112.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9AA7418166; Tue, 15 Aug 2017 20:05:53 +0000 (UTC) From: Hans de Goede To: Wolfram Sang , Guenter Roeck , Heikki Krogerus , Sebastian Reichel , Darren Hart , Andy Shevchenko , Greg Kroah-Hartman Cc: Hans de Goede , Liam Breck , Tony Lindgren , linux-i2c@vger.kernel.org, linux-pm@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, devel@driverdev.osuosl.org Subject: [PATCH v2 08/14] power: supply: Add power_supply_set_input_current_limit_from_supplier helper Date: Tue, 15 Aug 2017 22:04:56 +0200 Message-Id: <20170815200502.17339-9-hdegoede@redhat.com> In-Reply-To: <20170815200502.17339-1-hdegoede@redhat.com> References: <20170815200502.17339-1-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 15 Aug 2017 20:06:00 +0000 (UTC) Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On some devices the USB Type-C port power (USB PD 2.0) negotiation is done by a separate port-controller IC, while the current limit is controlled through another (charger) IC. It has been decided to model this by modelling the external Type-C power brick (adapter/charger) as a power-supply class device which supplies the charger-IC, with its voltage-now and current-max representing the negotiated voltage and max current draw. This commit adds a power_supply_set_input_current_limit_from_supplier helper function which charger power-supply drivers can call to get the max-current from their supplier and have this applied through their set_property call-back to their input-current-limit. Signed-off-by: Hans de Goede --- drivers/power/supply/power_supply_core.c | 41 ++++++++++++++++++++++++++++++++ include/linux/power_supply.h | 2 ++ 2 files changed, 43 insertions(+) diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 0741fce..3f92574 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -375,6 +375,47 @@ int power_supply_is_system_supplied(void) } EXPORT_SYMBOL_GPL(power_supply_is_system_supplied); +static int __power_supply_get_supplier_max_current(struct device *dev, + void *data) +{ + union power_supply_propval ret = {0,}; + struct power_supply *epsy = dev_get_drvdata(dev); + struct power_supply *psy = data; + + if (__power_supply_is_supplied_by(epsy, psy)) + if (!epsy->desc->get_property(epsy, + POWER_SUPPLY_PROP_CURRENT_MAX, + &ret)) + return ret.intval; + + return 0; +} + +int power_supply_set_input_current_limit_from_supplier(struct power_supply *psy) +{ + union power_supply_propval val = {0,}; + int curr; + + if (!psy->desc->set_property) + return -EINVAL; + + /* + * This function is not intended for use with a supply with multiple + * suppliers, we simply pick the first supply to report a non 0 + * max-current. + */ + curr = class_for_each_device(power_supply_class, NULL, psy, + __power_supply_get_supplier_max_current); + if (curr <= 0) + return (curr == 0) ? -ENODEV : curr; + + val.intval = curr; + + return psy->desc->set_property(psy, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val); +} +EXPORT_SYMBOL_GPL(power_supply_set_input_current_limit_from_supplier); + int power_supply_set_battery_charged(struct power_supply *psy) { if (atomic_read(&psy->use_cnt) >= 0 && diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index de89066..79e90b3 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -332,6 +332,8 @@ extern int power_supply_get_battery_info(struct power_supply *psy, struct power_supply_battery_info *info); extern void power_supply_changed(struct power_supply *psy); extern int power_supply_am_i_supplied(struct power_supply *psy); +extern int power_supply_set_input_current_limit_from_supplier( + struct power_supply *psy); extern int power_supply_set_battery_charged(struct power_supply *psy); #ifdef CONFIG_POWER_SUPPLY