diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-05-24 07:27:11 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-05-24 07:27:11 -0400 |
commit | 2d8fe6757e1d857d8b266b25c553923695409e01 (patch) | |
tree | e7669608f1f7087cee5aabae94b6ea136ccdfaea /drivers/acpi/video.c | |
parent | 07d1d29ee1e194b932328ad2dc1d40297062ab7f (diff) | |
parent | 9404cd95507de0a61f2a000fbd76748a9cae33b4 (diff) |
Merge back earlier 'acpi-video' material.
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r-- | drivers/acpi/video.c | 155 |
1 files changed, 89 insertions, 66 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index f8bc5a755dda..cd4389262d4f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -68,7 +68,7 @@ MODULE_AUTHOR("Bruno Ducrot"); | |||
68 | MODULE_DESCRIPTION("ACPI Video Driver"); | 68 | MODULE_DESCRIPTION("ACPI Video Driver"); |
69 | MODULE_LICENSE("GPL"); | 69 | MODULE_LICENSE("GPL"); |
70 | 70 | ||
71 | static bool brightness_switch_enabled = 1; | 71 | static bool brightness_switch_enabled; |
72 | module_param(brightness_switch_enabled, bool, 0644); | 72 | module_param(brightness_switch_enabled, bool, 0644); |
73 | 73 | ||
74 | /* | 74 | /* |
@@ -150,6 +150,7 @@ struct acpi_video_enumerated_device { | |||
150 | 150 | ||
151 | struct acpi_video_bus { | 151 | struct acpi_video_bus { |
152 | struct acpi_device *device; | 152 | struct acpi_device *device; |
153 | bool backlight_registered; | ||
153 | u8 dos_setting; | 154 | u8 dos_setting; |
154 | struct acpi_video_enumerated_device *attached_array; | 155 | struct acpi_video_enumerated_device *attached_array; |
155 | u8 attached_count; | 156 | u8 attached_count; |
@@ -1658,88 +1659,89 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context, | |||
1658 | 1659 | ||
1659 | static void acpi_video_dev_register_backlight(struct acpi_video_device *device) | 1660 | static void acpi_video_dev_register_backlight(struct acpi_video_device *device) |
1660 | { | 1661 | { |
1661 | if (acpi_video_verify_backlight_support()) { | 1662 | struct backlight_properties props; |
1662 | struct backlight_properties props; | 1663 | struct pci_dev *pdev; |
1663 | struct pci_dev *pdev; | 1664 | acpi_handle acpi_parent; |
1664 | acpi_handle acpi_parent; | 1665 | struct device *parent = NULL; |
1665 | struct device *parent = NULL; | 1666 | int result; |
1666 | int result; | 1667 | static int count; |
1667 | static int count; | 1668 | char *name; |
1668 | char *name; | ||
1669 | |||
1670 | result = acpi_video_init_brightness(device); | ||
1671 | if (result) | ||
1672 | return; | ||
1673 | name = kasprintf(GFP_KERNEL, "acpi_video%d", count); | ||
1674 | if (!name) | ||
1675 | return; | ||
1676 | count++; | ||
1677 | 1669 | ||
1678 | acpi_get_parent(device->dev->handle, &acpi_parent); | 1670 | result = acpi_video_init_brightness(device); |
1671 | if (result) | ||
1672 | return; | ||
1673 | name = kasprintf(GFP_KERNEL, "acpi_video%d", count); | ||
1674 | if (!name) | ||
1675 | return; | ||
1676 | count++; | ||
1679 | 1677 | ||
1680 | pdev = acpi_get_pci_dev(acpi_parent); | 1678 | acpi_get_parent(device->dev->handle, &acpi_parent); |
1681 | if (pdev) { | ||
1682 | parent = &pdev->dev; | ||
1683 | pci_dev_put(pdev); | ||
1684 | } | ||
1685 | 1679 | ||
1686 | memset(&props, 0, sizeof(struct backlight_properties)); | 1680 | pdev = acpi_get_pci_dev(acpi_parent); |
1687 | props.type = BACKLIGHT_FIRMWARE; | 1681 | if (pdev) { |
1688 | props.max_brightness = device->brightness->count - 3; | 1682 | parent = &pdev->dev; |
1689 | device->backlight = backlight_device_register(name, | 1683 | pci_dev_put(pdev); |
1690 | parent, | 1684 | } |
1691 | device, | ||
1692 | &acpi_backlight_ops, | ||
1693 | &props); | ||
1694 | kfree(name); | ||
1695 | if (IS_ERR(device->backlight)) | ||
1696 | return; | ||
1697 | 1685 | ||
1698 | /* | 1686 | memset(&props, 0, sizeof(struct backlight_properties)); |
1699 | * Save current brightness level in case we have to restore it | 1687 | props.type = BACKLIGHT_FIRMWARE; |
1700 | * before acpi_video_device_lcd_set_level() is called next time. | 1688 | props.max_brightness = device->brightness->count - 3; |
1701 | */ | 1689 | device->backlight = backlight_device_register(name, |
1702 | device->backlight->props.brightness = | 1690 | parent, |
1703 | acpi_video_get_brightness(device->backlight); | 1691 | device, |
1692 | &acpi_backlight_ops, | ||
1693 | &props); | ||
1694 | kfree(name); | ||
1695 | if (IS_ERR(device->backlight)) | ||
1696 | return; | ||
1704 | 1697 | ||
1705 | device->cooling_dev = thermal_cooling_device_register("LCD", | 1698 | /* |
1706 | device->dev, &video_cooling_ops); | 1699 | * Save current brightness level in case we have to restore it |
1707 | if (IS_ERR(device->cooling_dev)) { | 1700 | * before acpi_video_device_lcd_set_level() is called next time. |
1708 | /* | 1701 | */ |
1709 | * Set cooling_dev to NULL so we don't crash trying to | 1702 | device->backlight->props.brightness = |
1710 | * free it. | 1703 | acpi_video_get_brightness(device->backlight); |
1711 | * Also, why the hell we are returning early and | ||
1712 | * not attempt to register video output if cooling | ||
1713 | * device registration failed? | ||
1714 | * -- dtor | ||
1715 | */ | ||
1716 | device->cooling_dev = NULL; | ||
1717 | return; | ||
1718 | } | ||
1719 | 1704 | ||
1720 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", | 1705 | device->cooling_dev = thermal_cooling_device_register("LCD", |
1721 | device->cooling_dev->id); | 1706 | device->dev, &video_cooling_ops); |
1722 | result = sysfs_create_link(&device->dev->dev.kobj, | 1707 | if (IS_ERR(device->cooling_dev)) { |
1723 | &device->cooling_dev->device.kobj, | 1708 | /* |
1724 | "thermal_cooling"); | 1709 | * Set cooling_dev to NULL so we don't crash trying to free it. |
1725 | if (result) | 1710 | * Also, why the hell we are returning early and not attempt to |
1726 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1711 | * register video output if cooling device registration failed? |
1727 | result = sysfs_create_link(&device->cooling_dev->device.kobj, | 1712 | * -- dtor |
1728 | &device->dev->dev.kobj, "device"); | 1713 | */ |
1729 | if (result) | 1714 | device->cooling_dev = NULL; |
1730 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1715 | return; |
1731 | } | 1716 | } |
1717 | |||
1718 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", | ||
1719 | device->cooling_dev->id); | ||
1720 | result = sysfs_create_link(&device->dev->dev.kobj, | ||
1721 | &device->cooling_dev->device.kobj, | ||
1722 | "thermal_cooling"); | ||
1723 | if (result) | ||
1724 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
1725 | result = sysfs_create_link(&device->cooling_dev->device.kobj, | ||
1726 | &device->dev->dev.kobj, "device"); | ||
1727 | if (result) | ||
1728 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
1732 | } | 1729 | } |
1733 | 1730 | ||
1734 | static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) | 1731 | static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) |
1735 | { | 1732 | { |
1736 | struct acpi_video_device *dev; | 1733 | struct acpi_video_device *dev; |
1737 | 1734 | ||
1735 | if (!acpi_video_verify_backlight_support()) | ||
1736 | return 0; | ||
1737 | |||
1738 | mutex_lock(&video->device_list_lock); | 1738 | mutex_lock(&video->device_list_lock); |
1739 | list_for_each_entry(dev, &video->video_device_list, entry) | 1739 | list_for_each_entry(dev, &video->video_device_list, entry) |
1740 | acpi_video_dev_register_backlight(dev); | 1740 | acpi_video_dev_register_backlight(dev); |
1741 | mutex_unlock(&video->device_list_lock); | 1741 | mutex_unlock(&video->device_list_lock); |
1742 | 1742 | ||
1743 | video->backlight_registered = true; | ||
1744 | |||
1743 | video->pm_nb.notifier_call = acpi_video_resume; | 1745 | video->pm_nb.notifier_call = acpi_video_resume; |
1744 | video->pm_nb.priority = 0; | 1746 | video->pm_nb.priority = 0; |
1745 | return register_pm_notifier(&video->pm_nb); | 1747 | return register_pm_notifier(&video->pm_nb); |
@@ -1767,13 +1769,20 @@ static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device | |||
1767 | static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video) | 1769 | static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video) |
1768 | { | 1770 | { |
1769 | struct acpi_video_device *dev; | 1771 | struct acpi_video_device *dev; |
1770 | int error = unregister_pm_notifier(&video->pm_nb); | 1772 | int error; |
1773 | |||
1774 | if (!video->backlight_registered) | ||
1775 | return 0; | ||
1776 | |||
1777 | error = unregister_pm_notifier(&video->pm_nb); | ||
1771 | 1778 | ||
1772 | mutex_lock(&video->device_list_lock); | 1779 | mutex_lock(&video->device_list_lock); |
1773 | list_for_each_entry(dev, &video->video_device_list, entry) | 1780 | list_for_each_entry(dev, &video->video_device_list, entry) |
1774 | acpi_video_dev_unregister_backlight(dev); | 1781 | acpi_video_dev_unregister_backlight(dev); |
1775 | mutex_unlock(&video->device_list_lock); | 1782 | mutex_unlock(&video->device_list_lock); |
1776 | 1783 | ||
1784 | video->backlight_registered = false; | ||
1785 | |||
1777 | return error; | 1786 | return error; |
1778 | } | 1787 | } |
1779 | 1788 | ||
@@ -2061,6 +2070,20 @@ void acpi_video_unregister(void) | |||
2061 | } | 2070 | } |
2062 | EXPORT_SYMBOL(acpi_video_unregister); | 2071 | EXPORT_SYMBOL(acpi_video_unregister); |
2063 | 2072 | ||
2073 | void acpi_video_unregister_backlight(void) | ||
2074 | { | ||
2075 | struct acpi_video_bus *video; | ||
2076 | |||
2077 | if (!register_count) | ||
2078 | return; | ||
2079 | |||
2080 | mutex_lock(&video_list_lock); | ||
2081 | list_for_each_entry(video, &video_bus_head, entry) | ||
2082 | acpi_video_bus_unregister_backlight(video); | ||
2083 | mutex_unlock(&video_list_lock); | ||
2084 | } | ||
2085 | EXPORT_SYMBOL(acpi_video_unregister_backlight); | ||
2086 | |||
2064 | /* | 2087 | /* |
2065 | * This is kind of nasty. Hardware using Intel chipsets may require | 2088 | * This is kind of nasty. Hardware using Intel chipsets may require |
2066 | * the video opregion code to be run first in order to initialise | 2089 | * the video opregion code to be run first in order to initialise |