From patchwork Wed Apr 16 13:33:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lan Tianyu X-Patchwork-Id: 339596 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 63B301400D5 for ; Wed, 16 Apr 2014 23:36:43 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932070AbaDPNgL (ORCPT ); Wed, 16 Apr 2014 09:36:11 -0400 Received: from mga09.intel.com ([134.134.136.24]:55615 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161002AbaDPNgI (ORCPT ); Wed, 16 Apr 2014 09:36:08 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 16 Apr 2014 06:28:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,872,1389772800"; d="scan'208,223";a="494145332" Received: from unknown (HELO tlan1-mobl3.ccr.corp.intel.com) ([10.255.20.62]) by orsmga001.jf.intel.com with ESMTP; 16 Apr 2014 06:33:07 -0700 Message-ID: <534E86AD.6000204@intel.com> Date: Wed, 16 Apr 2014 21:33:33 +0800 From: Lan Tianyu User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: wsa@the-dreams.de, rjw@rjwysocki.net, lenb@kernel.org, mika.westerberg@linux.intel.com, awilliam@redhat.com CC: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 0/9] I2C ACPI operation region handler support References: <1397654682-7094-1-git-send-email-tianyu.lan@intel.com> In-Reply-To: <1397654682-7094-1-git-send-email-tianyu.lan@intel.com> Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org On 04/16/2014 09:24 PM, Lan Tianyu wrote: > ACPI 5.0 spec(5.5.2.4.5) defines GenericSerialBus(i2c, spi, uart) operation > region. It allows ACPI aml code able to access such kind of devices to > implement some ACPI standard method. > > On the Asus T100TA, Bios use GenericSerialBus operation region to access > i2c device to get battery info. So battery function depends on the I2C > operation region support. Here is the bug link. > https://bugzilla.kernel.org/show_bug.cgi?id=69011 Completely fixing battery issue on the Asus T100TA also needs ACPI _DEP support. The feature is under developing. Attach a temporary patch for test. > > This patchset is to add I2C ACPI operation region handler support. > > [PATCH 1/9] ACPICA: Executer: Fix buffer allocation issue for > [PATCH 2/9] ACPICA: Export acpi_buffer_to_resource symbol > [PATCH 3/9] ACPI: Add acpi_bus_attach_private_data() to facilitate to > [PATCH 4/9] ACPI/Thermal: Use acpi_bus_attach_private_data() to > [PATCH 5/9] I2C: Add smbus quick read/write helper function > [PATCH 6/9] I2C: Add smbus word/block process call helper function > [PATCH 7/9] I2C/ACPI: Add i2c ACPI operation region support > [PATCH 8/9] I2C/ACPI: Move ACPI related code to i2c-acpi.c > [PATCH 9/9] I2C/ACPI: Add CONFIG_I2C_ACPI config > From bbadbc67de278123e28dd6f9ee7e88b6ada56ce4 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Fri, 21 Mar 2014 16:42:12 +0800 Subject: [PATCH] ACPI: temporary dep solution for battery support This is a dep workaround for battery support on Asus T100TA and the formal dep solution is under developing. This patch is just for test and will not be upstreamed. --- drivers/acpi/scan.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++--- drivers/i2c/i2c-acpi.c | 1 + include/linux/acpi.h | 1 + 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7efe546..254afb7 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -36,6 +36,7 @@ bool acpi_force_hot_remove; static const char *dummy_hid = "device"; +static LIST_HEAD(acpi_bus_dep_device_list); static LIST_HEAD(acpi_bus_id_list); static DEFINE_MUTEX(acpi_scan_lock); static LIST_HEAD(acpi_scan_handlers_list); @@ -43,6 +44,12 @@ DEFINE_MUTEX(acpi_device_lock); LIST_HEAD(acpi_wakeup_device_list); static DEFINE_MUTEX(acpi_hp_context_lock); + +struct acpi_dep_handle { + struct list_head node; + acpi_handle handle; +}; + struct acpi_device_bus_id{ char bus_id[15]; unsigned int instance_no; @@ -2027,10 +2034,22 @@ static void acpi_scan_init_hotplug(struct acpi_device *adev) } } + +static int acpi_dep_device_check(acpi_handle handle) +{ + struct acpi_dep_handle *dep; + + list_for_each_entry(dep, &acpi_bus_dep_device_list, node) + if (dep->handle == handle) + return -EEXIST; + return 0; +} + static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, void *not_used, void **return_value) { struct acpi_device *device = NULL; + struct acpi_dep_handle *dep = NULL; int type; unsigned long long sta; int result; @@ -2048,9 +2067,24 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, return AE_OK; } - acpi_add_single_object(&device, handle, type, sta); - if (!device) - return AE_CTRL_DEPTH; + if (!acpi_dep_device_check(handle) + && acpi_has_method(handle, "_BIX") + && acpi_has_method(handle, "_DEP")) { + dep = kmalloc(sizeof(struct acpi_dep_handle), GFP_KERNEL); + if (!dep) + return AE_CTRL_DEPTH; + dep->handle = handle; + list_add_tail(&dep->node , &acpi_bus_dep_device_list); + + acpi_handle_info(dep->handle, + "is added to dep device list.\n"); + + return AE_OK; + } else { + acpi_add_single_object(&device, handle, type, sta); + if (!device) + return AE_CTRL_DEPTH; + } acpi_scan_init_hotplug(device); @@ -2061,6 +2095,30 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, return AE_OK; } +int acpi_walk_dep_device_list(void) +{ + struct acpi_dep_handle *dep, *tmp; + acpi_status status; + unsigned long long sta; + + list_for_each_entry_safe(dep, tmp, &acpi_bus_dep_device_list, node) { + status = acpi_evaluate_integer(dep->handle, "_STA", NULL, &sta); + + if (ACPI_FAILURE(status)) { + acpi_handle_warn(dep->handle, + "Status check failed (0x%x)\n", status); + } else if (sta & ACPI_STA_DEVICE_ENABLED) { + acpi_bus_scan(dep->handle); + acpi_handle_info(dep->handle, + "Device is readly\n"); + list_del(&dep->node); + kfree(dep); + } + } + return 0; +} +EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list); + static int acpi_scan_attach_handler(struct acpi_device *device) { struct acpi_hardware_id *hwid; diff --git a/drivers/i2c/i2c-acpi.c b/drivers/i2c/i2c-acpi.c index a0ae867..471490a 100644 --- a/drivers/i2c/i2c-acpi.c +++ b/drivers/i2c/i2c-acpi.c @@ -349,6 +349,7 @@ int acpi_i2c_install_space_handler(struct i2c_adapter *adapter) return -ENOMEM; } + acpi_walk_dep_device_list(); return 0; } diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 667204c..66ad0dd 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -115,6 +115,7 @@ int acpi_boot_init (void); void acpi_boot_table_init (void); int acpi_mps_check (void); int acpi_numa_init (void); +int acpi_walk_dep_device_list(void); int acpi_table_init (void); int acpi_table_parse(char *id, acpi_tbl_table_handler handler); -- 1.8.3.1