aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-04 13:44:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-04 13:44:06 -0400
commitc145307a110c14d09d5d92ff3c49dc0940e44b80 (patch)
treecba923818dea8857022de06ffd94ec6b2967aa1f /drivers/acpi/ec.c
parent5e83f6fbdb020b70c0e413312801424d13c58d68 (diff)
parent1a14703d6b20010401ca273ac1f07bff7992aa2c (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86: (88 commits) ips driver: make it less chatty intel_scu_ipc: fix size field for intel_scu_ipc_command intel_scu_ipc: return -EIO for error condition in busy_loop intel_scu_ipc: fix data packing of PMIC command on Moorestown Clean up command packing on MRST. zero the stack buffer before giving random garbage to the SCU Fix stack buffer size for IPC writev messages intel_scu_ipc: Use the new cpu identification function intel_scu_ipc: tidy up unused bits Remove indirect read write api support. intel_scu_ipc: Support Medfield processors intel_scu_ipc: detect CPU type automatically x86 plat: limit x86 platform driver menu to X86 acpi ec_sys: Be more cautious about ec write access acpi ec: Fix possible double io port registration hp-wmi: acpi_drivers.h is already included through acpi.h two lines below hp-wmi: Fix mixing up of and/or directive dell-laptop: make dell_laptop_i8042_filter() static asus-laptop: fix asus_input_init error path msi-wmi: make needlessly global symbols static ...
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 5f2027d782e8..1fa0aafebe2a 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 */
@@ -679,72 +669,6 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
679} 669}
680 670
681/* -------------------------------------------------------------------------- 671/* --------------------------------------------------------------------------
682 FS Interface (/proc)
683 -------------------------------------------------------------------------- */
684
685static struct proc_dir_entry *acpi_ec_dir;
686
687static int acpi_ec_read_info(struct seq_file *seq, void *offset)
688{
689 struct acpi_ec *ec = seq->private;
690
691 if (!ec)
692 goto end;
693
694 seq_printf(seq, "gpe:\t\t\t0x%02x\n", (u32) ec->gpe);
695 seq_printf(seq, "ports:\t\t\t0x%02x, 0x%02x\n",
696 (unsigned)ec->command_addr, (unsigned)ec->data_addr);
697 seq_printf(seq, "use global lock:\t%s\n",
698 ec->global_lock ? "yes" : "no");
699 end:
700 return 0;
701}
702
703static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
704{
705 return single_open(file, acpi_ec_read_info, PDE(inode)->data);
706}
707
708static const struct file_operations acpi_ec_info_ops = {
709 .open = acpi_ec_info_open_fs,
710 .read = seq_read,
711 .llseek = seq_lseek,
712 .release = single_release,
713 .owner = THIS_MODULE,
714};
715
716static int acpi_ec_add_fs(struct acpi_device *device)
717{
718 struct proc_dir_entry *entry = NULL;
719
720 if (!acpi_device_dir(device)) {
721 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
722 acpi_ec_dir);
723 if (!acpi_device_dir(device))
724 return -ENODEV;
725 }
726
727 entry = proc_create_data(ACPI_EC_FILE_INFO, S_IRUGO,
728 acpi_device_dir(device),
729 &acpi_ec_info_ops, acpi_driver_data(device));
730 if (!entry)
731 return -ENODEV;
732 return 0;
733}
734
735static int acpi_ec_remove_fs(struct acpi_device *device)
736{
737
738 if (acpi_device_dir(device)) {
739 remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device));
740 remove_proc_entry(acpi_device_bid(device), acpi_ec_dir);
741 acpi_device_dir(device) = NULL;
742 }
743
744 return 0;
745}
746
747/* --------------------------------------------------------------------------
748 Driver Interface 672 Driver Interface
749 -------------------------------------------------------------------------- */ 673 -------------------------------------------------------------------------- */
750static acpi_status 674static acpi_status
@@ -894,7 +818,12 @@ static int acpi_ec_add(struct acpi_device *device)
894 if (!first_ec) 818 if (!first_ec)
895 first_ec = ec; 819 first_ec = ec;
896 device->driver_data = ec; 820 device->driver_data = ec;
897 acpi_ec_add_fs(device); 821
822 WARN(!request_region(ec->data_addr, 1, "EC data"),
823 "Could not request EC data io port 0x%lx", ec->data_addr);
824 WARN(!request_region(ec->command_addr, 1, "EC cmd"),
825 "Could not request EC cmd io port 0x%lx", ec->command_addr);
826
898 pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", 827 pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
899 ec->gpe, ec->command_addr, ec->data_addr); 828 ec->gpe, ec->command_addr, ec->data_addr);
900 829
@@ -921,7 +850,8 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
921 kfree(handler); 850 kfree(handler);
922 } 851 }
923 mutex_unlock(&ec->lock); 852 mutex_unlock(&ec->lock);
924 acpi_ec_remove_fs(device); 853 release_region(ec->data_addr, 1);
854 release_region(ec->command_addr, 1);
925 device->driver_data = NULL; 855 device->driver_data = NULL;
926 if (ec == first_ec) 856 if (ec == first_ec)
927 first_ec = NULL; 857 first_ec = NULL;
@@ -1120,16 +1050,10 @@ int __init acpi_ec_init(void)
1120{ 1050{
1121 int result = 0; 1051 int result = 0;
1122 1052
1123 acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
1124 if (!acpi_ec_dir)
1125 return -ENODEV;
1126
1127 /* Now register the driver for the EC */ 1053 /* Now register the driver for the EC */
1128 result = acpi_bus_register_driver(&acpi_ec_driver); 1054 result = acpi_bus_register_driver(&acpi_ec_driver);
1129 if (result < 0) { 1055 if (result < 0)
1130 remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
1131 return -ENODEV; 1056 return -ENODEV;
1132 }
1133 1057
1134 return result; 1058 return result;
1135} 1059}
@@ -1140,9 +1064,6 @@ static void __exit acpi_ec_exit(void)
1140{ 1064{
1141 1065
1142 acpi_bus_unregister_driver(&acpi_ec_driver); 1066 acpi_bus_unregister_driver(&acpi_ec_driver);
1143
1144 remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
1145
1146 return; 1067 return;
1147} 1068}
1148#endif /* 0 */ 1069#endif /* 0 */