diff options
| -rw-r--r-- | drivers/acpi/video.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 350d52a8f781..bfe1fa2fb5d1 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -204,6 +204,8 @@ struct acpi_video_device { | |||
| 204 | struct acpi_video_device_flags flags; | 204 | struct acpi_video_device_flags flags; |
| 205 | struct acpi_video_device_cap cap; | 205 | struct acpi_video_device_cap cap; |
| 206 | struct list_head entry; | 206 | struct list_head entry; |
| 207 | struct delayed_work switch_brightness_work; | ||
| 208 | int switch_brightness_event; | ||
| 207 | struct acpi_video_bus *video; | 209 | struct acpi_video_bus *video; |
| 208 | struct acpi_device *dev; | 210 | struct acpi_device *dev; |
| 209 | struct acpi_video_device_brightness *brightness; | 211 | struct acpi_video_device_brightness *brightness; |
| @@ -230,8 +232,7 @@ static int acpi_video_device_lcd_get_level_current( | |||
| 230 | unsigned long long *level, bool raw); | 232 | unsigned long long *level, bool raw); |
| 231 | static int acpi_video_get_next_level(struct acpi_video_device *device, | 233 | static int acpi_video_get_next_level(struct acpi_video_device *device, |
| 232 | u32 level_current, u32 event); | 234 | u32 level_current, u32 event); |
| 233 | static int acpi_video_switch_brightness(struct acpi_video_device *device, | 235 | static void acpi_video_switch_brightness(struct work_struct *work); |
| 234 | int event); | ||
| 235 | 236 | ||
| 236 | static bool acpi_video_use_native_backlight(void) | 237 | static bool acpi_video_use_native_backlight(void) |
| 237 | { | 238 | { |
| @@ -275,6 +276,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd) | |||
| 275 | int request_level = bd->props.brightness + 2; | 276 | int request_level = bd->props.brightness + 2; |
| 276 | struct acpi_video_device *vd = bl_get_data(bd); | 277 | struct acpi_video_device *vd = bl_get_data(bd); |
| 277 | 278 | ||
| 279 | cancel_delayed_work(&vd->switch_brightness_work); | ||
| 278 | return acpi_video_device_lcd_set_level(vd, | 280 | return acpi_video_device_lcd_set_level(vd, |
| 279 | vd->brightness->levels[request_level]); | 281 | vd->brightness->levels[request_level]); |
| 280 | } | 282 | } |
| @@ -1188,6 +1190,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
| 1188 | data->device_id = device_id; | 1190 | data->device_id = device_id; |
| 1189 | data->video = video; | 1191 | data->video = video; |
| 1190 | data->dev = device; | 1192 | data->dev = device; |
| 1193 | INIT_DELAYED_WORK(&data->switch_brightness_work, | ||
| 1194 | acpi_video_switch_brightness); | ||
| 1191 | 1195 | ||
| 1192 | attribute = acpi_video_get_device_attr(video, device_id); | 1196 | attribute = acpi_video_get_device_attr(video, device_id); |
| 1193 | 1197 | ||
| @@ -1410,15 +1414,18 @@ acpi_video_get_next_level(struct acpi_video_device *device, | |||
| 1410 | } | 1414 | } |
| 1411 | } | 1415 | } |
| 1412 | 1416 | ||
| 1413 | static int | 1417 | static void |
| 1414 | acpi_video_switch_brightness(struct acpi_video_device *device, int event) | 1418 | acpi_video_switch_brightness(struct work_struct *work) |
| 1415 | { | 1419 | { |
| 1420 | struct acpi_video_device *device = container_of(to_delayed_work(work), | ||
| 1421 | struct acpi_video_device, switch_brightness_work); | ||
| 1416 | unsigned long long level_current, level_next; | 1422 | unsigned long long level_current, level_next; |
| 1423 | int event = device->switch_brightness_event; | ||
| 1417 | int result = -EINVAL; | 1424 | int result = -EINVAL; |
| 1418 | 1425 | ||
| 1419 | /* no warning message if acpi_backlight=vendor or a quirk is used */ | 1426 | /* no warning message if acpi_backlight=vendor or a quirk is used */ |
| 1420 | if (!acpi_video_verify_backlight_support()) | 1427 | if (!acpi_video_verify_backlight_support()) |
| 1421 | return 0; | 1428 | return; |
| 1422 | 1429 | ||
| 1423 | if (!device->brightness) | 1430 | if (!device->brightness) |
| 1424 | goto out; | 1431 | goto out; |
| @@ -1440,8 +1447,6 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) | |||
| 1440 | out: | 1447 | out: |
| 1441 | if (result) | 1448 | if (result) |
| 1442 | printk(KERN_ERR PREFIX "Failed to switch the brightness\n"); | 1449 | printk(KERN_ERR PREFIX "Failed to switch the brightness\n"); |
| 1443 | |||
| 1444 | return result; | ||
| 1445 | } | 1450 | } |
| 1446 | 1451 | ||
| 1447 | int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, | 1452 | int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, |
| @@ -1609,6 +1614,16 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | |||
| 1609 | return; | 1614 | return; |
| 1610 | } | 1615 | } |
| 1611 | 1616 | ||
| 1617 | static void brightness_switch_event(struct acpi_video_device *video_device, | ||
| 1618 | u32 event) | ||
| 1619 | { | ||
| 1620 | if (!brightness_switch_enabled) | ||
| 1621 | return; | ||
| 1622 | |||
| 1623 | video_device->switch_brightness_event = event; | ||
| 1624 | schedule_delayed_work(&video_device->switch_brightness_work, HZ / 10); | ||
| 1625 | } | ||
| 1626 | |||
| 1612 | static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | 1627 | static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) |
| 1613 | { | 1628 | { |
| 1614 | struct acpi_video_device *video_device = data; | 1629 | struct acpi_video_device *video_device = data; |
| @@ -1626,28 +1641,23 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
| 1626 | 1641 | ||
| 1627 | switch (event) { | 1642 | switch (event) { |
| 1628 | case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ | 1643 | case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ |
| 1629 | if (brightness_switch_enabled) | 1644 | brightness_switch_event(video_device, event); |
| 1630 | acpi_video_switch_brightness(video_device, event); | ||
| 1631 | keycode = KEY_BRIGHTNESS_CYCLE; | 1645 | keycode = KEY_BRIGHTNESS_CYCLE; |
| 1632 | break; | 1646 | break; |
| 1633 | case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ | 1647 | case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ |
| 1634 | if (brightness_switch_enabled) | 1648 | brightness_switch_event(video_device, event); |
| 1635 | acpi_video_switch_brightness(video_device, event); | ||
| 1636 | keycode = KEY_BRIGHTNESSUP; | 1649 | keycode = KEY_BRIGHTNESSUP; |
| 1637 | break; | 1650 | break; |
| 1638 | case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ | 1651 | case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ |
| 1639 | if (brightness_switch_enabled) | 1652 | brightness_switch_event(video_device, event); |
| 1640 | acpi_video_switch_brightness(video_device, event); | ||
| 1641 | keycode = KEY_BRIGHTNESSDOWN; | 1653 | keycode = KEY_BRIGHTNESSDOWN; |
| 1642 | break; | 1654 | break; |
| 1643 | case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ | 1655 | case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ |
| 1644 | if (brightness_switch_enabled) | 1656 | brightness_switch_event(video_device, event); |
| 1645 | acpi_video_switch_brightness(video_device, event); | ||
| 1646 | keycode = KEY_BRIGHTNESS_ZERO; | 1657 | keycode = KEY_BRIGHTNESS_ZERO; |
| 1647 | break; | 1658 | break; |
| 1648 | case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ | 1659 | case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ |
| 1649 | if (brightness_switch_enabled) | 1660 | brightness_switch_event(video_device, event); |
| 1650 | acpi_video_switch_brightness(video_device, event); | ||
| 1651 | keycode = KEY_DISPLAY_OFF; | 1661 | keycode = KEY_DISPLAY_OFF; |
| 1652 | break; | 1662 | break; |
| 1653 | default: | 1663 | default: |
