aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/video.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-05-24 07:27:11 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-05-24 07:27:11 -0400
commit2d8fe6757e1d857d8b266b25c553923695409e01 (patch)
treee7669608f1f7087cee5aabae94b6ea136ccdfaea /drivers/acpi/video.c
parent07d1d29ee1e194b932328ad2dc1d40297062ab7f (diff)
parent9404cd95507de0a61f2a000fbd76748a9cae33b4 (diff)
Merge back earlier 'acpi-video' material.
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r--drivers/acpi/video.c155
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");
68MODULE_DESCRIPTION("ACPI Video Driver"); 68MODULE_DESCRIPTION("ACPI Video Driver");
69MODULE_LICENSE("GPL"); 69MODULE_LICENSE("GPL");
70 70
71static bool brightness_switch_enabled = 1; 71static bool brightness_switch_enabled;
72module_param(brightness_switch_enabled, bool, 0644); 72module_param(brightness_switch_enabled, bool, 0644);
73 73
74/* 74/*
@@ -150,6 +150,7 @@ struct acpi_video_enumerated_device {
150 150
151struct acpi_video_bus { 151struct 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
1659static void acpi_video_dev_register_backlight(struct acpi_video_device *device) 1660static 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
1734static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) 1731static 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
1767static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video) 1769static 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}
2062EXPORT_SYMBOL(acpi_video_unregister); 2071EXPORT_SYMBOL(acpi_video_unregister);
2063 2072
2073void 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}
2085EXPORT_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