From patchwork Sun May 13 15:30:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ognjen Galic X-Patchwork-Id: 10396265 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 5334660236 for ; Sun, 13 May 2018 15:30:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4056428F5F for ; Sun, 13 May 2018 15:30:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 34E7229073; Sun, 13 May 2018 15:30: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=-7.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID 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 C406229070 for ; Sun, 13 May 2018 15:30:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751518AbeEMPaH (ORCPT ); Sun, 13 May 2018 11:30:07 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:43687 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751357AbeEMPaF (ORCPT ); Sun, 13 May 2018 11:30:05 -0400 Received: by mail-wr0-f196.google.com with SMTP id v15-v6so9735793wrm.10; Sun, 13 May 2018 08:30:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=EWR/WIkXidAbANV6KHtxYOdz95nnsr+SX36e6jFdfr0=; b=NmfpoJCovhLUEksWJNLVXLlJaKTS+DizHwpUsPKYxfK8GnAojXgbB9VOZGbgEEydK3 B0RiKSYvyY7RvtVcWZniXgodcFC4faN6HqdpdxE9xB/YBnn6RebBhKTqxgpGeNuL+tHs KqSOrn754b6BV9AllUG3NOLJTZ02jSZCyyAtDhVwEStUzlmjHb8DbbmhSdTgKns+l3G4 70aZRcz0J+HSnqoWGlhIdo1N7/o7WvW1cBPOK0JpqJgg3wqD01c3VEhcGPnIEyemuhja RSW/0aOFHaQLAOQYl9EmN8eRJsvQRKayCjJ/zdab/zroYCuH5RtGWAMiYY/HoT6PxvNX 2Hcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=EWR/WIkXidAbANV6KHtxYOdz95nnsr+SX36e6jFdfr0=; b=SAvRJF0xUcHPA7s8cVhkIbrAvDTw5tj7W8XRAdGr7sz6BAIvnkUckqebkG3xk+G8uw cYtQ1k69tSoyYE023J0TrllZ27WkuTrCAoECi4wOZeY14caObCItWE/CJj9LFQmw+aCL cE9MZbwMUihn5UuU/sXeRmLOqMXCMYoKC9X81kqVGFtLAwLT4K8dBanz/6r9L3fNFyYS Mo4dmdX07aAZ36zkBX0CWVe/JI98dP6iZSpeyyB9ESwXbbExt3Z7WKBici3feT4z7Rl9 qSBdvtAHXRrfVqoxRFTlZjtBpqmmmmQ7BBHOQNtCBHGKEv7x6mQBQLS2oZfOaJxrVuhD sX7g== X-Gm-Message-State: ALKqPwfGw+97rwp+GKoRwqOBXrEF5O1OkHwYMpmyLc/WzAIwoyi4Mh/q vPztkQ7bXvlZeVCbEyDnGMw= X-Google-Smtp-Source: AB8JxZqlxkvLoqCQkWPSOHKDZbMPdbavbXjzcrEOjA+x3adNGJTy+QCy8uF+I0za83PTyQN/3Bw3Pg== X-Received: by 2002:adf:a6f8:: with SMTP id t111-v6mr4471106wrc.161.1526225404253; Sun, 13 May 2018 08:30:04 -0700 (PDT) Received: from thinkpad (pppoe-46-239-10-213.teol.net. [46.239.10.213]) by smtp.googlemail.com with ESMTPSA id y129-v6sm6284641wmg.44.2018.05.13.08.30.02 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 13 May 2018 08:30:03 -0700 (PDT) Date: Sun, 13 May 2018 17:30:00 +0200 From: Ognjen Galic To: Andy Shevchenko , "Rafael J. Wysocki" , Ognjen =?utf-8?B?R2FsacSH?= , "Rafael J. Wysocki" , Len Brown , Robert Moore , ACPI Devel Maling List , devel@acpica.org, Darren Hart , Andy Shevchenko , Henrique de Moraes Holschuh , Sebastian Reichel , Platform Driver , ibm-acpi-devel@lists.sourceforge.net, Linux PM , Christoph =?iso-8859-1?Q?B=F6hmwalder?= , Kevin Locke Subject: [PATCH 2/3] thinkpad_acpi: add support for force_discharge Message-ID: <20180513153000.GA5117@thinkpad> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.9.4 (2018-02-28) Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Lenovo ThinkPad systems have a feature that lets you force the battery to discharge regardless if AC is attached or not. This patch implements that feature and exposes it via the generic ACPI battery driver. Signed-off-by: Ognjen Galic Tested-by: Kevin Locke --- drivers/platform/x86/thinkpad_acpi.c | 56 ++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index b8b74889..28a87640 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -9236,7 +9236,11 @@ static struct ibm_struct mute_led_driver_data = { #define SET_INHIBIT "BICS" #define GET_INHIBIT "BICG" +#define GET_DISCHARGE "BDSG" +#define SET_DISCHARGE "PSBS" + #define INHIBIT_ATTR "inhibit_charge" +#define DISCHARGE_ATTR "force_discharge" #define START_ATTR "charge_start_threshold" #define STOP_ATTR "charge_stop_threshold" @@ -9256,7 +9260,8 @@ enum { /* This is used in the get/set helpers */ THRESHOLD_START, THRESHOLD_STOP, - INHIBIT_CHARGE + INHIBIT_CHARGE, + FORCE_DISCHARGE }; struct tpacpi_battery_data { @@ -9265,6 +9270,7 @@ struct tpacpi_battery_data { int charge_stop; int stop_support; int inhibit_support; + int discharge_support; }; struct tpacpi_battery_driver_data { @@ -9329,6 +9335,12 @@ static int tpacpi_battery_get(int what, int battery, int *ret) /* The inhibit charge status is in the first bit */ *ret = *ret & 0x01; return 0; + case FORCE_DISCHARGE: + if ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_DISCHARGE, ret, battery)) + return -ENODEV; + /* The force discharge status is in the first bit */ + *ret = *ret & 0x01; + return 0; default: pr_crit("wrong parameter: %d", what); return -EINVAL; @@ -9372,6 +9384,14 @@ static int tpacpi_battery_set(int what, int battery, int value) return -ENODEV; } return 0; + case FORCE_DISCHARGE: + param = battery; + param |= value << 8; + if ACPI_FAILURE(tpacpi_battery_acpi_eval(SET_DISCHARGE, &ret, param)) { + pr_err("failed to set force dischrage on %d", battery); + return -ENODEV; + } + return 0; default: pr_crit("wrong parameter: %d", what); return -EINVAL; @@ -9431,11 +9451,16 @@ static int tpacpi_battery_probe(int battery) /* Support is marked in bit 5 */ battery_info.batteries[battery].inhibit_support = ret & BIT(5); - pr_info("battery %d registered (start %d, stop %d, inhibit: %d)", + if (acpi_has_method(hkey_handle, GET_DISCHARGE)) + if (!ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_DISCHARGE, &ret, battery))) + battery_info.batteries[battery].discharge_support = ret & BIT(8); + + pr_info("battery %d registered (start %d, stop %d, inhibit: %d, force: %d)", battery, battery_info.batteries[battery].charge_start, battery_info.batteries[battery].charge_stop, - battery_info.batteries[battery].inhibit_support); + battery_info.batteries[battery].inhibit_support, + battery_info.batteries[battery].discharge_support); return 0; } @@ -9530,6 +9555,15 @@ static ssize_t tpacpi_battery_store(int what, if (tpacpi_battery_set(INHIBIT_CHARGE, battery, value)) return -ENODEV; return count; + case FORCE_DISCHARGE: + if (!battery_info.batteries[battery].discharge_support) + return -ENODEV; + /* The only valid values are 1 and 0 */ + if (value != 0 && value != 1) + return -EINVAL; + if (tpacpi_battery_set(FORCE_DISCHARGE, battery, value)) + return -ENODEV; + return count; default: pr_crit("Wrong parameter: %d", what); return -EINVAL; @@ -9606,14 +9640,30 @@ static ssize_t inhibit_charge_show(struct device *device, return tpacpi_battery_show(INHIBIT_CHARGE, device, buf); } +static ssize_t force_discharge_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return tpacpi_battery_store(FORCE_DISCHARGE, dev, buf, count); +} + +static ssize_t force_discharge_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + return tpacpi_battery_show(FORCE_DISCHARGE, device, buf); +} + static DEVICE_ATTR_RW(charge_start_threshold); static DEVICE_ATTR_RW(charge_stop_threshold); static DEVICE_ATTR_RW(inhibit_charge); +static DEVICE_ATTR_RW(force_discharge); static struct attribute *tpacpi_battery_attrs[] = { &dev_attr_charge_start_threshold.attr, &dev_attr_charge_stop_threshold.attr, &dev_attr_inhibit_charge.attr, + &dev_attr_force_discharge.attr, NULL, };