Subject: [PATCH] [acpi power] Add new school power driver - Create drivers/acpi/driver/power/ - Populate with necessary driver files - Add Kconfig entry, with text to allow disablement - Add compatible proc interface (1 state file) - Add simple (1 file) sysfs interface - Add simple event interface Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/power/Kconfig | 13 +++++++ drivers/acpi/drivers/power/Makefile | 6 +++ drivers/acpi/drivers/power/device.c | 63 +++++++++++++++++++++++++++++++++++ drivers/acpi/drivers/power/driver.c | 60 +++++++++++++++++++++++++++++++++ drivers/acpi/drivers/power/event.c | 29 ++++++++++++++++ drivers/acpi/drivers/power/power.h | 26 ++++++++++++++ drivers/acpi/drivers/power/proc.c | 42 +++++++++++++++++++++++ drivers/acpi/drivers/power/sysfs.c | 22 ++++++++++++ 8 files changed, 261 insertions(+), 0 deletions(-) create mode 100644 drivers/acpi/drivers/power/Kconfig create mode 100644 drivers/acpi/drivers/power/Makefile create mode 100644 drivers/acpi/drivers/power/device.c create mode 100644 drivers/acpi/drivers/power/driver.c create mode 100644 drivers/acpi/drivers/power/event.c create mode 100644 drivers/acpi/drivers/power/power.h create mode 100644 drivers/acpi/drivers/power/proc.c create mode 100644 drivers/acpi/drivers/power/sysfs.c applies-to: 7c4e884f0b5db11e7e9d700441e8e14bda7a88f9 6b1f7a447934be44c973787dd9d71db0f41b877d diff --git a/drivers/acpi/drivers/power/Kconfig b/drivers/acpi/drivers/power/Kconfig new file mode 100644 index 0000000..10c7e04 --- /dev/null +++ b/drivers/acpi/drivers/power/Kconfig @@ -0,0 +1,13 @@ + +config ACPI_POWER + bool "Power Resource Driver" + depends on ACPI_DM + default y + ---help--- + This driver controls the Power Resource objects in the + ACPI namespace. + + You always want to enable this driver, unless you specifically + want to disable this (new) driver to enable the (old) legacy + driver. + diff --git a/drivers/acpi/drivers/power/Makefile b/drivers/acpi/drivers/power/Makefile new file mode 100644 index 0000000..4b4c7c7 --- /dev/null +++ b/drivers/acpi/drivers/power/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_ACPI_POWER) += power.o + +power-y := driver.o device.o event.o + +power-$(CONFIG_ACPI_DM_PROC) += proc.o +power-$(CONFIG_ACPI_DM_SYSFS) += sysfs.o diff --git a/drivers/acpi/drivers/power/device.c b/drivers/acpi/drivers/power/device.c new file mode 100644 index 0000000..f5c3523 --- /dev/null +++ b/drivers/acpi/drivers/power/device.c @@ -0,0 +1,63 @@ +/** + * drivers/acpi/drivers/power/device.c - Low-level device access + * + * Copyright (C) 2005 Patrick Mochel + * + * Based on drivers/acpi/power.c, which was: + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * + * This file is released under the GPLv2. + */ + +#include "power.h" + + +static int get_int(struct acpi_power * ap, char * obj, unsigned long * val) +{ + acpi_status status; + + status = acpi_evaluate_integer(ap->p_ad->acpi_device->handle, + obj, NULL, val); + return ACPI_SUCCESS(status) ? 0 : -ENODEV; +} + + +int power_get_state(struct acpi_power * ap) +{ + unsigned long sta; + int ret; + + ret = get_int(ap, "_STA", &sta); + + if (sta & 0x01) + ap->p_state = ACPI_POWER_RESOURCE_STATE_ON; + else + ap->p_state = ACPI_POWER_RESOURCE_STATE_OFF; + + dbg("Resource [%s] is %s\n", ap->p_name, ap->p_state ? "on" : "off"); + + return 0; +} + +int power_init(struct acpi_power * ap) +{ + union acpi_object obj; + struct acpi_buffer buffer = { + .length = sizeof(union acpi_object), + .pointer = &obj, + }; + acpi_status status; + + status = acpi_evaluate_object(ap->p_ad->acpi_device->handle, NULL, + NULL, &buffer); + if (ACPI_SUCCESS(status)) { + ap->p_system_level = obj.power_resource.system_level; + ap->p_order = obj.power_resource.system_level; + } else + return -ENODEV; + + return power_get_state(ap); +} + diff --git a/drivers/acpi/drivers/power/driver.c b/drivers/acpi/drivers/power/driver.c new file mode 100644 index 0000000..88a5a54 --- /dev/null +++ b/drivers/acpi/drivers/power/driver.c @@ -0,0 +1,60 @@ +/*** + * drivers/acpi/drivers/fan.c - New-style ACPI driver fan + * + * Copyright (C) 2006 Patrick Mochel + * + * Based on drivers/acpi/button.c, which was + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * This file is released under the GPLv2. + */ + + +#include "power.h" + +static int power_add(struct acpi_dev * ad) +{ + struct acpi_power * ap; + int ret = 0; + + ap = kzalloc(sizeof(struct acpi_power), GFP_KERNEL); + if (!ap) + return -ENOMEM; + + ap->p_ad = ad; + + ret = power_init(ap); + if (ret) { + kfree(ap); + return ret; + } + + dev_set_drvdata(&ad->dev, ap); + + + printk(KERN_INFO PREFIX "power [%s] (state: %s)\n", + acpi_dev_bid(ad), + ap->p_state == ACPI_POWER_RESOURCE_STATE_ON ? "on" : + ap->p_state == ACPI_POWER_RESOURCE_STATE_OFF ? "off" : "unknown"); + + return ret; +} + +static int power_remove(struct acpi_dev * ad) +{ + struct acpi_power * ap = dev_get_drvdata(&ad->dev); + + dev_set_drvdata(&ad->dev, NULL); + kfree(ap); + return 0; +} + +acpi_no_start(power); +acpi_no_stop(power); +acpi_no_shutdown(power); +acpi_no_suspend(power); +acpi_no_resume(power); + +declare_acpi_driver(power); diff --git a/drivers/acpi/drivers/power/event.c b/drivers/acpi/drivers/power/event.c new file mode 100644 index 0000000..9ec64e8 --- /dev/null +++ b/drivers/acpi/drivers/power/event.c @@ -0,0 +1,29 @@ +/** + * drivers/acpi/drivers/power/event.c - Power device event interface + * + * Copyright (C) 2005 Patrick Mochel + * + * Based on drivers/acpi/power.c, which was: + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * + * This file is released under the GPLv2. + */ + +#include "power.h" + +#define ACPI_POWER_NOTIFY_STATUS 0x80 + +static int power_notify(struct acpi_dev * ad, u32 event, int * data) +{ + struct acpi_power * ap = dev_get_drvdata(&ad->dev); + + power_get_state(ap); + *data = ap->p_state; + return 0; +} + +declare_acpi_events(power, acpi_event_raise(ACPI_POWER_NOTIFY_STATUS)); + +acpi_device_event(power); diff --git a/drivers/acpi/drivers/power/power.h b/drivers/acpi/drivers/power/power.h new file mode 100644 index 0000000..b507a93 --- /dev/null +++ b/drivers/acpi/drivers/power/power.h @@ -0,0 +1,26 @@ +#include + +#ifdef DEBUG +#define dbg(fmt, ...) printk(KERN_DEBUG PREFIX "power: " fmt "\n", ## __VA_ARGS__) +#else +#define dbg(fmt, ...) +#endif + +#define _COMPONENT ACPI_POWER_COMPONENT +ACPI_MODULE_NAME("acpi_power"); + + +#define ACPI_POWER_RESOURCE_STATE_OFF 0x00 +#define ACPI_POWER_RESOURCE_STATE_ON 0x01 +#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF + +struct acpi_power { + struct acpi_dev * p_ad; + u32 p_state; + u32 p_power_state; + u32 p_system_level; + u32 p_order; +}; + +extern int power_init(struct acpi_power * ap); +extern int power_get_state(struct acpi_power * ap); diff --git a/drivers/acpi/drivers/power/proc.c b/drivers/acpi/drivers/power/proc.c new file mode 100644 index 0000000..b80049b --- /dev/null +++ b/drivers/acpi/drivers/power/proc.c @@ -0,0 +1,42 @@ +/** + * drivers/acpi/drivers/power/proc.c - proc FS interface for power devices + * + * Copyright (C) 2005 Patrick Mochel + * + * Based on drivers/acpi/power.c, which was: + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * + * This file is released under the GPLv2. + */ + +#include "power.h" + +static int read_state(struct seq_file * seq, void * offset) +{ + struct acpi_dev * ad = seq->private; + struct acpi_power * ap = dev_get_drvdata(&ad->dev); + const char * state; + + if (power_get_state(ap)) { + seq_puts(seq, "ERROR: Unable to read POWER Adapter state\n"); + return 0; + } + + state = "unknown"; + + seq_printf(seq, "state: %s\n", state); + return 0; +} + +static int open_state(struct inode * inode, struct file * file) +{ + return single_open(file, read_state, PDE(inode)->data); +} + +static struct acpi_proc_file power_files[] = { + proc_file_ro(state), +}; + +acpi_driver_proc(power); diff --git a/drivers/acpi/drivers/power/sysfs.c b/drivers/acpi/drivers/power/sysfs.c new file mode 100644 index 0000000..0d1892e --- /dev/null +++ b/drivers/acpi/drivers/power/sysfs.c @@ -0,0 +1,22 @@ +/** + * drivers/acpi/drivers/power/sysfs.c - sysfs interface for power devices + * + * Copyright (C) 2006 Patrick Mochel + * + * This file is released under the GPLv2. + */ + +#include "power.h" + + +static ssize_t state_show(struct acpi_dev * ad, char * buf) +{ + struct acpi_power * ap = dev_get_drvdata(&ad->dev); + return sprintf(buf, "%02x", ap->p_state); +} + +static struct acpi_dev_attr power_attrs[] = { + acpi_dev_attr_ro(state), +}; + +acpi_driver_sysfs(power); --- 0.99.9.GIT