aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r--drivers/acpi/video.c208
1 files changed, 119 insertions, 89 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bac956b30c57..a54ff6bce8fa 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -29,6 +29,7 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/list.h> 31#include <linux/list.h>
32#include <linux/mutex.h>
32#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 34#include <linux/seq_file.h>
34#include <linux/input.h> 35#include <linux/input.h>
@@ -135,8 +136,8 @@ struct acpi_video_bus {
135 u8 attached_count; 136 u8 attached_count;
136 struct acpi_video_bus_cap cap; 137 struct acpi_video_bus_cap cap;
137 struct acpi_video_bus_flags flags; 138 struct acpi_video_bus_flags flags;
138 struct semaphore sem;
139 struct list_head video_device_list; 139 struct list_head video_device_list;
140 struct mutex device_list_lock; /* protects video_device_list */
140 struct proc_dir_entry *dir; 141 struct proc_dir_entry *dir;
141 struct input_dev *input; 142 struct input_dev *input;
142 char phys[32]; /* for input device */ 143 char phys[32]; /* for input device */
@@ -291,18 +292,26 @@ static int acpi_video_device_set_state(struct acpi_video_device *device, int sta
291static int acpi_video_get_brightness(struct backlight_device *bd) 292static int acpi_video_get_brightness(struct backlight_device *bd)
292{ 293{
293 unsigned long cur_level; 294 unsigned long cur_level;
295 int i;
294 struct acpi_video_device *vd = 296 struct acpi_video_device *vd =
295 (struct acpi_video_device *)bl_get_data(bd); 297 (struct acpi_video_device *)bl_get_data(bd);
296 acpi_video_device_lcd_get_level_current(vd, &cur_level); 298 acpi_video_device_lcd_get_level_current(vd, &cur_level);
297 return (int) cur_level; 299 for (i = 2; i < vd->brightness->count; i++) {
300 if (vd->brightness->levels[i] == cur_level)
301 /* The first two entries are special - see page 575
302 of the ACPI spec 3.0 */
303 return i-2;
304 }
305 return 0;
298} 306}
299 307
300static int acpi_video_set_brightness(struct backlight_device *bd) 308static int acpi_video_set_brightness(struct backlight_device *bd)
301{ 309{
302 int request_level = bd->props.brightness; 310 int request_level = bd->props.brightness+2;
303 struct acpi_video_device *vd = 311 struct acpi_video_device *vd =
304 (struct acpi_video_device *)bl_get_data(bd); 312 (struct acpi_video_device *)bl_get_data(bd);
305 acpi_video_device_lcd_set_level(vd, request_level); 313 acpi_video_device_lcd_set_level(vd,
314 vd->brightness->levels[request_level]);
306 return 0; 315 return 0;
307} 316}
308 317
@@ -576,7 +585,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
576 struct acpi_video_device_brightness *br = NULL; 585 struct acpi_video_device_brightness *br = NULL;
577 586
578 587
579 memset(&device->cap, 0, 4); 588 memset(&device->cap, 0, sizeof(device->cap));
580 589
581 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { 590 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) {
582 device->cap._ADR = 1; 591 device->cap._ADR = 1;
@@ -651,7 +660,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
651 kfree(obj); 660 kfree(obj);
652 661
653 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ 662 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
654 unsigned long tmp;
655 static int count = 0; 663 static int count = 0;
656 char *name; 664 char *name;
657 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 665 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
@@ -659,11 +667,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
659 return; 667 return;
660 668
661 sprintf(name, "acpi_video%d", count++); 669 sprintf(name, "acpi_video%d", count++);
662 acpi_video_device_lcd_get_level_current(device, &tmp);
663 device->backlight = backlight_device_register(name, 670 device->backlight = backlight_device_register(name,
664 NULL, device, &acpi_backlight_ops); 671 NULL, device, &acpi_backlight_ops);
665 device->backlight->props.max_brightness = max_level; 672 device->backlight->props.max_brightness = device->brightness->count-3;
666 device->backlight->props.brightness = (int)tmp; 673 device->backlight->props.brightness = acpi_video_get_brightness(device->backlight);
667 backlight_update_status(device->backlight); 674 backlight_update_status(device->backlight);
668 675
669 kfree(name); 676 kfree(name);
@@ -696,7 +703,7 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
696{ 703{
697 acpi_handle h_dummy1; 704 acpi_handle h_dummy1;
698 705
699 memset(&video->cap, 0, 4); 706 memset(&video->cap, 0, sizeof(video->cap));
700 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { 707 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) {
701 video->cap._DOS = 1; 708 video->cap._DOS = 1;
702 } 709 }
@@ -896,7 +903,7 @@ acpi_video_device_write_brightness(struct file *file,
896{ 903{
897 struct seq_file *m = file->private_data; 904 struct seq_file *m = file->private_data;
898 struct acpi_video_device *dev = m->private; 905 struct acpi_video_device *dev = m->private;
899 char str[4] = { 0 }; 906 char str[5] = { 0 };
900 unsigned int level = 0; 907 unsigned int level = 0;
901 int i; 908 int i;
902 909
@@ -1255,8 +1262,37 @@ acpi_video_bus_write_DOS(struct file *file,
1255 1262
1256static int acpi_video_bus_add_fs(struct acpi_device *device) 1263static int acpi_video_bus_add_fs(struct acpi_device *device)
1257{ 1264{
1265 long device_id;
1266 int status;
1258 struct proc_dir_entry *entry = NULL; 1267 struct proc_dir_entry *entry = NULL;
1259 struct acpi_video_bus *video; 1268 struct acpi_video_bus *video;
1269 struct device *dev;
1270
1271 status =
1272 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
1273
1274 if (!ACPI_SUCCESS(status))
1275 return -ENODEV;
1276
1277 /* We need to attempt to determine whether the _ADR refers to a
1278 PCI device or not. There's no terribly good way to do this,
1279 so the best we can hope for is to assume that there'll never
1280 be a video device in the host bridge */
1281 if (device_id >= 0x10000) {
1282 /* It looks like a PCI device. Does it exist? */
1283 dev = acpi_get_physical_device(device->handle);
1284 } else {
1285 /* It doesn't look like a PCI device. Does its parent
1286 exist? */
1287 acpi_handle phandle;
1288 if (acpi_get_parent(device->handle, &phandle))
1289 return -ENODEV;
1290 dev = acpi_get_physical_device(phandle);
1291 }
1292 if (!dev)
1293 return -ENODEV;
1294 put_device(dev);
1295
1260 1296
1261 1297
1262 video = acpi_driver_data(device); 1298 video = acpi_driver_data(device);
@@ -1436,9 +1472,9 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1436 return -ENODEV; 1472 return -ENODEV;
1437 } 1473 }
1438 1474
1439 down(&video->sem); 1475 mutex_lock(&video->device_list_lock);
1440 list_add_tail(&data->entry, &video->video_device_list); 1476 list_add_tail(&data->entry, &video->video_device_list);
1441 up(&video->sem); 1477 mutex_unlock(&video->device_list_lock);
1442 1478
1443 acpi_video_device_add_fs(device); 1479 acpi_video_device_add_fs(device);
1444 1480
@@ -1462,12 +1498,14 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1462 1498
1463static void acpi_video_device_rebind(struct acpi_video_bus *video) 1499static void acpi_video_device_rebind(struct acpi_video_bus *video)
1464{ 1500{
1465 struct list_head *node, *next; 1501 struct acpi_video_device *dev;
1466 list_for_each_safe(node, next, &video->video_device_list) { 1502
1467 struct acpi_video_device *dev = 1503 mutex_lock(&video->device_list_lock);
1468 container_of(node, struct acpi_video_device, entry); 1504
1505 list_for_each_entry(dev, &video->video_device_list, entry)
1469 acpi_video_device_bind(video, dev); 1506 acpi_video_device_bind(video, dev);
1470 } 1507
1508 mutex_unlock(&video->device_list_lock);
1471} 1509}
1472 1510
1473/* 1511/*
@@ -1592,30 +1630,33 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1592 1630
1593static int acpi_video_switch_output(struct acpi_video_bus *video, int event) 1631static int acpi_video_switch_output(struct acpi_video_bus *video, int event)
1594{ 1632{
1595 struct list_head *node, *next; 1633 struct list_head *node;
1596 struct acpi_video_device *dev = NULL; 1634 struct acpi_video_device *dev = NULL;
1597 struct acpi_video_device *dev_next = NULL; 1635 struct acpi_video_device *dev_next = NULL;
1598 struct acpi_video_device *dev_prev = NULL; 1636 struct acpi_video_device *dev_prev = NULL;
1599 unsigned long state; 1637 unsigned long state;
1600 int status = 0; 1638 int status = 0;
1601 1639
1640 mutex_lock(&video->device_list_lock);
1602 1641
1603 list_for_each_safe(node, next, &video->video_device_list) { 1642 list_for_each(node, &video->video_device_list) {
1604 dev = container_of(node, struct acpi_video_device, entry); 1643 dev = container_of(node, struct acpi_video_device, entry);
1605 status = acpi_video_device_get_state(dev, &state); 1644 status = acpi_video_device_get_state(dev, &state);
1606 if (state & 0x2) { 1645 if (state & 0x2) {
1607 dev_next = 1646 dev_next = container_of(node->next,
1608 container_of(node->next, struct acpi_video_device, 1647 struct acpi_video_device, entry);
1609 entry); 1648 dev_prev = container_of(node->prev,
1610 dev_prev = 1649 struct acpi_video_device, entry);
1611 container_of(node->prev, struct acpi_video_device,
1612 entry);
1613 goto out; 1650 goto out;
1614 } 1651 }
1615 } 1652 }
1653
1616 dev_next = container_of(node->next, struct acpi_video_device, entry); 1654 dev_next = container_of(node->next, struct acpi_video_device, entry);
1617 dev_prev = container_of(node->prev, struct acpi_video_device, entry); 1655 dev_prev = container_of(node->prev, struct acpi_video_device, entry);
1618 out: 1656
1657 out:
1658 mutex_unlock(&video->device_list_lock);
1659
1619 switch (event) { 1660 switch (event) {
1620 case ACPI_VIDEO_NOTIFY_CYCLE: 1661 case ACPI_VIDEO_NOTIFY_CYCLE:
1621 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: 1662 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:
@@ -1691,24 +1732,17 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
1691 struct acpi_device *device) 1732 struct acpi_device *device)
1692{ 1733{
1693 int status = 0; 1734 int status = 0;
1694 struct list_head *node, *next; 1735 struct acpi_device *dev;
1695
1696 1736
1697 acpi_video_device_enumerate(video); 1737 acpi_video_device_enumerate(video);
1698 1738
1699 list_for_each_safe(node, next, &device->children) { 1739 list_for_each_entry(dev, &device->children, node) {
1700 struct acpi_device *dev =
1701 list_entry(node, struct acpi_device, node);
1702
1703 if (!dev)
1704 continue;
1705 1740
1706 status = acpi_video_bus_get_one_device(dev, video); 1741 status = acpi_video_bus_get_one_device(dev, video);
1707 if (ACPI_FAILURE(status)) { 1742 if (ACPI_FAILURE(status)) {
1708 ACPI_EXCEPTION((AE_INFO, status, "Cant attach device")); 1743 ACPI_EXCEPTION((AE_INFO, status, "Cant attach device"));
1709 continue; 1744 continue;
1710 } 1745 }
1711
1712 } 1746 }
1713 return status; 1747 return status;
1714} 1748}
@@ -1724,9 +1758,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1724 1758
1725 video = device->video; 1759 video = device->video;
1726 1760
1727 down(&video->sem);
1728 list_del(&device->entry);
1729 up(&video->sem);
1730 acpi_video_device_remove_fs(device->dev); 1761 acpi_video_device_remove_fs(device->dev);
1731 1762
1732 status = acpi_remove_notify_handler(device->dev->handle, 1763 status = acpi_remove_notify_handler(device->dev->handle,
@@ -1734,32 +1765,34 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1734 acpi_video_device_notify); 1765 acpi_video_device_notify);
1735 backlight_device_unregister(device->backlight); 1766 backlight_device_unregister(device->backlight);
1736 video_output_unregister(device->output_dev); 1767 video_output_unregister(device->output_dev);
1768
1737 return 0; 1769 return 0;
1738} 1770}
1739 1771
1740static int acpi_video_bus_put_devices(struct acpi_video_bus *video) 1772static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1741{ 1773{
1742 int status; 1774 int status;
1743 struct list_head *node, *next; 1775 struct acpi_video_device *dev, *next;
1744 1776
1777 mutex_lock(&video->device_list_lock);
1745 1778
1746 list_for_each_safe(node, next, &video->video_device_list) { 1779 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
1747 struct acpi_video_device *data =
1748 list_entry(node, struct acpi_video_device, entry);
1749 if (!data)
1750 continue;
1751 1780
1752 status = acpi_video_bus_put_one_device(data); 1781 status = acpi_video_bus_put_one_device(dev);
1753 if (ACPI_FAILURE(status)) 1782 if (ACPI_FAILURE(status))
1754 printk(KERN_WARNING PREFIX 1783 printk(KERN_WARNING PREFIX
1755 "hhuuhhuu bug in acpi video driver.\n"); 1784 "hhuuhhuu bug in acpi video driver.\n");
1756 1785
1757 if (data->brightness) 1786 if (dev->brightness) {
1758 kfree(data->brightness->levels); 1787 kfree(dev->brightness->levels);
1759 kfree(data->brightness); 1788 kfree(dev->brightness);
1760 kfree(data); 1789 }
1790 list_del(&dev->entry);
1791 kfree(dev);
1761 } 1792 }
1762 1793
1794 mutex_unlock(&video->device_list_lock);
1795
1763 return 0; 1796 return 0;
1764} 1797}
1765 1798
@@ -1782,9 +1815,6 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1782 struct input_dev *input; 1815 struct input_dev *input;
1783 int keycode; 1816 int keycode;
1784 1817
1785
1786 printk("video bus notify\n");
1787
1788 if (!video) 1818 if (!video)
1789 return; 1819 return;
1790 1820
@@ -1897,14 +1927,10 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1897static int instance; 1927static int instance;
1898static int acpi_video_bus_add(struct acpi_device *device) 1928static int acpi_video_bus_add(struct acpi_device *device)
1899{ 1929{
1900 int result = 0; 1930 acpi_status status;
1901 acpi_status status = 0; 1931 struct acpi_video_bus *video;
1902 struct acpi_video_bus *video = NULL;
1903 struct input_dev *input; 1932 struct input_dev *input;
1904 1933 int error;
1905
1906 if (!device)
1907 return -EINVAL;
1908 1934
1909 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); 1935 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
1910 if (!video) 1936 if (!video)
@@ -1923,15 +1949,15 @@ static int acpi_video_bus_add(struct acpi_device *device)
1923 acpi_driver_data(device) = video; 1949 acpi_driver_data(device) = video;
1924 1950
1925 acpi_video_bus_find_cap(video); 1951 acpi_video_bus_find_cap(video);
1926 result = acpi_video_bus_check(video); 1952 error = acpi_video_bus_check(video);
1927 if (result) 1953 if (error)
1928 goto end; 1954 goto err_free_video;
1929 1955
1930 result = acpi_video_bus_add_fs(device); 1956 error = acpi_video_bus_add_fs(device);
1931 if (result) 1957 if (error)
1932 goto end; 1958 goto err_free_video;
1933 1959
1934 init_MUTEX(&video->sem); 1960 mutex_init(&video->device_list_lock);
1935 INIT_LIST_HEAD(&video->video_device_list); 1961 INIT_LIST_HEAD(&video->video_device_list);
1936 1962
1937 acpi_video_bus_get_devices(video, device); 1963 acpi_video_bus_get_devices(video, device);
@@ -1943,16 +1969,15 @@ static int acpi_video_bus_add(struct acpi_device *device)
1943 if (ACPI_FAILURE(status)) { 1969 if (ACPI_FAILURE(status)) {
1944 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1970 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1945 "Error installing notify handler\n")); 1971 "Error installing notify handler\n"));
1946 acpi_video_bus_stop_devices(video); 1972 error = -ENODEV;
1947 acpi_video_bus_put_devices(video); 1973 goto err_stop_video;
1948 kfree(video->attached_array);
1949 acpi_video_bus_remove_fs(device);
1950 result = -ENODEV;
1951 goto end;
1952 } 1974 }
1953 1975
1954
1955 video->input = input = input_allocate_device(); 1976 video->input = input = input_allocate_device();
1977 if (!input) {
1978 error = -ENOMEM;
1979 goto err_uninstall_notify;
1980 }
1956 1981
1957 snprintf(video->phys, sizeof(video->phys), 1982 snprintf(video->phys, sizeof(video->phys),
1958 "%s/video/input0", acpi_device_hid(video->device)); 1983 "%s/video/input0", acpi_device_hid(video->device));
@@ -1961,6 +1986,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
1961 input->phys = video->phys; 1986 input->phys = video->phys;
1962 input->id.bustype = BUS_HOST; 1987 input->id.bustype = BUS_HOST;
1963 input->id.product = 0x06; 1988 input->id.product = 0x06;
1989 input->dev.parent = &device->dev;
1964 input->evbit[0] = BIT(EV_KEY); 1990 input->evbit[0] = BIT(EV_KEY);
1965 set_bit(KEY_SWITCHVIDEOMODE, input->keybit); 1991 set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
1966 set_bit(KEY_VIDEO_NEXT, input->keybit); 1992 set_bit(KEY_VIDEO_NEXT, input->keybit);
@@ -1971,18 +1997,10 @@ static int acpi_video_bus_add(struct acpi_device *device)
1971 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); 1997 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
1972 set_bit(KEY_DISPLAY_OFF, input->keybit); 1998 set_bit(KEY_DISPLAY_OFF, input->keybit);
1973 set_bit(KEY_UNKNOWN, input->keybit); 1999 set_bit(KEY_UNKNOWN, input->keybit);
1974 result = input_register_device(input);
1975 if (result) {
1976 acpi_remove_notify_handler(video->device->handle,
1977 ACPI_DEVICE_NOTIFY,
1978 acpi_video_bus_notify);
1979 acpi_video_bus_stop_devices(video);
1980 acpi_video_bus_put_devices(video);
1981 kfree(video->attached_array);
1982 acpi_video_bus_remove_fs(device);
1983 goto end;
1984 }
1985 2000
2001 error = input_register_device(input);
2002 if (error)
2003 goto err_free_input_dev;
1986 2004
1987 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", 2005 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
1988 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 2006 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
@@ -1990,11 +2008,23 @@ static int acpi_video_bus_add(struct acpi_device *device)
1990 video->flags.rom ? "yes" : "no", 2008 video->flags.rom ? "yes" : "no",
1991 video->flags.post ? "yes" : "no"); 2009 video->flags.post ? "yes" : "no");
1992 2010
1993 end: 2011 return 0;
1994 if (result) 2012
1995 kfree(video); 2013 err_free_input_dev:
2014 input_free_device(input);
2015 err_uninstall_notify:
2016 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
2017 acpi_video_bus_notify);
2018 err_stop_video:
2019 acpi_video_bus_stop_devices(video);
2020 acpi_video_bus_put_devices(video);
2021 kfree(video->attached_array);
2022 acpi_video_bus_remove_fs(device);
2023 err_free_video:
2024 kfree(video);
2025 acpi_driver_data(device) = NULL;
1996 2026
1997 return result; 2027 return error;
1998} 2028}
1999 2029
2000static int acpi_video_bus_remove(struct acpi_device *device, int type) 2030static int acpi_video_bus_remove(struct acpi_device *device, int type)