149 lines
4.1 KiB
Diff
149 lines
4.1 KiB
Diff
|
From bbadbc67de278123e28dd6f9ee7e88b6ada56ce4 Mon Sep 17 00:00:00 2001
|
||
|
From: Lan Tianyu <tianyu.lan@intel.com>
|
||
|
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
|
||
|
|