From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754121Ab3KKN5h (ORCPT ); Mon, 11 Nov 2013 08:57:37 -0500 Received: from mail-bk0-f48.google.com ([209.85.214.48]:42039 "EHLO mail-bk0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753975Ab3KKN4y (ORCPT ); Mon, 11 Nov 2013 08:56:54 -0500 From: Julian Andres Klode To: Henrique de Moraes Holschuh , Matthew Garrett Cc: Julian Andres Klode , ibm-acpi-devel@lists.sourceforge.net (open list:THINKPAD ACPI EXT...), platform-driver-x86@vger.kernel.org (open list:THINKPAD ACPI EXT...), linux-kernel@vger.kernel.org (open list) Subject: [PATCH 2/4] thinkpad_acpi: battery: Add force_discharge attribute Date: Mon, 11 Nov 2013 14:56:31 +0100 Message-Id: <1384178195-12218-3-git-send-email-jak@jak-linux.org> X-Mailer: git-send-email 1.8.4.2 In-Reply-To: <1384178195-12218-1-git-send-email-jak@jak-linux.org> References: <1384178195-12218-1-git-send-email-jak@jak-linux.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This makes it possible to forcefully discharge a battery. Signed-off-by: Julian Andres Klode --- Documentation/laptops/thinkpad-acpi.txt | 4 +++ drivers/platform/x86/thinkpad_acpi.c | 49 ++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 97b150a..72882bb 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -1370,6 +1370,10 @@ battery sysfs attribute: stop_charge_thresh A percentage value from 1-99%, controlling when charging should stop, or 0 for the default value. +battery sysfs attribute: force_discharge + + Force discharging (0 or 1) + Multiple Commands, Module Parameters ------------------------------------ diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 66e629e..67ce469 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -8358,7 +8358,7 @@ static struct ibm_struct fan_driver_data = { /* Modify battery_init() if you modify them */ #define BATTERY_MAX_COUNT 3 -#define BATTERY_MAX_ATTRS 2 +#define BATTERY_MAX_ATTRS 3 static struct battery { char name[3 + 1 + 1]; @@ -8437,6 +8437,46 @@ static ssize_t battery_stop_charge_thresh_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", value & 0xFF); } +static ssize_t battery_force_discharge_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int bat = battery_attribute_get_battery(attr); + int value; + + if (!hkey_handle || !acpi_evalf(hkey_handle, &value, "BDSG", + "dd", bat)) + return -EIO; + + return snprintf(buf, PAGE_SIZE, "%d\n", value & 0x1); +} + +static ssize_t battery_force_discharge_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int bat = battery_attribute_get_battery(attr); + int res = -EINVAL; + unsigned long value; + + res = kstrtoul(buf, 0, &value); + if (res || value > 1) + return res ? res : -EINVAL; + + if (!hkey_handle || !acpi_evalf(hkey_handle, &res, "BDSG", "dd", bat)) + return -EIO; + + /* Keep the break on AC disconnect state */ + value |= (res >> 1) & 0x1; + /* Set the battery */ + value |= (bat << 8); + + if (!hkey_handle || !acpi_evalf(hkey_handle, &res, "BDSS", + "dd", (int) value) || res < 0) + return -EIO; + return count; +} + static int __init battery_init(struct ibm_init_struct *iibm) { int res; @@ -8482,6 +8522,13 @@ static int __init battery_init(struct ibm_init_struct *iibm) battery_stop_charge_thresh_store), .var = (void *) (unsigned long) (i + 1) }; + batteries[i].attributes[j++] = (struct dev_ext_attribute) { + .attr = __ATTR(force_discharge, + S_IWUSR | S_IRUGO, + battery_force_discharge_show, + battery_force_discharge_store), + .var = (void *) (unsigned long) (i + 1) + }; strncpy(batteries[i].name, "BAT", 3); batteries[i].name[3] = '0' + i; -- 1.8.4.2