forked from mirrors/linux
		
	ACPI: Provide /sys/kernel/debug/ec/...
This patch provides the same information through debugfs, which previously was provided through /proc/acpi/embedded_controller/*/info This is the gpe the EC is connected to and whether the global lock gets used. The io ports used are added to /proc/ioports in another patch. Beside the fact that /proc/acpi is deprecated for quite some time, this info is not needed for applications and thus can be moved to debugfs instead of a public interface like /sys. Signed-off-by: Thomas Renninger <trenn@suse.de> CC: Alexey Starikovskiy <astarikovskiy@suse.de> CC: Len Brown <lenb@kernel.org> CC: linux-kernel@vger.kernel.org CC: linux-acpi@vger.kernel.org CC: Bjorn Helgaas <bjorn.helgaas@hp.com> CC: platform-driver-x86@vger.kernel.org Signed-off-by: Matthew Garrett <mjg@redhat.com>
This commit is contained in:
		
							parent
							
								
									cd89e08fa0
								
							
						
					
					
						commit
						1195a09816
					
				
					 5 changed files with 100 additions and 13 deletions
				
			
		|  | @ -104,6 +104,19 @@ config ACPI_SYSFS_POWER | |||
| 	help | ||||
| 	  Say N to disable power /sys interface | ||||
| 
 | ||||
| config ACPI_EC_DEBUGFS | ||||
| 	tristate "EC read/write access through /sys/kernel/debug/ec" | ||||
| 	default y | ||||
| 	help | ||||
| 	  Say N to disable Embedded Controller /sys/kernel/debug interface | ||||
| 
 | ||||
| 	  An Embedded Controller typically is available on laptops and reads | ||||
| 	  sensor values like battery state and temperature. | ||||
| 	  The kernel access the EC through ACPI parsed code provided by BIOS | ||||
| 	  tables. | ||||
| 	  Thus this option is a debug option that helps to write ACPI drivers | ||||
| 	  and can be used to identify ACPI code or EC firmware bugs. | ||||
| 
 | ||||
| config ACPI_PROC_EVENT | ||||
| 	bool "Deprecated /proc/acpi/event support" | ||||
| 	depends on PROC_FS | ||||
|  |  | |||
|  | @ -60,6 +60,7 @@ obj-$(CONFIG_ACPI_SBS)		+= sbshc.o | |||
| obj-$(CONFIG_ACPI_SBS)		+= sbs.o | ||||
| obj-$(CONFIG_ACPI_POWER_METER)	+= power_meter.o | ||||
| obj-$(CONFIG_ACPI_HED)		+= hed.o | ||||
| obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o | ||||
| 
 | ||||
| # processor has its own "processor." module_param namespace
 | ||||
| processor-y			:= processor_driver.o processor_throttling.o | ||||
|  |  | |||
|  | @ -43,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 */ | ||||
|  | @ -104,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 */ | ||||
|  |  | |||
							
								
								
									
										57
									
								
								drivers/acpi/ec_sys.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								drivers/acpi/ec_sys.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,57 @@ | |||
| #include <linux/kernel.h> | ||||
| #include <linux/acpi.h> | ||||
| #include <linux/debugfs.h> | ||||
| #include "internal.h" | ||||
| 
 | ||||
| MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>"); | ||||
| MODULE_DESCRIPTION("ACPI EC sysfs access driver"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| 
 | ||||
| struct sysdev_class acpi_ec_sysdev_class = { | ||||
| 	.name = "ec", | ||||
| }; | ||||
| 
 | ||||
| static struct dentry *acpi_ec_debugfs_dir; | ||||
| 
 | ||||
| int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) | ||||
| { | ||||
| 	struct dentry *dev_dir; | ||||
| 	char name[64]; | ||||
| 	if (ec_device_count == 0) { | ||||
| 		acpi_ec_debugfs_dir = debugfs_create_dir("ec", NULL); | ||||
| 		if (!acpi_ec_debugfs_dir) | ||||
| 			return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
| 	sprintf(name, "ec%u", ec_device_count); | ||||
| 	dev_dir = debugfs_create_dir(name, acpi_ec_debugfs_dir); | ||||
| 	if (!dev_dir) { | ||||
| 		if (ec_device_count == 0) | ||||
| 			debugfs_remove_recursive(acpi_ec_debugfs_dir); | ||||
| 		/* TBD: Proper cleanup for multiple ECs */ | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
| 	debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe); | ||||
| 	debugfs_create_bool("use_global_lock", 0444, dev_dir, | ||||
| 			    (u32 *)&first_ec->global_lock); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int __init acpi_ec_sys_init(void) | ||||
| { | ||||
| 	int err = 0; | ||||
| 	if (first_ec) | ||||
| 		err = acpi_ec_add_debugfs(first_ec, 0); | ||||
| 	else | ||||
| 		err = -ENODEV; | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static void __exit acpi_ec_sys_exit(void) | ||||
| { | ||||
| 	debugfs_remove_recursive(acpi_ec_debugfs_dir); | ||||
| } | ||||
| 
 | ||||
| module_init(acpi_ec_sys_init); | ||||
| module_exit(acpi_ec_sys_exit); | ||||
|  | @ -18,6 +18,11 @@ | |||
|  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ACPI_INTERNAL_H_ | ||||
| #define _ACPI_INTERNAL_H_ | ||||
| 
 | ||||
| #include <linux/sysdev.h> | ||||
| 
 | ||||
| #define PREFIX "ACPI: " | ||||
| 
 | ||||
| int init_acpi_device_notify(void); | ||||
|  | @ -46,6 +51,23 @@ void acpi_early_processor_set_pdc(void); | |||
| /* --------------------------------------------------------------------------
 | ||||
|                                   Embedded Controller | ||||
|    -------------------------------------------------------------------------- */ | ||||
| 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; | ||||
| 	struct sys_device sysdev; | ||||
| }; | ||||
| 
 | ||||
| extern struct acpi_ec *first_ec; | ||||
| 
 | ||||
| int acpi_ec_init(void); | ||||
| int acpi_ec_ecdt_probe(void); | ||||
| int acpi_boot_ec_enable(void); | ||||
|  | @ -63,3 +85,5 @@ int acpi_sleep_proc_init(void); | |||
| #else | ||||
| static inline int acpi_sleep_proc_init(void) { return 0; } | ||||
| #endif | ||||
| 
 | ||||
| #endif /* _ACPI_INTERNAL_H_ */ | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Thomas Renninger
						Thomas Renninger