diff options
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r-- | drivers/acpi/ec.c | 129 |
1 files changed, 30 insertions, 99 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e61d4f8e62a5..1fa0aafebe2a 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 */ |