X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Facpi%2Ffan.c;h=6cf10cbc1eee41687e462d14168827d6830b4cb0;hb=08acd4f8af42affd8cbed81cc1b69fa12ddb213f;hp=a6e149d692cbd332aaf947d689815392474cda34;hpb=75659ca0c10992dcb39258518368a0f6f56e935d;p=linux-2.6-omap-h63xx.git diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index a6e149d692c..6cf10cbc1ee 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -30,7 +30,7 @@ #include #include #include - +#include #include #include @@ -68,9 +68,55 @@ static struct acpi_driver acpi_fan_driver = { }, }; +/* thermal cooling device callbacks */ +static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf) +{ + /* ACPI fan device only support two states: ON/OFF */ + return sprintf(buf, "1\n"); +} + +static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf) +{ + struct acpi_device *device = cdev->devdata; + int state; + int result; + + if (!device) + return -EINVAL; + + result = acpi_bus_get_power(device->handle, &state); + if (result) + return result; + + return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" : + (state == ACPI_STATE_D0 ? "1" : "unknown")); +} + +static int +fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) +{ + struct acpi_device *device = cdev->devdata; + int result; + + if (!device || (state != 0 && state != 1)) + return -EINVAL; + + result = acpi_bus_set_power(device->handle, + state ? ACPI_STATE_D0 : ACPI_STATE_D3); + + return result; +} + +static struct thermal_cooling_device_ops fan_cooling_ops = { + .get_max_state = fan_get_max_state, + .get_cur_state = fan_get_cur_state, + .set_cur_state = fan_set_cur_state, +}; + /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROCFS static struct proc_dir_entry *acpi_fan_dir; @@ -146,17 +192,13 @@ static int acpi_fan_add_fs(struct acpi_device *device) } /* 'status' [R/W] */ - entry = create_proc_entry(ACPI_FAN_FILE_STATE, - S_IFREG | S_IRUGO | S_IWUSR, - acpi_device_dir(device)); + entry = proc_create_data(ACPI_FAN_FILE_STATE, + S_IFREG | S_IRUGO | S_IWUSR, + acpi_device_dir(device), + &acpi_fan_state_ops, + device); if (!entry) return -ENODEV; - else { - entry->proc_fops = &acpi_fan_state_ops; - entry->data = device; - entry->owner = THIS_MODULE; - } - return 0; } @@ -171,7 +213,17 @@ static int acpi_fan_remove_fs(struct acpi_device *device) return 0; } +#else +static int acpi_fan_add_fs(struct acpi_device *device) +{ + return 0; +} +static int acpi_fan_remove_fs(struct acpi_device *device) +{ + return 0; +} +#endif /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -179,9 +231,8 @@ static int acpi_fan_remove_fs(struct acpi_device *device) static int acpi_fan_add(struct acpi_device *device) { int result = 0; - struct acpi_fan *fan = NULL; int state = 0; - + struct thermal_cooling_device *cdev; if (!device) return -EINVAL; @@ -199,6 +250,30 @@ static int acpi_fan_add(struct acpi_device *device) acpi_bus_set_power(device->handle, state); device->flags.force_power_state = 0; + cdev = thermal_cooling_device_register("Fan", device, + &fan_cooling_ops); + if (IS_ERR(cdev)) { + result = PTR_ERR(cdev); + goto end; + } + + printk(KERN_INFO PREFIX + "%s is registered as cooling_device%d\n", + device->dev.bus_id, cdev->id); + + acpi_driver_data(device) = cdev; + result = sysfs_create_link(&device->dev.kobj, + &cdev->device.kobj, + "thermal_cooling"); + if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); + + result = sysfs_create_link(&cdev->device.kobj, + &device->dev.kobj, + "device"); + if (result) + printk(KERN_ERR PREFIX "Create sysfs link\n"); + result = acpi_fan_add_fs(device); if (result) goto end; @@ -208,18 +283,20 @@ static int acpi_fan_add(struct acpi_device *device) !device->power.state ? "on" : "off"); end: - if (result) - kfree(fan); - return result; } static int acpi_fan_remove(struct acpi_device *device, int type) { - if (!device || !acpi_driver_data(device)) + struct thermal_cooling_device *cdev = acpi_driver_data(device); + + if (!device || !cdev) return -EINVAL; acpi_fan_remove_fs(device); + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); + sysfs_remove_link(&cdev->device.kobj, "device"); + thermal_cooling_device_unregister(cdev); return 0; } @@ -261,10 +338,12 @@ static int __init acpi_fan_init(void) int result = 0; +#ifdef CONFIG_ACPI_PROCFS acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); if (!acpi_fan_dir) return -ENODEV; acpi_fan_dir->owner = THIS_MODULE; +#endif result = acpi_bus_register_driver(&acpi_fan_driver); if (result < 0) {