diff options
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r-- | drivers/acpi/video.c | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a54ff6bce8fa..82815cff15a9 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
35 | #include <linux/input.h> | 35 | #include <linux/input.h> |
36 | #include <linux/backlight.h> | 36 | #include <linux/backlight.h> |
37 | #include <linux/thermal.h> | ||
37 | #include <linux/video_output.h> | 38 | #include <linux/video_output.h> |
38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
39 | 40 | ||
@@ -179,6 +180,7 @@ struct acpi_video_device { | |||
179 | struct acpi_device *dev; | 180 | struct acpi_device *dev; |
180 | struct acpi_video_device_brightness *brightness; | 181 | struct acpi_video_device_brightness *brightness; |
181 | struct backlight_device *backlight; | 182 | struct backlight_device *backlight; |
183 | struct thermal_cooling_device *cdev; | ||
182 | struct output_device *output_dev; | 184 | struct output_device *output_dev; |
183 | }; | 185 | }; |
184 | 186 | ||
@@ -342,6 +344,54 @@ static struct output_properties acpi_output_properties = { | |||
342 | .set_state = acpi_video_output_set, | 344 | .set_state = acpi_video_output_set, |
343 | .get_status = acpi_video_output_get, | 345 | .get_status = acpi_video_output_get, |
344 | }; | 346 | }; |
347 | |||
348 | |||
349 | /* thermal cooling device callbacks */ | ||
350 | static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf) | ||
351 | { | ||
352 | struct acpi_device *device = cdev->devdata; | ||
353 | struct acpi_video_device *video = acpi_driver_data(device); | ||
354 | |||
355 | return sprintf(buf, "%d\n", video->brightness->count - 3); | ||
356 | } | ||
357 | |||
358 | static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf) | ||
359 | { | ||
360 | struct acpi_device *device = cdev->devdata; | ||
361 | struct acpi_video_device *video = acpi_driver_data(device); | ||
362 | unsigned long level; | ||
363 | int state; | ||
364 | |||
365 | acpi_video_device_lcd_get_level_current(video, &level); | ||
366 | for (state = 2; state < video->brightness->count; state++) | ||
367 | if (level == video->brightness->levels[state]) | ||
368 | return sprintf(buf, "%d\n", | ||
369 | video->brightness->count - state - 1); | ||
370 | |||
371 | return -EINVAL; | ||
372 | } | ||
373 | |||
374 | static int | ||
375 | video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) | ||
376 | { | ||
377 | struct acpi_device *device = cdev->devdata; | ||
378 | struct acpi_video_device *video = acpi_driver_data(device); | ||
379 | int level; | ||
380 | |||
381 | if ( state >= video->brightness->count - 2) | ||
382 | return -EINVAL; | ||
383 | |||
384 | state = video->brightness->count - state; | ||
385 | level = video->brightness->levels[state -1]; | ||
386 | return acpi_video_device_lcd_set_level(video, level); | ||
387 | } | ||
388 | |||
389 | static struct thermal_cooling_device_ops video_cooling_ops = { | ||
390 | .get_max_state = video_get_max_state, | ||
391 | .get_cur_state = video_get_cur_state, | ||
392 | .set_cur_state = video_set_cur_state, | ||
393 | }; | ||
394 | |||
345 | /* -------------------------------------------------------------------------- | 395 | /* -------------------------------------------------------------------------- |
346 | Video Management | 396 | Video Management |
347 | -------------------------------------------------------------------------- */ | 397 | -------------------------------------------------------------------------- */ |
@@ -660,6 +710,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
660 | kfree(obj); | 710 | kfree(obj); |
661 | 711 | ||
662 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ | 712 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ |
713 | int result; | ||
663 | static int count = 0; | 714 | static int count = 0; |
664 | char *name; | 715 | char *name; |
665 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | 716 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); |
@@ -672,8 +723,25 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
672 | device->backlight->props.max_brightness = device->brightness->count-3; | 723 | device->backlight->props.max_brightness = device->brightness->count-3; |
673 | device->backlight->props.brightness = acpi_video_get_brightness(device->backlight); | 724 | device->backlight->props.brightness = acpi_video_get_brightness(device->backlight); |
674 | backlight_update_status(device->backlight); | 725 | backlight_update_status(device->backlight); |
675 | |||
676 | kfree(name); | 726 | kfree(name); |
727 | |||
728 | device->cdev = thermal_cooling_device_register("LCD", | ||
729 | device->dev, &video_cooling_ops); | ||
730 | if (device->cdev) { | ||
731 | printk(KERN_INFO PREFIX | ||
732 | "%s is registered as cooling_device%d\n", | ||
733 | device->dev->dev.bus_id, device->cdev->id); | ||
734 | result = sysfs_create_link(&device->dev->dev.kobj, | ||
735 | &device->cdev->device.kobj, | ||
736 | "thermal_cooling"); | ||
737 | if (result) | ||
738 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
739 | result = sysfs_create_link(&device->cdev->device.kobj, | ||
740 | &device->dev->dev.kobj, | ||
741 | "device"); | ||
742 | if (result) | ||
743 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
744 | } | ||
677 | } | 745 | } |
678 | if (device->cap._DCS && device->cap._DSS){ | 746 | if (device->cap._DCS && device->cap._DSS){ |
679 | static int count = 0; | 747 | static int count = 0; |
@@ -1764,6 +1832,14 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1764 | ACPI_DEVICE_NOTIFY, | 1832 | ACPI_DEVICE_NOTIFY, |
1765 | acpi_video_device_notify); | 1833 | acpi_video_device_notify); |
1766 | backlight_device_unregister(device->backlight); | 1834 | backlight_device_unregister(device->backlight); |
1835 | if (device->cdev) { | ||
1836 | sysfs_remove_link(&device->dev->dev.kobj, | ||
1837 | "thermal_cooling"); | ||
1838 | sysfs_remove_link(&device->cdev->device.kobj, | ||
1839 | "device"); | ||
1840 | thermal_cooling_device_unregister(device->cdev); | ||
1841 | device->cdev = NULL; | ||
1842 | } | ||
1767 | video_output_unregister(device->output_dev); | 1843 | video_output_unregister(device->output_dev); |
1768 | 1844 | ||
1769 | return 0; | 1845 | return 0; |