aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/video.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 14:52:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 14:52:52 -0400
commit08acd4f8af42affd8cbed81cc1b69fa12ddb213f (patch)
tree988d15db6233b20db6a500cd5f590c6d2041462d /drivers/acpi/video.c
parentccf2779544eecfcc5447e2028d1029b6d4ff7bb6 (diff)
parent008238b54ac2350babf195084ecedbcf7851a202 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (179 commits) ACPI: Fix acpi_processor_idle and idle= boot parameters interaction acpi: fix section mismatch warning in pnpacpi intel_menlo: fix build warning ACPI: Cleanup: Remove unneeded, multiple local dummy variables ACPI: video - fix permissions on some proc entries ACPI: video - properly handle errors when registering proc elements ACPI: video - do not store invalid entries in attached_array list ACPI: re-name acpi_pm_ops to acpi_suspend_ops ACER_WMI/ASUS_LAPTOP: fix build bug thinkpad_acpi: fix possible NULL pointer dereference if kstrdup failed ACPI: check a return value correctly in acpi_power_get_context() #if 0 acpi/bay.c:eject_removable_drive() eeepc-laptop: add hwmon fan control eeepc-laptop: add backlight eeepc-laptop: add base driver ACPI: thinkpad-acpi: bump up version to 0.20 ACPI: thinkpad-acpi: fix selects in Kconfig ACPI: thinkpad-acpi: use a private workqueue ACPI: thinkpad-acpi: fluff really minor fix ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation ... Fixed conflicts in drivers/acpi/video.c and drivers/misc/intel_menlow.c manually.
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r--drivers/acpi/video.c199
1 files changed, 103 insertions, 96 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 43b228314a86..f7eb12e55602 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -57,8 +57,6 @@
57#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 57#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
58#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 58#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
59 59
60#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
61#define ACPI_VIDEO_HEAD_END (~0u)
62#define MAX_NAME_LEN 20 60#define MAX_NAME_LEN 20
63 61
64#define ACPI_VIDEO_DISPLAY_CRT 1 62#define ACPI_VIDEO_DISPLAY_CRT 1
@@ -743,21 +741,19 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
743 if (IS_ERR(device->cdev)) 741 if (IS_ERR(device->cdev))
744 return; 742 return;
745 743
746 if (device->cdev) { 744 printk(KERN_INFO PREFIX
747 printk(KERN_INFO PREFIX 745 "%s is registered as cooling_device%d\n",
748 "%s is registered as cooling_device%d\n", 746 device->dev->dev.bus_id, device->cdev->id);
749 device->dev->dev.bus_id, device->cdev->id); 747 result = sysfs_create_link(&device->dev->dev.kobj,
750 result = sysfs_create_link(&device->dev->dev.kobj, 748 &device->cdev->device.kobj,
751 &device->cdev->device.kobj, 749 "thermal_cooling");
752 "thermal_cooling"); 750 if (result)
753 if (result) 751 printk(KERN_ERR PREFIX "Create sysfs link\n");
754 printk(KERN_ERR PREFIX "Create sysfs link\n"); 752 result = sysfs_create_link(&device->cdev->device.kobj,
755 result = sysfs_create_link(&device->cdev->device.kobj, 753 &device->dev->dev.kobj, "device");
756 &device->dev->dev.kobj, 754 if (result)
757 "device"); 755 printk(KERN_ERR PREFIX "Create sysfs link\n");
758 if (result) 756
759 printk(KERN_ERR PREFIX "Create sysfs link\n");
760 }
761 } 757 }
762 if (device->cap._DCS && device->cap._DSS){ 758 if (device->cap._DCS && device->cap._DSS){
763 static int count = 0; 759 static int count = 0;
@@ -1059,30 +1055,25 @@ acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
1059 1055
1060static int acpi_video_device_add_fs(struct acpi_device *device) 1056static int acpi_video_device_add_fs(struct acpi_device *device)
1061{ 1057{
1062 struct proc_dir_entry *entry = NULL; 1058 struct proc_dir_entry *entry, *device_dir;
1063 struct acpi_video_device *vid_dev; 1059 struct acpi_video_device *vid_dev;
1064 1060
1065
1066 if (!device)
1067 return -ENODEV;
1068
1069 vid_dev = acpi_driver_data(device); 1061 vid_dev = acpi_driver_data(device);
1070 if (!vid_dev) 1062 if (!vid_dev)
1071 return -ENODEV; 1063 return -ENODEV;
1072 1064
1073 if (!acpi_device_dir(device)) { 1065 device_dir = proc_mkdir(acpi_device_bid(device),
1074 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1066 vid_dev->video->dir);
1075 vid_dev->video->dir); 1067 if (!device_dir)
1076 if (!acpi_device_dir(device)) 1068 return -ENOMEM;
1077 return -ENODEV; 1069
1078 acpi_device_dir(device)->owner = THIS_MODULE; 1070 device_dir->owner = THIS_MODULE;
1079 }
1080 1071
1081 /* 'info' [R] */ 1072 /* 'info' [R] */
1082 entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device), 1073 entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device),
1083 &acpi_video_device_info_fops, acpi_driver_data(device)); 1074 &acpi_video_device_info_fops, acpi_driver_data(device));
1084 if (!entry) 1075 if (!entry)
1085 return -ENODEV; 1076 goto err_remove_dir;
1086 1077
1087 /* 'state' [R/W] */ 1078 /* 'state' [R/W] */
1088 acpi_video_device_state_fops.write = acpi_video_device_write_state; 1079 acpi_video_device_state_fops.write = acpi_video_device_write_state;
@@ -1091,7 +1082,7 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
1091 &acpi_video_device_state_fops, 1082 &acpi_video_device_state_fops,
1092 acpi_driver_data(device)); 1083 acpi_driver_data(device));
1093 if (!entry) 1084 if (!entry)
1094 return -ENODEV; 1085 goto err_remove_info;
1095 1086
1096 /* 'brightness' [R/W] */ 1087 /* 'brightness' [R/W] */
1097 acpi_video_device_brightness_fops.write = 1088 acpi_video_device_brightness_fops.write =
@@ -1101,30 +1092,43 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
1101 &acpi_video_device_brightness_fops, 1092 &acpi_video_device_brightness_fops,
1102 acpi_driver_data(device)); 1093 acpi_driver_data(device));
1103 if (!entry) 1094 if (!entry)
1104 return -ENODEV; 1095 goto err_remove_state;
1105 1096
1106 /* 'EDID' [R] */ 1097 /* 'EDID' [R] */
1107 entry = proc_create_data("EDID", S_IRUGO, acpi_device_dir(device), 1098 entry = proc_create_data("EDID", S_IRUGO, acpi_device_dir(device),
1108 &acpi_video_device_EDID_fops, 1099 &acpi_video_device_EDID_fops,
1109 acpi_driver_data(device)); 1100 acpi_driver_data(device));
1110 if (!entry) 1101 if (!entry)
1111 return -ENODEV; 1102 goto err_remove_brightness;
1103
1112 return 0; 1104 return 0;
1105
1106 err_remove_brightness:
1107 remove_proc_entry("brightness", device_dir);
1108 err_remove_state:
1109 remove_proc_entry("state", device_dir);
1110 err_remove_info:
1111 remove_proc_entry("info", device_dir);
1112 err_remove_dir:
1113 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1114 return -ENOMEM;
1113} 1115}
1114 1116
1115static int acpi_video_device_remove_fs(struct acpi_device *device) 1117static int acpi_video_device_remove_fs(struct acpi_device *device)
1116{ 1118{
1117 struct acpi_video_device *vid_dev; 1119 struct acpi_video_device *vid_dev;
1120 struct proc_dir_entry *device_dir;
1118 1121
1119 vid_dev = acpi_driver_data(device); 1122 vid_dev = acpi_driver_data(device);
1120 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) 1123 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
1121 return -ENODEV; 1124 return -ENODEV;
1122 1125
1123 if (acpi_device_dir(device)) { 1126 device_dir = acpi_device_dir(device);
1124 remove_proc_entry("info", acpi_device_dir(device)); 1127 if (device_dir) {
1125 remove_proc_entry("state", acpi_device_dir(device)); 1128 remove_proc_entry("info", device_dir);
1126 remove_proc_entry("brightness", acpi_device_dir(device)); 1129 remove_proc_entry("state", device_dir);
1127 remove_proc_entry("EDID", acpi_device_dir(device)); 1130 remove_proc_entry("brightness", device_dir);
1131 remove_proc_entry("EDID", device_dir);
1128 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); 1132 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1129 acpi_device_dir(device) = NULL; 1133 acpi_device_dir(device) = NULL;
1130 } 1134 }
@@ -1331,76 +1335,81 @@ acpi_video_bus_write_DOS(struct file *file,
1331 1335
1332static int acpi_video_bus_add_fs(struct acpi_device *device) 1336static int acpi_video_bus_add_fs(struct acpi_device *device)
1333{ 1337{
1334 struct proc_dir_entry *entry = NULL; 1338 struct acpi_video_bus *video = acpi_driver_data(device);
1335 struct acpi_video_bus *video; 1339 struct proc_dir_entry *device_dir;
1340 struct proc_dir_entry *entry;
1336 1341
1342 device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
1343 if (!device_dir)
1344 return -ENOMEM;
1337 1345
1338 video = acpi_driver_data(device); 1346 device_dir->owner = THIS_MODULE;
1339
1340 if (!acpi_device_dir(device)) {
1341 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1342 acpi_video_dir);
1343 if (!acpi_device_dir(device))
1344 return -ENODEV;
1345 video->dir = acpi_device_dir(device);
1346 acpi_device_dir(device)->owner = THIS_MODULE;
1347 }
1348 1347
1349 /* 'info' [R] */ 1348 /* 'info' [R] */
1350 entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device), 1349 entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device),
1351 &acpi_video_bus_info_fops, 1350 &acpi_video_bus_info_fops,
1352 acpi_driver_data(device)); 1351 acpi_driver_data(device));
1353 if (!entry) 1352 if (!entry)
1354 return -ENODEV; 1353 goto err_remove_dir;
1355 1354
1356 /* 'ROM' [R] */ 1355 /* 'ROM' [R] */
1357 entry = proc_create_data("ROM", S_IRUGO, acpi_device_dir(device), 1356 entry = proc_create_data("ROM", S_IRUGO, acpi_device_dir(device),
1358 &acpi_video_bus_ROM_fops, 1357 &acpi_video_bus_ROM_fops,
1359 acpi_driver_data(device)); 1358 acpi_driver_data(device));
1360 if (!entry) 1359 if (!entry)
1361 return -ENODEV; 1360 goto err_remove_info;
1362 1361
1363 /* 'POST_info' [R] */ 1362 /* 'POST_info' [R] */
1364 entry = proc_create_data("POST_info", S_IRUGO, acpi_device_dir(device), 1363 entry = proc_create_data("POST_info", S_IRUGO, acpi_device_dir(device),
1365 &acpi_video_bus_POST_info_fops, 1364 &acpi_video_bus_POST_info_fops,
1366 acpi_driver_data(device)); 1365 acpi_driver_data(device));
1367 if (!entry) 1366 if (!entry)
1368 return -ENODEV; 1367 goto err_remove_rom;
1369 1368
1370 /* 'POST' [R/W] */ 1369 /* 'POST' [R/W] */
1371 acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST; 1370 acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
1372 entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IRUSR, 1371 entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
1373 acpi_device_dir(device), 1372 acpi_device_dir(device),
1374 &acpi_video_bus_POST_fops, 1373 &acpi_video_bus_POST_fops,
1375 acpi_driver_data(device)); 1374 acpi_driver_data(device));
1376 if (!entry) 1375 if (!entry)
1377 return -ENODEV; 1376 goto err_remove_post_info;
1378 1377
1379 /* 'DOS' [R/W] */ 1378 /* 'DOS' [R/W] */
1380 acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS; 1379 acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
1381 entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IRUSR, 1380 entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
1382 acpi_device_dir(device), 1381 acpi_device_dir(device),
1383 &acpi_video_bus_DOS_fops, 1382 &acpi_video_bus_DOS_fops,
1384 acpi_driver_data(device)); 1383 acpi_driver_data(device));
1385 if (!entry) 1384 if (!entry)
1386 return -ENODEV; 1385 goto err_remove_post;
1387 1386
1387 video->dir = acpi_device_dir(device) = device_dir;
1388 return 0; 1388 return 0;
1389
1390 err_remove_post:
1391 remove_proc_entry("POST", device_dir);
1392 err_remove_post_info:
1393 remove_proc_entry("POST_info", device_dir);
1394 err_remove_rom:
1395 remove_proc_entry("ROM", device_dir);
1396 err_remove_info:
1397 remove_proc_entry("info", device_dir);
1398 err_remove_dir:
1399 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1400 return -ENOMEM;
1389} 1401}
1390 1402
1391static int acpi_video_bus_remove_fs(struct acpi_device *device) 1403static int acpi_video_bus_remove_fs(struct acpi_device *device)
1392{ 1404{
1393 struct acpi_video_bus *video; 1405 struct proc_dir_entry *device_dir = acpi_device_dir(device);
1394
1395 1406
1396 video = acpi_driver_data(device); 1407 if (device_dir) {
1397 1408 remove_proc_entry("info", device_dir);
1398 if (acpi_device_dir(device)) { 1409 remove_proc_entry("ROM", device_dir);
1399 remove_proc_entry("info", acpi_device_dir(device)); 1410 remove_proc_entry("POST_info", device_dir);
1400 remove_proc_entry("ROM", acpi_device_dir(device)); 1411 remove_proc_entry("POST", device_dir);
1401 remove_proc_entry("POST_info", acpi_device_dir(device)); 1412 remove_proc_entry("DOS", device_dir);
1402 remove_proc_entry("POST", acpi_device_dir(device));
1403 remove_proc_entry("DOS", acpi_device_dir(device));
1404 remove_proc_entry(acpi_device_bid(device), acpi_video_dir); 1413 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1405 acpi_device_dir(device) = NULL; 1414 acpi_device_dir(device) = NULL;
1406 } 1415 }
@@ -1416,11 +1425,15 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
1416static struct acpi_video_device_attrib* 1425static struct acpi_video_device_attrib*
1417acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) 1426acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1418{ 1427{
1419 int count; 1428 struct acpi_video_enumerated_device *ids;
1429 int i;
1430
1431 for (i = 0; i < video->attached_count; i++) {
1432 ids = &video->attached_array[i];
1433 if ((ids->value.int_val & 0xffff) == device_id)
1434 return &ids->value.attrib;
1435 }
1420 1436
1421 for(count = 0; count < video->attached_count; count++)
1422 if((video->attached_array[count].value.int_val & 0xffff) == device_id)
1423 return &(video->attached_array[count].value.attrib);
1424 return NULL; 1437 return NULL;
1425} 1438}
1426 1439
@@ -1547,20 +1560,16 @@ static void
1547acpi_video_device_bind(struct acpi_video_bus *video, 1560acpi_video_device_bind(struct acpi_video_bus *video,
1548 struct acpi_video_device *device) 1561 struct acpi_video_device *device)
1549{ 1562{
1563 struct acpi_video_enumerated_device *ids;
1550 int i; 1564 int i;
1551 1565
1552#define IDS_VAL(i) video->attached_array[i].value.int_val 1566 for (i = 0; i < video->attached_count; i++) {
1553#define IDS_BIND(i) video->attached_array[i].bind_info 1567 ids = &video->attached_array[i];
1554 1568 if (device->device_id == (ids->value.int_val & 0xffff)) {
1555 for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID && 1569 ids->bind_info = device;
1556 i < video->attached_count; i++) {
1557 if (device->device_id == (IDS_VAL(i) & 0xffff)) {
1558 IDS_BIND(i) = device;
1559 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); 1570 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
1560 } 1571 }
1561 } 1572 }
1562#undef IDS_VAL
1563#undef IDS_BIND
1564} 1573}
1565 1574
1566/* 1575/*
@@ -1579,7 +1588,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1579 int status; 1588 int status;
1580 int count; 1589 int count;
1581 int i; 1590 int i;
1582 struct acpi_video_enumerated_device *active_device_list; 1591 struct acpi_video_enumerated_device *active_list;
1583 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 1592 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1584 union acpi_object *dod = NULL; 1593 union acpi_object *dod = NULL;
1585 union acpi_object *obj; 1594 union acpi_object *obj;
@@ -1600,13 +1609,10 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1600 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", 1609 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
1601 dod->package.count)); 1610 dod->package.count));
1602 1611
1603 active_device_list = kmalloc((1 + 1612 active_list = kcalloc(1 + dod->package.count,
1604 dod->package.count) * 1613 sizeof(struct acpi_video_enumerated_device),
1605 sizeof(struct 1614 GFP_KERNEL);
1606 acpi_video_enumerated_device), 1615 if (!active_list) {
1607 GFP_KERNEL);
1608
1609 if (!active_device_list) {
1610 status = -ENOMEM; 1616 status = -ENOMEM;
1611 goto out; 1617 goto out;
1612 } 1618 }
@@ -1616,23 +1622,24 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1616 obj = &dod->package.elements[i]; 1622 obj = &dod->package.elements[i];
1617 1623
1618 if (obj->type != ACPI_TYPE_INTEGER) { 1624 if (obj->type != ACPI_TYPE_INTEGER) {
1619 printk(KERN_ERR PREFIX "Invalid _DOD data\n"); 1625 printk(KERN_ERR PREFIX
1620 active_device_list[i].value.int_val = 1626 "Invalid _DOD data in element %d\n", i);
1621 ACPI_VIDEO_HEAD_INVALID; 1627 continue;
1622 } 1628 }
1623 active_device_list[i].value.int_val = obj->integer.value; 1629
1624 active_device_list[i].bind_info = NULL; 1630 active_list[count].value.int_val = obj->integer.value;
1631 active_list[count].bind_info = NULL;
1625 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, 1632 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
1626 (int)obj->integer.value)); 1633 (int)obj->integer.value));
1627 count++; 1634 count++;
1628 } 1635 }
1629 active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
1630 1636
1631 kfree(video->attached_array); 1637 kfree(video->attached_array);
1632 1638
1633 video->attached_array = active_device_list; 1639 video->attached_array = active_list;
1634 video->attached_count = count; 1640 video->attached_count = count;
1635 out: 1641
1642 out:
1636 kfree(buffer.pointer); 1643 kfree(buffer.pointer);
1637 return status; 1644 return status;
1638} 1645}