summaryrefslogtreecommitdiff
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r--drivers/acpi/ec.c129
1 files changed, 30 insertions, 99 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e61d4f8e62a..1fa0aafebe2 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -34,8 +34,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/spinlock.h>
@@ -45,10 +43,13 @@
#include <acpi/acpi_drivers.h>
#include <linux/dmi.h>
+#include "internal.h"
+
#define ACPI_EC_CLASS "embedded_controller"
#define ACPI_EC_DEVICE_NAME "Embedded Controller"
#define ACPI_EC_FILE_INFO "info"
+#undef PREFIX
#define PREFIX "ACPI: EC: "
/* EC status register */
@@ -79,7 +80,7 @@ enum {
EC_FLAGS_GPE_STORM, /* GPE storm detected */
EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and
* OpReg are installed */
- EC_FLAGS_FROZEN, /* Transactions are suspended */
+ EC_FLAGS_BLOCKED, /* Transactions are blocked */
};
/* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -106,19 +107,8 @@ struct transaction {
bool done;
};
-static struct acpi_ec {
- acpi_handle handle;
- unsigned long gpe;
- unsigned long command_addr;
- unsigned long data_addr;
- unsigned long global_lock;
- unsigned long flags;
- struct mutex lock;
- wait_queue_head_t wait;
- struct list_head list;
- struct transaction *curr;
- spinlock_t curr_lock;
-} *boot_ec, *first_ec;
+struct acpi_ec *boot_ec, *first_ec;
+EXPORT_SYMBOL(first_ec);
static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
@@ -293,7 +283,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
if (t->rdata)
memset(t->rdata, 0, t->rlen);
mutex_lock(&ec->lock);
- if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) {
+ if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) {
status = -EINVAL;
goto unlock;
}
@@ -459,7 +449,7 @@ int ec_transaction(u8 command,
EXPORT_SYMBOL(ec_transaction);
-void acpi_ec_suspend_transactions(void)
+void acpi_ec_block_transactions(void)
{
struct acpi_ec *ec = first_ec;
@@ -468,11 +458,11 @@ void acpi_ec_suspend_transactions(void)
mutex_lock(&ec->lock);
/* Prevent transactions from being carried out */
- set_bit(EC_FLAGS_FROZEN, &ec->flags);
+ set_bit(EC_FLAGS_BLOCKED, &ec->flags);
mutex_unlock(&ec->lock);
}
-void acpi_ec_resume_transactions(void)
+void acpi_ec_unblock_transactions(void)
{
struct acpi_ec *ec = first_ec;
@@ -481,10 +471,20 @@ void acpi_ec_resume_transactions(void)
mutex_lock(&ec->lock);
/* Allow transactions to be carried out again */
- clear_bit(EC_FLAGS_FROZEN, &ec->flags);
+ clear_bit(EC_FLAGS_BLOCKED, &ec->flags);
mutex_unlock(&ec->lock);
}
+void acpi_ec_unblock_transactions_early(void)
+{
+ /*
+ * Allow transactions to happen again (this function is called from
+ * atomic context during wakeup, so we don't need to acquire the mutex).
+ */
+ if (first_ec)
+ clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags);
+}
+
static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
{
int result;
@@ -669,72 +669,6 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
}
/* --------------------------------------------------------------------------
- FS Interface (/proc)
- -------------------------------------------------------------------------- */
-
-static struct proc_dir_entry *acpi_ec_dir;
-
-static int acpi_ec_read_info(struct seq_file *seq, void *offset)
-{
- struct acpi_ec *ec = seq->private;
-
- if (!ec)
- goto end;
-
- seq_printf(seq, "gpe:\t\t\t0x%02x\n", (u32) ec->gpe);
- seq_printf(seq, "ports:\t\t\t0x%02x, 0x%02x\n",
- (unsigned)ec->command_addr, (unsigned)ec->data_addr);
- seq_printf(seq, "use global lock:\t%s\n",
- ec->global_lock ? "yes" : "no");
- end:
- return 0;
-}
-
-static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_ec_read_info, PDE(inode)->data);
-}
-
-static const struct file_operations acpi_ec_info_ops = {
- .open = acpi_ec_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
-};
-
-static int acpi_ec_add_fs(struct acpi_device *device)
-{
- struct proc_dir_entry *entry = NULL;
-
- if (!acpi_device_dir(device)) {
- acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
- acpi_ec_dir);
- if (!acpi_device_dir(device))
- return -ENODEV;
- }
-
- entry = proc_create_data(ACPI_EC_FILE_INFO, S_IRUGO,
- acpi_device_dir(device),
- &acpi_ec_info_ops, acpi_driver_data(device));
- if (!entry)
- return -ENODEV;
- return 0;
-}
-
-static int acpi_ec_remove_fs(struct acpi_device *device)
-{
-
- if (acpi_device_dir(device)) {
- remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device));
- remove_proc_entry(acpi_device_bid(device), acpi_ec_dir);
- acpi_device_dir(device) = NULL;
- }
-
- return 0;
-}
-
-/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
static acpi_status
@@ -884,7 +818,12 @@ static int acpi_ec_add(struct acpi_device *device)
if (!first_ec)
first_ec = ec;
device->driver_data = ec;
- acpi_ec_add_fs(device);
+
+ WARN(!request_region(ec->data_addr, 1, "EC data"),
+ "Could not request EC data io port 0x%lx", ec->data_addr);
+ WARN(!request_region(ec->command_addr, 1, "EC cmd"),
+ "Could not request EC cmd io port 0x%lx", ec->command_addr);
+
pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
ec->gpe, ec->command_addr, ec->data_addr);
@@ -911,7 +850,8 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
kfree(handler);
}
mutex_unlock(&ec->lock);
- acpi_ec_remove_fs(device);
+ release_region(ec->data_addr, 1);
+ release_region(ec->command_addr, 1);
device->driver_data = NULL;
if (ec == first_ec)
first_ec = NULL;
@@ -1110,16 +1050,10 @@ int __init acpi_ec_init(void)
{
int result = 0;
- acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
- if (!acpi_ec_dir)
- return -ENODEV;
-
/* Now register the driver for the EC */
result = acpi_bus_register_driver(&acpi_ec_driver);
- if (result < 0) {
- remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
+ if (result < 0)
return -ENODEV;
- }
return result;
}
@@ -1130,9 +1064,6 @@ static void __exit acpi_ec_exit(void)
{
acpi_bus_unregister_driver(&acpi_ec_driver);
-
- remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
-
return;
}
#endif /* 0 */