diff options
| author | Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | 2005-08-03 17:55:21 -0400 | 
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2005-08-03 17:57:24 -0400 | 
| commit | b34a8030eeab4d59dcdd86de38f6927b9edd441f (patch) | |
| tree | b0bdf2532175ea0209b2782b9a077d25a6f33aec /drivers/acpi/button.c | |
| parent | 7b15f5e7bb180ac7bfb8926dbbd8835fecc07fad (diff) | |
[ACPI] restore /proc/acpi/button/ (ala 2.6.12)
Signed-off-by Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/button.c')
| -rw-r--r-- | drivers/acpi/button.c | 206 | 
1 files changed, 205 insertions, 1 deletions
| diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 0f45d45f05a0..8162fd0c21a7 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -26,6 +26,9 @@  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/init.h> +#include <linux/types.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h>  #include <acpi/acpi_bus.h>  #include <acpi/acpi_drivers.h> @@ -33,6 +36,9 @@  #define ACPI_BUTTON_COMPONENT		0x00080000  #define ACPI_BUTTON_DRIVER_NAME		"ACPI Button Driver"  #define ACPI_BUTTON_CLASS		"button" +#define ACPI_BUTTON_FILE_INFO		"info" +#define ACPI_BUTTON_FILE_STATE		"state" +#define ACPI_BUTTON_TYPE_UNKNOWN	0x00  #define ACPI_BUTTON_NOTIFY_STATUS	0x80  #define ACPI_BUTTON_SUBCLASS_POWER	"power" @@ -64,6 +70,8 @@ MODULE_LICENSE("GPL");  static int acpi_button_add (struct acpi_device *device);  static int acpi_button_remove (struct acpi_device *device, int type); +static int acpi_button_info_open_fs(struct inode *inode, struct file *file); +static int acpi_button_state_open_fs(struct inode *inode, struct file *file);  static struct acpi_driver acpi_button_driver = {  	.name =		ACPI_BUTTON_DRIVER_NAME, @@ -82,6 +90,179 @@ struct acpi_button {  	unsigned long		pushed;  }; +static struct file_operations acpi_button_info_fops = { +	.open		= acpi_button_info_open_fs, +	.read		= seq_read, +	.llseek		= seq_lseek, +	.release	= single_release, +}; + +static struct file_operations acpi_button_state_fops = { +	.open		= acpi_button_state_open_fs, +	.read		= seq_read, +	.llseek		= seq_lseek, +	.release	= single_release, +}; +/* -------------------------------------------------------------------------- +                              FS Interface (/proc) +   -------------------------------------------------------------------------- */ + +static struct proc_dir_entry	*acpi_button_dir; + +static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) +{ +	struct acpi_button	*button = (struct acpi_button *) seq->private; + +	ACPI_FUNCTION_TRACE("acpi_button_info_seq_show"); + +	if (!button || !button->device) +		return_VALUE(0); + +	seq_printf(seq, "type:                    %s\n",  +		acpi_device_name(button->device)); + +	return_VALUE(0); +} + +static int acpi_button_info_open_fs(struct inode *inode, struct file *file) +{ +	return single_open(file, acpi_button_info_seq_show, PDE(inode)->data); +} +	 +static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) +{ +	struct acpi_button	*button = (struct acpi_button *) seq->private; +	acpi_status		status; +	unsigned long		state; + +	ACPI_FUNCTION_TRACE("acpi_button_state_seq_show"); + +	if (!button || !button->device) +		return_VALUE(0); + +	status = acpi_evaluate_integer(button->handle,"_LID",NULL,&state); +	if (ACPI_FAILURE(status)) { +		seq_printf(seq, "state:      unsupported\n"); +	} +	else{ +		seq_printf(seq, "state:      %s\n", (state ? "open" : "closed"));  +	} + +	return_VALUE(0); +} + +static int acpi_button_state_open_fs(struct inode *inode, struct file *file) +{ +	return single_open(file, acpi_button_state_seq_show, PDE(inode)->data); +} + +static struct proc_dir_entry *acpi_power_dir; +static struct proc_dir_entry *acpi_sleep_dir; +static struct proc_dir_entry *acpi_lid_dir; + +static int +acpi_button_add_fs ( +	struct acpi_device	*device) +{ +	struct proc_dir_entry	*entry = NULL; +	struct acpi_button	*button = NULL; + +	ACPI_FUNCTION_TRACE("acpi_button_add_fs"); + +	if (!device || !acpi_driver_data(device)) +		return_VALUE(-EINVAL); + +	button = acpi_driver_data(device); + +	switch (button->type) { +	case ACPI_BUTTON_TYPE_POWER: +	case ACPI_BUTTON_TYPE_POWERF: +		if (!acpi_power_dir) +			acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,  +				acpi_button_dir); +		entry = acpi_power_dir; +		break; +	case ACPI_BUTTON_TYPE_SLEEP: +	case ACPI_BUTTON_TYPE_SLEEPF: +		if (!acpi_sleep_dir) +			acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,  +				acpi_button_dir); +		entry = acpi_sleep_dir; +		break; +	case ACPI_BUTTON_TYPE_LID: +		if (!acpi_lid_dir) +			acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID,  +				acpi_button_dir); +		entry = acpi_lid_dir; +		break; +	} + +	if (!entry) +		return_VALUE(-ENODEV); +	entry->owner = THIS_MODULE; + +	acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); +	if (!acpi_device_dir(device)) +		return_VALUE(-ENODEV); +	acpi_device_dir(device)->owner = THIS_MODULE; + +	/* 'info' [R] */ +	entry = create_proc_entry(ACPI_BUTTON_FILE_INFO, +		S_IRUGO, acpi_device_dir(device)); +	if (!entry) +		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, +			"Unable to create '%s' fs entry\n", +			ACPI_BUTTON_FILE_INFO)); +	else { +		entry->proc_fops = &acpi_button_info_fops; +		entry->data = acpi_driver_data(device); +		entry->owner = THIS_MODULE; +	} + +	/* show lid state [R] */ +	if (button->type == ACPI_BUTTON_TYPE_LID) { +		entry = create_proc_entry(ACPI_BUTTON_FILE_STATE, +			S_IRUGO, acpi_device_dir(device)); +		if (!entry) +			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, +				"Unable to create '%s' fs entry\n", +				ACPI_BUTTON_FILE_INFO)); +		else { +			entry->proc_fops = &acpi_button_state_fops; +			entry->data = acpi_driver_data(device); +			entry->owner = THIS_MODULE; +		} +	} + +	return_VALUE(0); +} + + +static int +acpi_button_remove_fs ( +	struct acpi_device	*device) +{ +	struct acpi_button	*button = NULL; + +	ACPI_FUNCTION_TRACE("acpi_button_remove_fs"); + +	button = acpi_driver_data(device); +	if (acpi_device_dir(device)) { +		if (button->type == ACPI_BUTTON_TYPE_LID) +			remove_proc_entry(ACPI_BUTTON_FILE_STATE, +					     acpi_device_dir(device)); +		remove_proc_entry(ACPI_BUTTON_FILE_INFO, +				     acpi_device_dir(device)); + +		remove_proc_entry(acpi_device_bid(device), +				     acpi_device_dir(device)->parent); +		acpi_device_dir(device) = NULL; +	} + +	return_VALUE(0); +} + +  /* --------------------------------------------------------------------------                                  Driver Interface     -------------------------------------------------------------------------- */ @@ -121,7 +302,8 @@ acpi_button_notify_fixed (  	ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); -	BUG_ON(!button); +	if (!button) +		return_ACPI_STATUS(AE_BAD_PARAMETER);  	acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); @@ -197,6 +379,10 @@ acpi_button_add (  		goto end;  	} +	result = acpi_button_add_fs(device); +	if (result) +		goto end; +  	switch (button->type) {  	case ACPI_BUTTON_TYPE_POWERF:  		status = acpi_install_fixed_event_handler ( @@ -240,6 +426,7 @@ acpi_button_add (  end:  	if (result) { +		acpi_button_remove_fs(device);  		kfree(button);  	} @@ -280,6 +467,8 @@ acpi_button_remove (struct acpi_device *device, int type)  		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,  			"Error removing notify handler\n")); +	acpi_button_remove_fs(device);	 +  	kfree(button);  	return_VALUE(0); @@ -293,14 +482,20 @@ acpi_button_init (void)  	ACPI_FUNCTION_TRACE("acpi_button_init"); +	acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); +	if (!acpi_button_dir) +		return_VALUE(-ENODEV); +	acpi_button_dir->owner = THIS_MODULE;  	result = acpi_bus_register_driver(&acpi_button_driver);  	if (result < 0) { +		remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);  		return_VALUE(-ENODEV);  	}  	return_VALUE(0);  } +  static void __exit  acpi_button_exit (void)  { @@ -308,8 +503,17 @@ acpi_button_exit (void)  	acpi_bus_unregister_driver(&acpi_button_driver); +	if (acpi_power_dir)  +		remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir); +	if (acpi_sleep_dir) +		remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir); +	if (acpi_lid_dir) +		remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); +	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); +  	return_VOID;  } +  module_init(acpi_button_init);  module_exit(acpi_button_exit); | 
