aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r--drivers/acpi/ec.c107
1 files changed, 14 insertions, 93 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 1e6d4184f0ea..f31291ba94d0 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -34,8 +34,6 @@
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/types.h> 35#include <linux/types.h>
36#include <linux/delay.h> 36#include <linux/delay.h>
37#include <linux/proc_fs.h>
38#include <linux/seq_file.h>
39#include <linux/interrupt.h> 37#include <linux/interrupt.h>
40#include <linux/list.h> 38#include <linux/list.h>
41#include <linux/spinlock.h> 39#include <linux/spinlock.h>
@@ -45,10 +43,13 @@
45#include <acpi/acpi_drivers.h> 43#include <acpi/acpi_drivers.h>
46#include <linux/dmi.h> 44#include <linux/dmi.h>
47 45
46#include "internal.h"
47
48#define ACPI_EC_CLASS "embedded_controller" 48#define ACPI_EC_CLASS "embedded_controller"
49#define ACPI_EC_DEVICE_NAME "Embedded Controller" 49#define ACPI_EC_DEVICE_NAME "Embedded Controller"
50#define ACPI_EC_FILE_INFO "info" 50#define ACPI_EC_FILE_INFO "info"
51 51
52#undef PREFIX
52#define PREFIX "ACPI: EC: " 53#define PREFIX "ACPI: EC: "
53 54
54/* EC status register */ 55/* EC status register */
@@ -106,19 +107,8 @@ struct transaction {
106 bool done; 107 bool done;
107}; 108};
108 109
109static struct acpi_ec { 110struct acpi_ec *boot_ec, *first_ec;
110 acpi_handle handle; 111EXPORT_SYMBOL(first_ec);
111 unsigned long gpe;
112 unsigned long command_addr;
113 unsigned long data_addr;
114 unsigned long global_lock;
115 unsigned long flags;
116 struct mutex lock;
117 wait_queue_head_t wait;
118 struct list_head list;
119 struct transaction *curr;
120 spinlock_t curr_lock;
121} *boot_ec, *first_ec;
122 112
123static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ 113static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
124static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ 114static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
@@ -672,72 +662,6 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
672} 662}
673 663
674/* -------------------------------------------------------------------------- 664/* --------------------------------------------------------------------------
675 FS Interface (/proc)
676 -------------------------------------------------------------------------- */
677
678static struct proc_dir_entry *acpi_ec_dir;
679
680static int acpi_ec_read_info(struct seq_file *seq, void *offset)
681{
682 struct acpi_ec *ec = seq->private;
683
684 if (!ec)
685 goto end;
686
687 seq_printf(seq, "gpe:\t\t\t0x%02x\n", (u32) ec->gpe);
688 seq_printf(seq, "ports:\t\t\t0x%02x, 0x%02x\n",
689 (unsigned)ec->command_addr, (unsigned)ec->data_addr);
690 seq_printf(seq, "use global lock:\t%s\n",
691 ec->global_lock ? "yes" : "no");
692 end:
693 return 0;
694}
695
696static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
697{
698 return single_open(file, acpi_ec_read_info, PDE(inode)->data);
699}
700
701static const struct file_operations acpi_ec_info_ops = {
702 .open = acpi_ec_info_open_fs,
703 .read = seq_read,
704 .llseek = seq_lseek,
705 .release = single_release,
706 .owner = THIS_MODULE,
707};
708
709static int acpi_ec_add_fs(struct acpi_device *device)
710{
711 struct proc_dir_entry *entry = NULL;
712
713 if (!acpi_device_dir(device)) {
714 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
715 acpi_ec_dir);
716 if (!acpi_device_dir(device))
717 return -ENODEV;
718 }
719
720 entry = proc_create_data(ACPI_EC_FILE_INFO, S_IRUGO,
721 acpi_device_dir(device),
722 &acpi_ec_info_ops, acpi_driver_data(device));
723 if (!entry)
724 return -ENODEV;
725 return 0;
726}
727
728static int acpi_ec_remove_fs(struct acpi_device *device)
729{
730
731 if (acpi_device_dir(device)) {
732 remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device));
733 remove_proc_entry(acpi_device_bid(device), acpi_ec_dir);
734 acpi_device_dir(device) = NULL;
735 }
736
737 return 0;
738}
739
740/* --------------------------------------------------------------------------
741 Driver Interface 665 Driver Interface
742 -------------------------------------------------------------------------- */ 666 -------------------------------------------------------------------------- */
743static acpi_status 667static acpi_status
@@ -887,7 +811,12 @@ static int acpi_ec_add(struct acpi_device *device)
887 if (!first_ec) 811 if (!first_ec)
888 first_ec = ec; 812 first_ec = ec;
889 device->driver_data = ec; 813 device->driver_data = ec;
890 acpi_ec_add_fs(device); 814
815 WARN(!request_region(ec->data_addr, 1, "EC data"),
816 "Could not request EC data io port 0x%lx", ec->data_addr);
817 WARN(!request_region(ec->command_addr, 1, "EC cmd"),
818 "Could not request EC cmd io port 0x%lx", ec->command_addr);
819
891 pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", 820 pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
892 ec->gpe, ec->command_addr, ec->data_addr); 821 ec->gpe, ec->command_addr, ec->data_addr);
893 822
@@ -914,7 +843,8 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
914 kfree(handler); 843 kfree(handler);
915 } 844 }
916 mutex_unlock(&ec->lock); 845 mutex_unlock(&ec->lock);
917 acpi_ec_remove_fs(device); 846 release_region(ec->data_addr, 1);
847 release_region(ec->command_addr, 1);
918 device->driver_data = NULL; 848 device->driver_data = NULL;
919 if (ec == first_ec) 849 if (ec == first_ec)
920 first_ec = NULL; 850 first_ec = NULL;
@@ -1095,16 +1025,10 @@ int __init acpi_ec_init(void)
1095{ 1025{
1096 int result = 0; 1026 int result = 0;
1097 1027
1098 acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
1099 if (!acpi_ec_dir)
1100 return -ENODEV;
1101
1102 /* Now register the driver for the EC */ 1028 /* Now register the driver for the EC */
1103 result = acpi_bus_register_driver(&acpi_ec_driver); 1029 result = acpi_bus_register_driver(&acpi_ec_driver);
1104 if (result < 0) { 1030 if (result < 0)
1105 remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
1106 return -ENODEV; 1031 return -ENODEV;
1107 }
1108 1032
1109 return result; 1033 return result;
1110} 1034}
@@ -1115,9 +1039,6 @@ static void __exit acpi_ec_exit(void)
1115{ 1039{
1116 1040
1117 acpi_bus_unregister_driver(&acpi_ec_driver); 1041 acpi_bus_unregister_driver(&acpi_ec_driver);
1118
1119 remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
1120
1121 return; 1042 return;
1122} 1043}
1123#endif /* 0 */ 1044#endif /* 0 */