Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1195a098 authored by Thomas Renninger's avatar Thomas Renninger Committed by Matthew Garrett
Browse files

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: default avatarThomas 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: default avatarMatthew Garrett <mjg@redhat.com>
parent cd89e08f
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+5 −13
Original line number Diff line number Diff line
@@ -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 */

drivers/acpi/ec_sys.c

0 → 100644
+57 −0
Original line number Diff line number Diff line
#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 −0
Original line number Diff line number Diff line
@@ -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_ */