X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Facpi%2Ffan.c;h=f305a826ca2df46c1db4b1bb940c987d885e3672;hb=refs%2Fheads%2Fvserver;hp=9af986206f118736cc32c0735f473e5f1047a277;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 9af986206..f305a826c 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -28,278 +28,275 @@ #include #include #include +#include #include #include #include - #define ACPI_FAN_COMPONENT 0x00200000 #define ACPI_FAN_CLASS "fan" -#define ACPI_FAN_HID "PNP0C0B" #define ACPI_FAN_DRIVER_NAME "ACPI Fan Driver" -#define ACPI_FAN_DEVICE_NAME "Fan" #define ACPI_FAN_FILE_STATE "state" -#define ACPI_FAN_NOTIFY_STATUS 0x80 #define _COMPONENT ACPI_FAN_COMPONENT -ACPI_MODULE_NAME ("acpi_fan") +ACPI_MODULE_NAME("acpi_fan") -MODULE_AUTHOR("Paul Diefenbaugh"); + MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME); MODULE_LICENSE("GPL"); -int acpi_fan_add (struct acpi_device *device); -int acpi_fan_remove (struct acpi_device *device, int type); +static int acpi_fan_add(struct acpi_device *device); +static int acpi_fan_remove(struct acpi_device *device, int type); +static int acpi_fan_suspend(struct acpi_device *device, int state); +static int acpi_fan_resume(struct acpi_device *device, int state); static struct acpi_driver acpi_fan_driver = { - .name = ACPI_FAN_DRIVER_NAME, - .class = ACPI_FAN_CLASS, - .ids = ACPI_FAN_HID, - .ops = { - .add = acpi_fan_add, - .remove = acpi_fan_remove, - }, + .name = ACPI_FAN_DRIVER_NAME, + .class = ACPI_FAN_CLASS, + .ids = "PNP0C0B", + .ops = { + .add = acpi_fan_add, + .remove = acpi_fan_remove, + .suspend = acpi_fan_suspend, + .resume = acpi_fan_resume, + }, }; struct acpi_fan { - acpi_handle handle; + struct acpi_device * device; }; - /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ -struct proc_dir_entry *acpi_fan_dir; - +static struct proc_dir_entry *acpi_fan_dir; -static int -acpi_fan_read_state ( - char *page, - char **start, - off_t off, - int count, - int *eof, - void *data) +static int acpi_fan_read_state(struct seq_file *seq, void *offset) { - struct acpi_fan *fan = (struct acpi_fan *) data; - char *p = page; - int len = 0; - int state = 0; + struct acpi_fan *fan = seq->private; + int state = 0; - ACPI_FUNCTION_TRACE("acpi_fan_read_state"); - if (!fan || (off != 0)) - goto end; - - if (acpi_bus_get_power(fan->handle, &state)) - goto end; - - p += sprintf(p, "status: %s\n", - !state?"on":"off"); - -end: - len = (p - page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - - return_VALUE(len); + if (fan) { + if (acpi_bus_get_power(fan->device->handle, &state)) + seq_printf(seq, "status: ERROR\n"); + else + seq_printf(seq, "status: %s\n", + !state ? "on" : "off"); + } + return 0; } +static int acpi_fan_state_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_fan_read_state, PDE(inode)->data); +} -static int -acpi_fan_write_state ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) +static ssize_t +acpi_fan_write_state(struct file *file, const char __user * buffer, + size_t count, loff_t * ppos) { - int result = 0; - struct acpi_fan *fan = (struct acpi_fan *) data; - char state_string[12] = {'\0'}; + int result = 0; + struct seq_file *m = file->private_data; + struct acpi_fan *fan = m->private; + char state_string[12] = { '\0' }; - ACPI_FUNCTION_TRACE("acpi_fan_write_state"); if (!fan || (count > sizeof(state_string) - 1)) - return_VALUE(-EINVAL); - + return -EINVAL; + if (copy_from_user(state_string, buffer, count)) - return_VALUE(-EFAULT); - + return -EFAULT; + state_string[count] = '\0'; - - result = acpi_bus_set_power(fan->handle, - simple_strtoul(state_string, NULL, 0)); + + result = acpi_bus_set_power(fan->device->handle, + simple_strtoul(state_string, NULL, 0)); if (result) - return_VALUE(result); + return result; - return_VALUE(count); + return count; } +static const struct file_operations acpi_fan_state_ops = { + .open = acpi_fan_state_open_fs, + .read = seq_read, + .write = acpi_fan_write_state, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; -static int -acpi_fan_add_fs ( - struct acpi_device *device) +static int acpi_fan_add_fs(struct acpi_device *device) { - struct proc_dir_entry *entry = NULL; + struct proc_dir_entry *entry = NULL; - ACPI_FUNCTION_TRACE("acpi_fan_add_fs"); if (!device) - return_VALUE(-EINVAL); + return -EINVAL; if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_fan_dir); + acpi_fan_dir); if (!acpi_device_dir(device)) - return_VALUE(-ENODEV); + return -ENODEV; acpi_device_dir(device)->owner = THIS_MODULE; } /* 'status' [R/W] */ entry = create_proc_entry(ACPI_FAN_FILE_STATE, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + S_IFREG | S_IRUGO | S_IWUSR, + acpi_device_dir(device)); if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_FAN_FILE_STATE)); + return -ENODEV; else { - entry->read_proc = acpi_fan_read_state; - entry->write_proc = acpi_fan_write_state; + entry->proc_fops = &acpi_fan_state_ops; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } - return_VALUE(0); + return 0; } - -static int -acpi_fan_remove_fs ( - struct acpi_device *device) +static int acpi_fan_remove_fs(struct acpi_device *device) { - ACPI_FUNCTION_TRACE("acpi_fan_remove_fs"); if (acpi_device_dir(device)) { + remove_proc_entry(ACPI_FAN_FILE_STATE, acpi_device_dir(device)); remove_proc_entry(acpi_device_bid(device), acpi_fan_dir); acpi_device_dir(device) = NULL; } - return_VALUE(0); + return 0; } - /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ -int -acpi_fan_add ( - struct acpi_device *device) +static int acpi_fan_add(struct acpi_device *device) { - int result = 0; - struct acpi_fan *fan = NULL; - int state = 0; + int result = 0; + struct acpi_fan *fan = NULL; + int state = 0; - ACPI_FUNCTION_TRACE("acpi_fan_add"); if (!device) - return_VALUE(-EINVAL); + return -EINVAL; - fan = kmalloc(sizeof(struct acpi_fan), GFP_KERNEL); + fan = kzalloc(sizeof(struct acpi_fan), GFP_KERNEL); if (!fan) - return_VALUE(-ENOMEM); - memset(fan, 0, sizeof(struct acpi_fan)); + return -ENOMEM; - fan->handle = device->handle; - strcpy(acpi_device_name(device), ACPI_FAN_DEVICE_NAME); + fan->device = device; + strcpy(acpi_device_name(device), "Fan"); strcpy(acpi_device_class(device), ACPI_FAN_CLASS); acpi_driver_data(device) = fan; - result = acpi_bus_get_power(fan->handle, &state); + result = acpi_bus_get_power(device->handle, &state); if (result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error reading power state\n")); + printk(KERN_ERR PREFIX "Reading power state\n"); goto end; } + device->flags.force_power_state = 1; + acpi_bus_set_power(device->handle, state); + device->flags.force_power_state = 0; + result = acpi_fan_add_fs(device); if (result) goto end; printk(KERN_INFO PREFIX "%s [%s] (%s)\n", - acpi_device_name(device), acpi_device_bid(device), - !device->power.state?"on":"off"); + acpi_device_name(device), acpi_device_bid(device), + !device->power.state ? "on" : "off"); -end: + end: if (result) kfree(fan); - return_VALUE(result); + return result; } - -int -acpi_fan_remove ( - struct acpi_device *device, - int type) +static int acpi_fan_remove(struct acpi_device *device, int type) { - struct acpi_fan *fan = NULL; + struct acpi_fan *fan = NULL; - ACPI_FUNCTION_TRACE("acpi_fan_remove"); if (!device || !acpi_driver_data(device)) - return_VALUE(-EINVAL); + return -EINVAL; - fan = (struct acpi_fan *) acpi_driver_data(device); + fan = acpi_driver_data(device); acpi_fan_remove_fs(device); kfree(fan); - return_VALUE(0); + return 0; +} + +static int acpi_fan_suspend(struct acpi_device *device, int state) +{ + if (!device) + return -EINVAL; + + acpi_bus_set_power(device->handle, ACPI_STATE_D0); + + return AE_OK; } +static int acpi_fan_resume(struct acpi_device *device, int state) +{ + int result = 0; + int power_state = 0; + + if (!device) + return -EINVAL; + + result = acpi_bus_get_power(device->handle, &power_state); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error reading fan power state\n")); + return result; + } + + device->flags.force_power_state = 1; + acpi_bus_set_power(device->handle, power_state); + device->flags.force_power_state = 0; -int __init -acpi_fan_init (void) + return result; +} + +static int __init acpi_fan_init(void) { - int result = 0; + int result = 0; - ACPI_FUNCTION_TRACE("acpi_fan_init"); acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); if (!acpi_fan_dir) - return_VALUE(-ENODEV); + return -ENODEV; acpi_fan_dir->owner = THIS_MODULE; result = acpi_bus_register_driver(&acpi_fan_driver); if (result < 0) { remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); - return_VALUE(-ENODEV); + return -ENODEV; } - return_VALUE(0); + return 0; } - -void __exit -acpi_fan_exit (void) +static void __exit acpi_fan_exit(void) { - ACPI_FUNCTION_TRACE("acpi_fan_exit"); acpi_bus_unregister_driver(&acpi_fan_driver); remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); - return_VOID; + return; } - module_init(acpi_fan_init); module_exit(acpi_fan_exit); -