* [PATCH 0/3] Series short description
@ 2007-05-29 12:42 Alexey Starikovskiy
2007-05-29 12:42 ` [PATCH 1/3] ACPI EC: Re-factor EC space handler to avoid using label/goto for cycle Alexey Starikovskiy
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Alexey Starikovskiy @ 2007-05-29 12:42 UTC (permalink / raw)
To: len.brown, linux-acpi
In order to get notifications from Smart Batteries there is a need to
allow non-AML query handlers in EC driver.
AML query handlers are now found at init time, so there is no need to
look them up in namespace at query time.
--
Regards,
Alex.
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] ACPI EC: Re-factor EC space handler to avoid using label/goto for cycle.
2007-05-29 12:42 [PATCH 0/3] Series short description Alexey Starikovskiy
@ 2007-05-29 12:42 ` Alexey Starikovskiy
2007-06-23 20:02 ` Len Brown
2007-05-29 12:42 ` [PATCH 2/3] ACPI EC: drop usage of ACPI_DEBUG_PRINT as too heavy weight Alexey Starikovskiy
2007-05-29 12:43 ` [PATCH 3/3] ACPI EC: Add support for non-AML EC query handlers Alexey Starikovskiy
2 siblings, 1 reply; 7+ messages in thread
From: Alexey Starikovskiy @ 2007-05-29 12:42 UTC (permalink / raw)
To: len.brown, linux-acpi; +Cc: Alexey Starikovskiy
Signed-off-by: Alexey Starikovskiy <aystarik@gmail.com>
---
drivers/acpi/ec.c | 56 ++++++++++++++++-------------------------------------
1 files changed, 17 insertions(+), 39 deletions(-)
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 82f496c..5534b23 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -454,57 +454,35 @@ acpi_ec_space_setup(acpi_handle region_handle,
}
static acpi_status
-acpi_ec_space_handler(u32 function,
- acpi_physical_address address,
- u32 bit_width,
- acpi_integer * value,
+acpi_ec_space_handler(u32 function, acpi_physical_address address,
+ u32 bits, acpi_integer *value,
void *handler_context, void *region_context)
{
- int result = 0;
struct acpi_ec *ec = handler_context;
- u64 temp = *value;
- acpi_integer f_v = 0;
- int i = 0;
+ int result = 0, i = 0;
+ u8 temp = 0;
if ((address > 0xFF) || !value || !handler_context)
return AE_BAD_PARAMETER;
- if (bit_width != 8 && acpi_strict) {
+ if (function != ACPI_READ && function != ACPI_WRITE)
return AE_BAD_PARAMETER;
- }
-
- next_byte:
- switch (function) {
- case ACPI_READ:
- temp = 0;
- result = acpi_ec_read(ec, (u8) address, (u8 *) & temp);
- break;
- case ACPI_WRITE:
- result = acpi_ec_write(ec, (u8) address, (u8) temp);
- break;
- default:
- result = -EINVAL;
- goto out;
- break;
- }
- bit_width -= 8;
- if (bit_width) {
- if (function == ACPI_READ)
- f_v |= temp << 8 * i;
- if (function == ACPI_WRITE)
- temp >>= 8;
- i++;
- address++;
- goto next_byte;
- }
+ if (bits != 8 && acpi_strict)
+ return AE_BAD_PARAMETER;
- if (function == ACPI_READ) {
- f_v |= temp << 8 * i;
- *value = f_v;
+ while (bits - i > 0) {
+ if (function == ACPI_READ) {
+ result = acpi_ec_read(ec, address, &temp);
+ (*value) |= ((acpi_integer)temp) << i;
+ } else {
+ temp = 0xff & ((*value) >> i);
+ result = acpi_ec_write(ec, address, temp);
+ }
+ i += 8;
+ ++address;
}
- out:
switch (result) {
case -EINVAL:
return AE_BAD_PARAMETER;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] ACPI EC: drop usage of ACPI_DEBUG_PRINT as too heavy weight
2007-05-29 12:42 [PATCH 0/3] Series short description Alexey Starikovskiy
2007-05-29 12:42 ` [PATCH 1/3] ACPI EC: Re-factor EC space handler to avoid using label/goto for cycle Alexey Starikovskiy
@ 2007-05-29 12:42 ` Alexey Starikovskiy
2007-06-23 20:03 ` Len Brown
2007-05-29 12:43 ` [PATCH 3/3] ACPI EC: Add support for non-AML EC query handlers Alexey Starikovskiy
2 siblings, 1 reply; 7+ messages in thread
From: Alexey Starikovskiy @ 2007-05-29 12:42 UTC (permalink / raw)
To: len.brown, linux-acpi; +Cc: Alexey Starikovskiy
Signed-off-by: Alexey Starikovskiy <aystarik@gmail.com>
---
drivers/acpi/ec.c | 20 ++++++--------------
1 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 5534b23..ffb8361 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -39,20 +39,19 @@
#include <acpi/acpi_drivers.h>
#include <acpi/actypes.h>
-#define _COMPONENT ACPI_EC_COMPONENT
-ACPI_MODULE_NAME("ec");
-#define ACPI_EC_COMPONENT 0x00100000
#define ACPI_EC_CLASS "embedded_controller"
#define ACPI_EC_HID "PNP0C09"
#define ACPI_EC_DEVICE_NAME "Embedded Controller"
#define ACPI_EC_FILE_INFO "info"
#undef PREFIX
#define PREFIX "ACPI: EC: "
+
/* EC status register */
#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
+
/* EC commands */
enum ec_command {
ACPI_EC_COMMAND_READ = 0x80,
@@ -245,7 +244,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0);
if (status) {
- printk(KERN_DEBUG PREFIX
+ printk(KERN_ERR PREFIX
"input buffer is not empty, aborting transaction\n");
goto end;
}
@@ -630,10 +629,6 @@ static int acpi_ec_add(struct acpi_device *device)
acpi_ec_add_fs(device);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
- acpi_device_name(device), acpi_device_bid(device),
- (u32) ec->gpe));
-
return 0;
}
@@ -718,9 +713,6 @@ static int acpi_ec_start(struct acpi_device *device)
if (!ec)
return -EINVAL;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
- ec->gpe, ec->command_addr, ec->data_addr));
-
/* Boot EC is already working */
if (ec == boot_ec)
return 0;
@@ -779,8 +771,8 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
ec->handle = handle;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
- ec->gpe, ec->command_addr, ec->data_addr));
+ printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
+ ec->gpe, ec->command_addr, ec->data_addr);
return AE_CTRL_TERMINATE;
}
@@ -803,7 +795,7 @@ int __init acpi_ec_ecdt_probe(void)
if (ACPI_FAILURE(status))
goto error;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
+ printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] ACPI EC: Add support for non-AML EC query handlers
2007-05-29 12:42 [PATCH 0/3] Series short description Alexey Starikovskiy
2007-05-29 12:42 ` [PATCH 1/3] ACPI EC: Re-factor EC space handler to avoid using label/goto for cycle Alexey Starikovskiy
2007-05-29 12:42 ` [PATCH 2/3] ACPI EC: drop usage of ACPI_DEBUG_PRINT as too heavy weight Alexey Starikovskiy
@ 2007-05-29 12:43 ` Alexey Starikovskiy
2007-06-23 20:07 ` Len Brown
2 siblings, 1 reply; 7+ messages in thread
From: Alexey Starikovskiy @ 2007-05-29 12:43 UTC (permalink / raw)
To: len.brown, linux-acpi; +Cc: Alexey Starikovskiy
Signed-off-by: Alexey Starikovskiy <aystarik@gmail.com>
---
drivers/acpi/ec.c | 175 ++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 125 insertions(+), 50 deletions(-)
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index ffb8361..10e8510 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -34,6 +34,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/interrupt.h>
+#include <linux/list.h>
#include <asm/io.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
@@ -43,6 +44,7 @@
#define ACPI_EC_HID "PNP0C09"
#define ACPI_EC_DEVICE_NAME "Embedded Controller"
#define ACPI_EC_FILE_INFO "info"
+
#undef PREFIX
#define PREFIX "ACPI: EC: "
@@ -60,6 +62,7 @@ enum ec_command {
ACPI_EC_BURST_DISABLE = 0x83,
ACPI_EC_COMMAND_QUERY = 0x84,
};
+
/* EC events */
enum ec_event {
ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
@@ -93,6 +96,16 @@ static struct acpi_driver acpi_ec_driver = {
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
/* External interfaces use first EC only, so remember */
+typedef int (*acpi_ec_query_func) (void *data);
+
+struct acpi_ec_query_handler {
+ struct list_head node;
+ acpi_ec_query_func func;
+ acpi_handle handle;
+ void *data;
+ u8 query_bit;
+};
+
static struct acpi_ec {
acpi_handle handle;
unsigned long gpe;
@@ -103,6 +116,7 @@ static struct acpi_ec {
atomic_t query_pending;
atomic_t event_count;
wait_queue_head_t wait;
+ struct list_head list;
} *boot_ec, *first_ec;
/* --------------------------------------------------------------------------
@@ -393,21 +407,67 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
/* --------------------------------------------------------------------------
Event Management
-------------------------------------------------------------------------- */
+int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
+ acpi_handle handle, acpi_ec_query_func func,
+ void *data)
+{
+ struct acpi_ec_query_handler *handler =
+ kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL);
+ if (!handler)
+ return -ENOMEM;
+
+ handler->query_bit = query_bit;
+ handler->handle = handle;
+ handler->func = func;
+ handler->data = data;
+ mutex_lock(&ec->lock);
+ list_add_tail(&handler->node, &ec->list);
+ mutex_unlock(&ec->lock);
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
+
+void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
+{
+ struct acpi_ec_query_handler *handler;
+ mutex_lock(&ec->lock);
+ list_for_each_entry(handler, &ec->list, node) {
+ if (query_bit == handler->query_bit) {
+ list_del(&handler->node);
+ kfree(handler);
+ break;
+ }
+ }
+ mutex_unlock(&ec->lock);
+}
+
+EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
static void acpi_ec_gpe_query(void *ec_cxt)
{
struct acpi_ec *ec = ec_cxt;
u8 value = 0;
- char object_name[8];
+ struct acpi_ec_query_handler *handler, copy;
if (!ec || acpi_ec_query(ec, &value))
return;
-
- snprintf(object_name, 8, "_Q%2.2X", value);
-
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
-
- acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
+ mutex_lock(&ec->lock);
+ list_for_each_entry(handler, &ec->list, node) {
+ if (value == handler->query_bit) {
+ /* have custom handler for this bit */
+ memcpy(©, handler, sizeof(copy));
+ mutex_unlock(&ec->lock);
+ if (copy.func) {
+ copy.func(copy.data);
+ } else if (copy.handle) {
+ acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
+ }
+ return;
+ }
+ }
+ mutex_unlock(&ec->lock);
+ printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
}
static u32 acpi_ec_gpe_handler(void *data)
@@ -426,8 +486,7 @@ static u32 acpi_ec_gpe_handler(void *data)
if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
atomic_set(&ec->query_pending, 1);
status =
- acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query,
- ec);
+ acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
}
return status == AE_OK ?
@@ -574,9 +633,6 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
static acpi_status
ec_parse_io_ports(struct acpi_resource *resource, void *context);
-static acpi_status
-ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval);
-
static struct acpi_ec *make_acpi_ec(void)
{
struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
@@ -587,13 +643,52 @@ static struct acpi_ec *make_acpi_ec(void)
atomic_set(&ec->event_count, 1);
mutex_init(&ec->lock);
init_waitqueue_head(&ec->wait);
+ INIT_LIST_HEAD(&ec->list);
return ec;
}
+static acpi_status
+acpi_ec_register_query_methods(acpi_handle handle, u32 level,
+ void *context, void **return_value)
+{
+ struct acpi_namespace_node *node = handle;
+ struct acpi_ec *ec = context;
+ int value = 0;
+ if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
+ acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
+ }
+ return AE_OK;
+}
+
+static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle)
+{
+ if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS,
+ ec_parse_io_ports, ec)))
+ return -EINVAL;
+
+ /* Get GPE bit assignment (EC events). */
+ /* TODO: Add support for _GPE returning a package */
+ if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe)))
+ return -EINVAL;
+
+ /* Use the global lock for all EC transactions? */
+ acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
+
+ /* Find and register all query methods */
+ acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
+ acpi_ec_register_query_methods, ec, NULL);
+
+ ec->handle = handle;
+
+ printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
+ ec->gpe, ec->command_addr, ec->data_addr);
+
+ return 0;
+}
+
static int acpi_ec_add(struct acpi_device *device)
{
- acpi_status status = AE_OK;
struct acpi_ec *ec = NULL;
if (!device)
@@ -606,8 +701,7 @@ static int acpi_ec_add(struct acpi_device *device)
if (!ec)
return -ENOMEM;
- status = ec_parse_device(device->handle, 0, ec, NULL);
- if (status != AE_CTRL_TERMINATE) {
+ if (ec_parse_device(ec, device->handle)) {
kfree(ec);
return -EINVAL;
}
@@ -618,6 +712,8 @@ static int acpi_ec_add(struct acpi_device *device)
/* We might have incorrect info for GL at boot time */
mutex_lock(&boot_ec->lock);
boot_ec->global_lock = ec->global_lock;
+ /* Copy handlers from new ec into boot ec */
+ list_splice(&ec->list, &boot_ec->list);
mutex_unlock(&boot_ec->lock);
kfree(ec);
ec = boot_ec;
@@ -628,18 +724,24 @@ static int acpi_ec_add(struct acpi_device *device)
acpi_driver_data(device) = ec;
acpi_ec_add_fs(device);
-
return 0;
}
static int acpi_ec_remove(struct acpi_device *device, int type)
{
struct acpi_ec *ec;
+ struct acpi_ec_query_handler *handler;
if (!device)
return -EINVAL;
ec = acpi_driver_data(device);
+ mutex_lock(&ec->lock);
+ list_for_each_entry(handler, &ec->list, node) {
+ list_del(&handler->node);
+ kfree(handler);
+ }
+ mutex_unlock(&ec->lock);
acpi_ec_remove_fs(device);
acpi_driver_data(device) = NULL;
if (ec == first_ec)
@@ -695,15 +797,13 @@ static int ec_install_handlers(struct acpi_ec *ec)
return -ENODEV;
}
- /* EC is fully operational, allow queries */
- atomic_set(&ec->query_pending, 0);
-
return 0;
}
static int acpi_ec_start(struct acpi_device *device)
{
struct acpi_ec *ec;
+ int ret = 0;
if (!device)
return -EINVAL;
@@ -714,10 +814,13 @@ static int acpi_ec_start(struct acpi_device *device)
return -EINVAL;
/* Boot EC is already working */
- if (ec == boot_ec)
- return 0;
+ if (ec != boot_ec)
+ ret = ec_install_handlers(ec);
+
+ /* EC is fully operational, allow queries */
+ atomic_set(&ec->query_pending, 0);
- return ec_install_handlers(ec);
+ return ret;
}
static int acpi_ec_stop(struct acpi_device *device, int type)
@@ -749,34 +852,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
return 0;
}
-static acpi_status
-ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
-{
- acpi_status status;
-
- struct acpi_ec *ec = context;
- status = acpi_walk_resources(handle, METHOD_NAME__CRS,
- ec_parse_io_ports, ec);
- if (ACPI_FAILURE(status))
- return status;
-
- /* Get GPE bit assignment (EC events). */
- /* TODO: Add support for _GPE returning a package */
- status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
- if (ACPI_FAILURE(status))
- return status;
-
- /* Use the global lock for all EC transactions? */
- acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
-
- ec->handle = handle;
-
- printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
- ec->gpe, ec->command_addr, ec->data_addr);
-
- return AE_CTRL_TERMINATE;
-}
-
int __init acpi_ec_ecdt_probe(void)
{
int ret;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] ACPI EC: Re-factor EC space handler to avoid using label/goto for cycle.
2007-05-29 12:42 ` [PATCH 1/3] ACPI EC: Re-factor EC space handler to avoid using label/goto for cycle Alexey Starikovskiy
@ 2007-06-23 20:02 ` Len Brown
0 siblings, 0 replies; 7+ messages in thread
From: Len Brown @ 2007-06-23 20:02 UTC (permalink / raw)
To: Alexey Starikovskiy; +Cc: linux-acpi
Applied.
thanks,
-Len
On Tuesday 29 May 2007 08:42, Alexey Starikovskiy wrote:
> Signed-off-by: Alexey Starikovskiy <aystarik@gmail.com>
> ---
>
> drivers/acpi/ec.c | 56 ++++++++++++++++-------------------------------------
> 1 files changed, 17 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
> index 82f496c..5534b23 100644
> --- a/drivers/acpi/ec.c
> +++ b/drivers/acpi/ec.c
> @@ -454,57 +454,35 @@ acpi_ec_space_setup(acpi_handle region_handle,
> }
>
> static acpi_status
> -acpi_ec_space_handler(u32 function,
> - acpi_physical_address address,
> - u32 bit_width,
> - acpi_integer * value,
> +acpi_ec_space_handler(u32 function, acpi_physical_address address,
> + u32 bits, acpi_integer *value,
> void *handler_context, void *region_context)
> {
> - int result = 0;
> struct acpi_ec *ec = handler_context;
> - u64 temp = *value;
> - acpi_integer f_v = 0;
> - int i = 0;
> + int result = 0, i = 0;
> + u8 temp = 0;
>
> if ((address > 0xFF) || !value || !handler_context)
> return AE_BAD_PARAMETER;
>
> - if (bit_width != 8 && acpi_strict) {
> + if (function != ACPI_READ && function != ACPI_WRITE)
> return AE_BAD_PARAMETER;
> - }
> -
> - next_byte:
> - switch (function) {
> - case ACPI_READ:
> - temp = 0;
> - result = acpi_ec_read(ec, (u8) address, (u8 *) & temp);
> - break;
> - case ACPI_WRITE:
> - result = acpi_ec_write(ec, (u8) address, (u8) temp);
> - break;
> - default:
> - result = -EINVAL;
> - goto out;
> - break;
> - }
>
> - bit_width -= 8;
> - if (bit_width) {
> - if (function == ACPI_READ)
> - f_v |= temp << 8 * i;
> - if (function == ACPI_WRITE)
> - temp >>= 8;
> - i++;
> - address++;
> - goto next_byte;
> - }
> + if (bits != 8 && acpi_strict)
> + return AE_BAD_PARAMETER;
>
> - if (function == ACPI_READ) {
> - f_v |= temp << 8 * i;
> - *value = f_v;
> + while (bits - i > 0) {
> + if (function == ACPI_READ) {
> + result = acpi_ec_read(ec, address, &temp);
> + (*value) |= ((acpi_integer)temp) << i;
> + } else {
> + temp = 0xff & ((*value) >> i);
> + result = acpi_ec_write(ec, address, temp);
> + }
> + i += 8;
> + ++address;
> }
>
> - out:
> switch (result) {
> case -EINVAL:
> return AE_BAD_PARAMETER;
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] ACPI EC: drop usage of ACPI_DEBUG_PRINT as too heavy weight
2007-05-29 12:42 ` [PATCH 2/3] ACPI EC: drop usage of ACPI_DEBUG_PRINT as too heavy weight Alexey Starikovskiy
@ 2007-06-23 20:03 ` Len Brown
0 siblings, 0 replies; 7+ messages in thread
From: Len Brown @ 2007-06-23 20:03 UTC (permalink / raw)
To: Alexey Starikovskiy; +Cc: linux-acpi
Applied.
thanks,
-Len
On Tuesday 29 May 2007 08:42, Alexey Starikovskiy wrote:
> Signed-off-by: Alexey Starikovskiy <aystarik@gmail.com>
> ---
>
> drivers/acpi/ec.c | 20 ++++++--------------
> 1 files changed, 6 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
> index 5534b23..ffb8361 100644
> --- a/drivers/acpi/ec.c
> +++ b/drivers/acpi/ec.c
> @@ -39,20 +39,19 @@
> #include <acpi/acpi_drivers.h>
> #include <acpi/actypes.h>
>
> -#define _COMPONENT ACPI_EC_COMPONENT
> -ACPI_MODULE_NAME("ec");
> -#define ACPI_EC_COMPONENT 0x00100000
> #define ACPI_EC_CLASS "embedded_controller"
> #define ACPI_EC_HID "PNP0C09"
> #define ACPI_EC_DEVICE_NAME "Embedded Controller"
> #define ACPI_EC_FILE_INFO "info"
> #undef PREFIX
> #define PREFIX "ACPI: EC: "
> +
> /* EC status register */
> #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
> #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
> #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
> #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
> +
> /* EC commands */
> enum ec_command {
> ACPI_EC_COMMAND_READ = 0x80,
> @@ -245,7 +244,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
>
> status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0);
> if (status) {
> - printk(KERN_DEBUG PREFIX
> + printk(KERN_ERR PREFIX
> "input buffer is not empty, aborting transaction\n");
> goto end;
> }
> @@ -630,10 +629,6 @@ static int acpi_ec_add(struct acpi_device *device)
>
> acpi_ec_add_fs(device);
>
> - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
> - acpi_device_name(device), acpi_device_bid(device),
> - (u32) ec->gpe));
> -
> return 0;
> }
>
> @@ -718,9 +713,6 @@ static int acpi_ec_start(struct acpi_device *device)
> if (!ec)
> return -EINVAL;
>
> - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
> - ec->gpe, ec->command_addr, ec->data_addr));
> -
> /* Boot EC is already working */
> if (ec == boot_ec)
> return 0;
> @@ -779,8 +771,8 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
>
> ec->handle = handle;
>
> - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
> - ec->gpe, ec->command_addr, ec->data_addr));
> + printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
> + ec->gpe, ec->command_addr, ec->data_addr);
>
> return AE_CTRL_TERMINATE;
> }
> @@ -803,7 +795,7 @@ int __init acpi_ec_ecdt_probe(void)
> if (ACPI_FAILURE(status))
> goto error;
>
> - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
> + printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
>
> boot_ec->command_addr = ecdt_ptr->control.address;
> boot_ec->data_addr = ecdt_ptr->data.address;
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] ACPI EC: Add support for non-AML EC query handlers
2007-05-29 12:43 ` [PATCH 3/3] ACPI EC: Add support for non-AML EC query handlers Alexey Starikovskiy
@ 2007-06-23 20:07 ` Len Brown
0 siblings, 0 replies; 7+ messages in thread
From: Len Brown @ 2007-06-23 20:07 UTC (permalink / raw)
To: Alexey Starikovskiy; +Cc: linux-acpi
What is the benefit of this patch?
(it would be good to say in the check-in comments...hint hint)
Also, if you want your git commit author tag to be
"Alexey Starikovskiy <astarikovskiy@suse.de>" as you mentioned earlier,
then this would be a good time to cut over to sending patches From
and signed-off-by that address.
thanks,
-Len
On Tuesday 29 May 2007 08:43, Alexey Starikovskiy wrote:
> Signed-off-by: Alexey Starikovskiy <aystarik@gmail.com>
> ---
>
> drivers/acpi/ec.c | 175 ++++++++++++++++++++++++++++++++++++++---------------
> 1 files changed, 125 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
> index ffb8361..10e8510 100644
> --- a/drivers/acpi/ec.c
> +++ b/drivers/acpi/ec.c
> @@ -34,6 +34,7 @@
> #include <linux/proc_fs.h>
> #include <linux/seq_file.h>
> #include <linux/interrupt.h>
> +#include <linux/list.h>
> #include <asm/io.h>
> #include <acpi/acpi_bus.h>
> #include <acpi/acpi_drivers.h>
> @@ -43,6 +44,7 @@
> #define ACPI_EC_HID "PNP0C09"
> #define ACPI_EC_DEVICE_NAME "Embedded Controller"
> #define ACPI_EC_FILE_INFO "info"
> +
> #undef PREFIX
> #define PREFIX "ACPI: EC: "
>
> @@ -60,6 +62,7 @@ enum ec_command {
> ACPI_EC_BURST_DISABLE = 0x83,
> ACPI_EC_COMMAND_QUERY = 0x84,
> };
> +
> /* EC events */
> enum ec_event {
> ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
> @@ -93,6 +96,16 @@ static struct acpi_driver acpi_ec_driver = {
>
> /* If we find an EC via the ECDT, we need to keep a ptr to its context */
> /* External interfaces use first EC only, so remember */
> +typedef int (*acpi_ec_query_func) (void *data);
> +
> +struct acpi_ec_query_handler {
> + struct list_head node;
> + acpi_ec_query_func func;
> + acpi_handle handle;
> + void *data;
> + u8 query_bit;
> +};
> +
> static struct acpi_ec {
> acpi_handle handle;
> unsigned long gpe;
> @@ -103,6 +116,7 @@ static struct acpi_ec {
> atomic_t query_pending;
> atomic_t event_count;
> wait_queue_head_t wait;
> + struct list_head list;
> } *boot_ec, *first_ec;
>
> /* --------------------------------------------------------------------------
> @@ -393,21 +407,67 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
> /* --------------------------------------------------------------------------
> Event Management
> -------------------------------------------------------------------------- */
> +int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
> + acpi_handle handle, acpi_ec_query_func func,
> + void *data)
> +{
> + struct acpi_ec_query_handler *handler =
> + kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL);
> + if (!handler)
> + return -ENOMEM;
> +
> + handler->query_bit = query_bit;
> + handler->handle = handle;
> + handler->func = func;
> + handler->data = data;
> + mutex_lock(&ec->lock);
> + list_add_tail(&handler->node, &ec->list);
> + mutex_unlock(&ec->lock);
> + return 0;
> +}
> +
> +EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
> +
> +void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
> +{
> + struct acpi_ec_query_handler *handler;
> + mutex_lock(&ec->lock);
> + list_for_each_entry(handler, &ec->list, node) {
> + if (query_bit == handler->query_bit) {
> + list_del(&handler->node);
> + kfree(handler);
> + break;
> + }
> + }
> + mutex_unlock(&ec->lock);
> +}
> +
> +EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
>
> static void acpi_ec_gpe_query(void *ec_cxt)
> {
> struct acpi_ec *ec = ec_cxt;
> u8 value = 0;
> - char object_name[8];
> + struct acpi_ec_query_handler *handler, copy;
>
> if (!ec || acpi_ec_query(ec, &value))
> return;
> -
> - snprintf(object_name, 8, "_Q%2.2X", value);
> -
> - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
> -
> - acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
> + mutex_lock(&ec->lock);
> + list_for_each_entry(handler, &ec->list, node) {
> + if (value == handler->query_bit) {
> + /* have custom handler for this bit */
> + memcpy(©, handler, sizeof(copy));
> + mutex_unlock(&ec->lock);
> + if (copy.func) {
> + copy.func(copy.data);
> + } else if (copy.handle) {
> + acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
> + }
> + return;
> + }
> + }
> + mutex_unlock(&ec->lock);
> + printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
> }
>
> static u32 acpi_ec_gpe_handler(void *data)
> @@ -426,8 +486,7 @@ static u32 acpi_ec_gpe_handler(void *data)
> if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
> atomic_set(&ec->query_pending, 1);
> status =
> - acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query,
> - ec);
> + acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
> }
>
> return status == AE_OK ?
> @@ -574,9 +633,6 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
> static acpi_status
> ec_parse_io_ports(struct acpi_resource *resource, void *context);
>
> -static acpi_status
> -ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval);
> -
> static struct acpi_ec *make_acpi_ec(void)
> {
> struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
> @@ -587,13 +643,52 @@ static struct acpi_ec *make_acpi_ec(void)
> atomic_set(&ec->event_count, 1);
> mutex_init(&ec->lock);
> init_waitqueue_head(&ec->wait);
> + INIT_LIST_HEAD(&ec->list);
>
> return ec;
> }
>
> +static acpi_status
> +acpi_ec_register_query_methods(acpi_handle handle, u32 level,
> + void *context, void **return_value)
> +{
> + struct acpi_namespace_node *node = handle;
> + struct acpi_ec *ec = context;
> + int value = 0;
> + if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
> + acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
> + }
> + return AE_OK;
> +}
> +
> +static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle)
> +{
> + if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS,
> + ec_parse_io_ports, ec)))
> + return -EINVAL;
> +
> + /* Get GPE bit assignment (EC events). */
> + /* TODO: Add support for _GPE returning a package */
> + if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe)))
> + return -EINVAL;
> +
> + /* Use the global lock for all EC transactions? */
> + acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
> +
> + /* Find and register all query methods */
> + acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
> + acpi_ec_register_query_methods, ec, NULL);
> +
> + ec->handle = handle;
> +
> + printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
> + ec->gpe, ec->command_addr, ec->data_addr);
> +
> + return 0;
> +}
> +
> static int acpi_ec_add(struct acpi_device *device)
> {
> - acpi_status status = AE_OK;
> struct acpi_ec *ec = NULL;
>
> if (!device)
> @@ -606,8 +701,7 @@ static int acpi_ec_add(struct acpi_device *device)
> if (!ec)
> return -ENOMEM;
>
> - status = ec_parse_device(device->handle, 0, ec, NULL);
> - if (status != AE_CTRL_TERMINATE) {
> + if (ec_parse_device(ec, device->handle)) {
> kfree(ec);
> return -EINVAL;
> }
> @@ -618,6 +712,8 @@ static int acpi_ec_add(struct acpi_device *device)
> /* We might have incorrect info for GL at boot time */
> mutex_lock(&boot_ec->lock);
> boot_ec->global_lock = ec->global_lock;
> + /* Copy handlers from new ec into boot ec */
> + list_splice(&ec->list, &boot_ec->list);
> mutex_unlock(&boot_ec->lock);
> kfree(ec);
> ec = boot_ec;
> @@ -628,18 +724,24 @@ static int acpi_ec_add(struct acpi_device *device)
> acpi_driver_data(device) = ec;
>
> acpi_ec_add_fs(device);
> -
> return 0;
> }
>
> static int acpi_ec_remove(struct acpi_device *device, int type)
> {
> struct acpi_ec *ec;
> + struct acpi_ec_query_handler *handler;
>
> if (!device)
> return -EINVAL;
>
> ec = acpi_driver_data(device);
> + mutex_lock(&ec->lock);
> + list_for_each_entry(handler, &ec->list, node) {
> + list_del(&handler->node);
> + kfree(handler);
> + }
> + mutex_unlock(&ec->lock);
> acpi_ec_remove_fs(device);
> acpi_driver_data(device) = NULL;
> if (ec == first_ec)
> @@ -695,15 +797,13 @@ static int ec_install_handlers(struct acpi_ec *ec)
> return -ENODEV;
> }
>
> - /* EC is fully operational, allow queries */
> - atomic_set(&ec->query_pending, 0);
> -
> return 0;
> }
>
> static int acpi_ec_start(struct acpi_device *device)
> {
> struct acpi_ec *ec;
> + int ret = 0;
>
> if (!device)
> return -EINVAL;
> @@ -714,10 +814,13 @@ static int acpi_ec_start(struct acpi_device *device)
> return -EINVAL;
>
> /* Boot EC is already working */
> - if (ec == boot_ec)
> - return 0;
> + if (ec != boot_ec)
> + ret = ec_install_handlers(ec);
> +
> + /* EC is fully operational, allow queries */
> + atomic_set(&ec->query_pending, 0);
>
> - return ec_install_handlers(ec);
> + return ret;
> }
>
> static int acpi_ec_stop(struct acpi_device *device, int type)
> @@ -749,34 +852,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
> return 0;
> }
>
> -static acpi_status
> -ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
> -{
> - acpi_status status;
> -
> - struct acpi_ec *ec = context;
> - status = acpi_walk_resources(handle, METHOD_NAME__CRS,
> - ec_parse_io_ports, ec);
> - if (ACPI_FAILURE(status))
> - return status;
> -
> - /* Get GPE bit assignment (EC events). */
> - /* TODO: Add support for _GPE returning a package */
> - status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
> - if (ACPI_FAILURE(status))
> - return status;
> -
> - /* Use the global lock for all EC transactions? */
> - acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
> -
> - ec->handle = handle;
> -
> - printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
> - ec->gpe, ec->command_addr, ec->data_addr);
> -
> - return AE_CTRL_TERMINATE;
> -}
> -
> int __init acpi_ec_ecdt_probe(void)
> {
> int ret;
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2007-06-23 20:07 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-29 12:42 [PATCH 0/3] Series short description Alexey Starikovskiy
2007-05-29 12:42 ` [PATCH 1/3] ACPI EC: Re-factor EC space handler to avoid using label/goto for cycle Alexey Starikovskiy
2007-06-23 20:02 ` Len Brown
2007-05-29 12:42 ` [PATCH 2/3] ACPI EC: drop usage of ACPI_DEBUG_PRINT as too heavy weight Alexey Starikovskiy
2007-06-23 20:03 ` Len Brown
2007-05-29 12:43 ` [PATCH 3/3] ACPI EC: Add support for non-AML EC query handlers Alexey Starikovskiy
2007-06-23 20:07 ` Len Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).