Skip to content

Commit

Permalink
ACPI: Provide /sys/kernel/debug/ec/...
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
watologo1 authored and Matthew Garrett committed Aug 3, 2010
1 parent cd89e08 commit 1195a09
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 13 deletions.
13 changes: 13 additions & 0 deletions drivers/acpi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions drivers/acpi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 5 additions & 13 deletions drivers/acpi/ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down
57 changes: 57 additions & 0 deletions drivers/acpi/ec_sys.c
Original file line number Diff line number Diff line change
@@ -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);
24 changes: 24 additions & 0 deletions drivers/acpi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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_ */

0 comments on commit 1195a09

Please sign in to comment.