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:
Thomas Renninger 2010-07-16 13:11:31 +02:00 committed by Matthew Garrett
parent cd89e08fa0
commit 1195a09816
5 changed files with 100 additions and 13 deletions

View file

@ -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

View file

@ -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

View file

@ -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
View 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);

View file

@ -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_ */