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.c316
1 files changed, 155 insertions, 161 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 980a74188781..33c502e56026 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
@@ -734,21 +732,19 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
734 if (IS_ERR(device->cdev)) 732 if (IS_ERR(device->cdev))
735 return; 733 return;
736 734
737 if (device->cdev) { 735 printk(KERN_INFO PREFIX
738 printk(KERN_INFO PREFIX 736 "%s is registered as cooling_device%d\n",
739 "%s is registered as cooling_device%d\n", 737 device->dev->dev.bus_id, device->cdev->id);
740 device->dev->dev.bus_id, device->cdev->id); 738 result = sysfs_create_link(&device->dev->dev.kobj,
741 result = sysfs_create_link(&device->dev->dev.kobj, 739 &device->cdev->device.kobj,
742 &device->cdev->device.kobj, 740 "thermal_cooling");
743 "thermal_cooling"); 741 if (result)
744 if (result) 742 printk(KERN_ERR PREFIX "Create sysfs link\n");
745 printk(KERN_ERR PREFIX "Create sysfs link\n"); 743 result = sysfs_create_link(&device->cdev->device.kobj,
746 result = sysfs_create_link(&device->cdev->device.kobj, 744 &device->dev->dev.kobj, "device");
747 &device->dev->dev.kobj, 745 if (result)
748 "device"); 746 printk(KERN_ERR PREFIX "Create sysfs link\n");
749 if (result) 747
750 printk(KERN_ERR PREFIX "Create sysfs link\n");
751 }
752 } 748 }
753 if (device->cap._DCS && device->cap._DSS){ 749 if (device->cap._DCS && device->cap._DSS){
754 static int count = 0; 750 static int count = 0;
@@ -1050,87 +1046,90 @@ acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
1050 1046
1051static int acpi_video_device_add_fs(struct acpi_device *device) 1047static int acpi_video_device_add_fs(struct acpi_device *device)
1052{ 1048{
1053 struct proc_dir_entry *entry = NULL; 1049 struct proc_dir_entry *entry, *device_dir;
1054 struct acpi_video_device *vid_dev; 1050 struct acpi_video_device *vid_dev;
1055 1051
1056
1057 if (!device)
1058 return -ENODEV;
1059
1060 vid_dev = acpi_driver_data(device); 1052 vid_dev = acpi_driver_data(device);
1061 if (!vid_dev) 1053 if (!vid_dev)
1062 return -ENODEV; 1054 return -ENODEV;
1063 1055
1064 if (!acpi_device_dir(device)) { 1056 device_dir = proc_mkdir(acpi_device_bid(device),
1065 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1057 vid_dev->video->dir);
1066 vid_dev->video->dir); 1058 if (!device_dir)
1067 if (!acpi_device_dir(device)) 1059 return -ENOMEM;
1068 return -ENODEV; 1060
1069 acpi_device_dir(device)->owner = THIS_MODULE; 1061 device_dir->owner = THIS_MODULE;
1070 }
1071 1062
1072 /* 'info' [R] */ 1063 /* 'info' [R] */
1073 entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device)); 1064 entry = create_proc_entry("info", S_IRUGO, device_dir);
1074 if (!entry) 1065 if (!entry)
1075 return -ENODEV; 1066 goto err_remove_dir;
1076 else { 1067
1077 entry->proc_fops = &acpi_video_device_info_fops; 1068 entry->proc_fops = &acpi_video_device_info_fops;
1078 entry->data = acpi_driver_data(device); 1069 entry->data = acpi_driver_data(device);
1079 entry->owner = THIS_MODULE; 1070 entry->owner = THIS_MODULE;
1080 }
1081 1071
1082 /* 'state' [R/W] */ 1072 /* 'state' [R/W] */
1083 entry = 1073 entry = create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR,
1084 create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR, 1074 device_dir);
1085 acpi_device_dir(device));
1086 if (!entry) 1075 if (!entry)
1087 return -ENODEV; 1076 goto err_remove_info;
1088 else { 1077
1089 acpi_video_device_state_fops.write = acpi_video_device_write_state; 1078 acpi_video_device_state_fops.write = acpi_video_device_write_state;
1090 entry->proc_fops = &acpi_video_device_state_fops; 1079 entry->proc_fops = &acpi_video_device_state_fops;
1091 entry->data = acpi_driver_data(device); 1080 entry->data = acpi_driver_data(device);
1092 entry->owner = THIS_MODULE; 1081 entry->owner = THIS_MODULE;
1093 }
1094 1082
1095 /* 'brightness' [R/W] */ 1083 /* 'brightness' [R/W] */
1096 entry = 1084 entry = create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR,
1097 create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR, 1085 device_dir);
1098 acpi_device_dir(device));
1099 if (!entry) 1086 if (!entry)
1100 return -ENODEV; 1087 goto err_remove_state;
1101 else { 1088
1102 acpi_video_device_brightness_fops.write = acpi_video_device_write_brightness; 1089 acpi_video_device_brightness_fops.write =
1103 entry->proc_fops = &acpi_video_device_brightness_fops; 1090 acpi_video_device_write_brightness;
1104 entry->data = acpi_driver_data(device); 1091 entry->proc_fops = &acpi_video_device_brightness_fops;
1105 entry->owner = THIS_MODULE; 1092 entry->data = acpi_driver_data(device);
1106 } 1093 entry->owner = THIS_MODULE;
1107 1094
1108 /* 'EDID' [R] */ 1095 /* 'EDID' [R] */
1109 entry = create_proc_entry("EDID", S_IRUGO, acpi_device_dir(device)); 1096 entry = create_proc_entry("EDID", S_IRUGO, device_dir);
1110 if (!entry) 1097 if (!entry)
1111 return -ENODEV; 1098 goto err_remove_brightness;
1112 else {
1113 entry->proc_fops = &acpi_video_device_EDID_fops;
1114 entry->data = acpi_driver_data(device);
1115 entry->owner = THIS_MODULE;
1116 }
1117 1099
1100 entry->proc_fops = &acpi_video_device_EDID_fops;
1101 entry->data = acpi_driver_data(device);
1102 entry->owner = THIS_MODULE;
1103
1104 acpi_device_dir(device) = device_dir;
1118 return 0; 1105 return 0;
1106
1107 err_remove_brightness:
1108 remove_proc_entry("brightness", device_dir);
1109 err_remove_state:
1110 remove_proc_entry("state", device_dir);
1111 err_remove_info:
1112 remove_proc_entry("info", device_dir);
1113 err_remove_dir:
1114 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1115 return -ENOMEM;
1119} 1116}
1120 1117
1121static int acpi_video_device_remove_fs(struct acpi_device *device) 1118static int acpi_video_device_remove_fs(struct acpi_device *device)
1122{ 1119{
1123 struct acpi_video_device *vid_dev; 1120 struct acpi_video_device *vid_dev;
1121 struct proc_dir_entry *device_dir;
1124 1122
1125 vid_dev = acpi_driver_data(device); 1123 vid_dev = acpi_driver_data(device);
1126 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) 1124 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
1127 return -ENODEV; 1125 return -ENODEV;
1128 1126
1129 if (acpi_device_dir(device)) { 1127 device_dir = acpi_device_dir(device);
1130 remove_proc_entry("info", acpi_device_dir(device)); 1128 if (device_dir) {
1131 remove_proc_entry("state", acpi_device_dir(device)); 1129 remove_proc_entry("info", device_dir);
1132 remove_proc_entry("brightness", acpi_device_dir(device)); 1130 remove_proc_entry("state", device_dir);
1133 remove_proc_entry("EDID", acpi_device_dir(device)); 1131 remove_proc_entry("brightness", device_dir);
1132 remove_proc_entry("EDID", device_dir);
1134 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); 1133 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1135 acpi_device_dir(device) = NULL; 1134 acpi_device_dir(device) = NULL;
1136 } 1135 }
@@ -1337,94 +1336,91 @@ acpi_video_bus_write_DOS(struct file *file,
1337 1336
1338static int acpi_video_bus_add_fs(struct acpi_device *device) 1337static int acpi_video_bus_add_fs(struct acpi_device *device)
1339{ 1338{
1340 struct proc_dir_entry *entry = NULL; 1339 struct acpi_video_bus *video = acpi_driver_data(device);
1341 struct acpi_video_bus *video; 1340 struct proc_dir_entry *device_dir;
1342 1341 struct proc_dir_entry *entry;
1343 1342
1344 video = acpi_driver_data(device); 1343 device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
1344 if (!device_dir)
1345 return -ENOMEM;
1345 1346
1346 if (!acpi_device_dir(device)) { 1347 device_dir->owner = THIS_MODULE;
1347 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1348 acpi_video_dir);
1349 if (!acpi_device_dir(device))
1350 return -ENODEV;
1351 video->dir = acpi_device_dir(device);
1352 acpi_device_dir(device)->owner = THIS_MODULE;
1353 }
1354 1348
1355 /* 'info' [R] */ 1349 /* 'info' [R] */
1356 entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device)); 1350 entry = create_proc_entry("info", S_IRUGO, device_dir);
1357 if (!entry) 1351 if (!entry)
1358 return -ENODEV; 1352 goto err_remove_dir;
1359 else { 1353
1360 entry->proc_fops = &acpi_video_bus_info_fops; 1354 entry->proc_fops = &acpi_video_bus_info_fops;
1361 entry->data = acpi_driver_data(device); 1355 entry->data = acpi_driver_data(device);
1362 entry->owner = THIS_MODULE; 1356 entry->owner = THIS_MODULE;
1363 }
1364 1357
1365 /* 'ROM' [R] */ 1358 /* 'ROM' [R] */
1366 entry = create_proc_entry("ROM", S_IRUGO, acpi_device_dir(device)); 1359 entry = create_proc_entry("ROM", S_IRUGO, device_dir);
1367 if (!entry) 1360 if (!entry)
1368 return -ENODEV; 1361 goto err_remove_info;
1369 else { 1362
1370 entry->proc_fops = &acpi_video_bus_ROM_fops; 1363 entry->proc_fops = &acpi_video_bus_ROM_fops;
1371 entry->data = acpi_driver_data(device); 1364 entry->data = acpi_driver_data(device);
1372 entry->owner = THIS_MODULE; 1365 entry->owner = THIS_MODULE;
1373 }
1374 1366
1375 /* 'POST_info' [R] */ 1367 /* 'POST_info' [R] */
1376 entry = 1368 entry = create_proc_entry("POST_info", S_IRUGO, device_dir);
1377 create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device));
1378 if (!entry) 1369 if (!entry)
1379 return -ENODEV; 1370 goto err_remove_rom;
1380 else { 1371
1381 entry->proc_fops = &acpi_video_bus_POST_info_fops; 1372 entry->proc_fops = &acpi_video_bus_POST_info_fops;
1382 entry->data = acpi_driver_data(device); 1373 entry->data = acpi_driver_data(device);
1383 entry->owner = THIS_MODULE; 1374 entry->owner = THIS_MODULE;
1384 }
1385 1375
1386 /* 'POST' [R/W] */ 1376 /* 'POST' [R/W] */
1387 entry = 1377 entry = create_proc_entry("POST", S_IFREG | S_IRUGO | S_IWUSR,
1388 create_proc_entry("POST", S_IFREG | S_IRUGO | S_IRUSR, 1378 device_dir);
1389 acpi_device_dir(device));
1390 if (!entry) 1379 if (!entry)
1391 return -ENODEV; 1380 goto err_remove_post_info;
1392 else { 1381
1393 acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST; 1382 acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
1394 entry->proc_fops = &acpi_video_bus_POST_fops; 1383 entry->proc_fops = &acpi_video_bus_POST_fops;
1395 entry->data = acpi_driver_data(device); 1384 entry->data = acpi_driver_data(device);
1396 entry->owner = THIS_MODULE; 1385 entry->owner = THIS_MODULE;
1397 }
1398 1386
1399 /* 'DOS' [R/W] */ 1387 /* 'DOS' [R/W] */
1400 entry = 1388 entry = create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IWUSR,
1401 create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IRUSR, 1389 device_dir);
1402 acpi_device_dir(device));
1403 if (!entry) 1390 if (!entry)
1404 return -ENODEV; 1391 goto err_remove_post;
1405 else { 1392
1406 acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS; 1393 acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
1407 entry->proc_fops = &acpi_video_bus_DOS_fops; 1394 entry->proc_fops = &acpi_video_bus_DOS_fops;
1408 entry->data = acpi_driver_data(device); 1395 entry->data = acpi_driver_data(device);
1409 entry->owner = THIS_MODULE; 1396 entry->owner = THIS_MODULE;
1410 }
1411 1397
1398 video->dir = acpi_device_dir(device) = device_dir;
1412 return 0; 1399 return 0;
1400
1401 err_remove_post:
1402 remove_proc_entry("POST", device_dir);
1403 err_remove_post_info:
1404 remove_proc_entry("POST_info", device_dir);
1405 err_remove_rom:
1406 remove_proc_entry("ROM", device_dir);
1407 err_remove_info:
1408 remove_proc_entry("info", device_dir);
1409 err_remove_dir:
1410 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1411 return -ENOMEM;
1413} 1412}
1414 1413
1415static int acpi_video_bus_remove_fs(struct acpi_device *device) 1414static int acpi_video_bus_remove_fs(struct acpi_device *device)
1416{ 1415{
1417 struct acpi_video_bus *video; 1416 struct proc_dir_entry *device_dir = acpi_device_dir(device);
1418
1419
1420 video = acpi_driver_data(device);
1421 1417
1422 if (acpi_device_dir(device)) { 1418 if (device_dir) {
1423 remove_proc_entry("info", acpi_device_dir(device)); 1419 remove_proc_entry("info", device_dir);
1424 remove_proc_entry("ROM", acpi_device_dir(device)); 1420 remove_proc_entry("ROM", device_dir);
1425 remove_proc_entry("POST_info", acpi_device_dir(device)); 1421 remove_proc_entry("POST_info", device_dir);
1426 remove_proc_entry("POST", acpi_device_dir(device)); 1422 remove_proc_entry("POST", device_dir);
1427 remove_proc_entry("DOS", acpi_device_dir(device)); 1423 remove_proc_entry("DOS", device_dir);
1428 remove_proc_entry(acpi_device_bid(device), acpi_video_dir); 1424 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1429 acpi_device_dir(device) = NULL; 1425 acpi_device_dir(device) = NULL;
1430 } 1426 }
@@ -1440,11 +1436,15 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
1440static struct acpi_video_device_attrib* 1436static struct acpi_video_device_attrib*
1441acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) 1437acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1442{ 1438{
1443 int count; 1439 struct acpi_video_enumerated_device *ids;
1440 int i;
1441
1442 for (i = 0; i < video->attached_count; i++) {
1443 ids = &video->attached_array[i];
1444 if ((ids->value.int_val & 0xffff) == device_id)
1445 return &ids->value.attrib;
1446 }
1444 1447
1445 for(count = 0; count < video->attached_count; count++)
1446 if((video->attached_array[count].value.int_val & 0xffff) == device_id)
1447 return &(video->attached_array[count].value.attrib);
1448 return NULL; 1448 return NULL;
1449} 1449}
1450 1450
@@ -1571,20 +1571,16 @@ static void
1571acpi_video_device_bind(struct acpi_video_bus *video, 1571acpi_video_device_bind(struct acpi_video_bus *video,
1572 struct acpi_video_device *device) 1572 struct acpi_video_device *device)
1573{ 1573{
1574 struct acpi_video_enumerated_device *ids;
1574 int i; 1575 int i;
1575 1576
1576#define IDS_VAL(i) video->attached_array[i].value.int_val 1577 for (i = 0; i < video->attached_count; i++) {
1577#define IDS_BIND(i) video->attached_array[i].bind_info 1578 ids = &video->attached_array[i];
1578 1579 if (device->device_id == (ids->value.int_val & 0xffff)) {
1579 for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID && 1580 ids->bind_info = device;
1580 i < video->attached_count; i++) {
1581 if (device->device_id == (IDS_VAL(i) & 0xffff)) {
1582 IDS_BIND(i) = device;
1583 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); 1581 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
1584 } 1582 }
1585 } 1583 }
1586#undef IDS_VAL
1587#undef IDS_BIND
1588} 1584}
1589 1585
1590/* 1586/*
@@ -1603,7 +1599,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1603 int status; 1599 int status;
1604 int count; 1600 int count;
1605 int i; 1601 int i;
1606 struct acpi_video_enumerated_device *active_device_list; 1602 struct acpi_video_enumerated_device *active_list;
1607 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 1603 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1608 union acpi_object *dod = NULL; 1604 union acpi_object *dod = NULL;
1609 union acpi_object *obj; 1605 union acpi_object *obj;
@@ -1624,13 +1620,10 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1624 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", 1620 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
1625 dod->package.count)); 1621 dod->package.count));
1626 1622
1627 active_device_list = kmalloc((1 + 1623 active_list = kcalloc(1 + dod->package.count,
1628 dod->package.count) * 1624 sizeof(struct acpi_video_enumerated_device),
1629 sizeof(struct 1625 GFP_KERNEL);
1630 acpi_video_enumerated_device), 1626 if (!active_list) {
1631 GFP_KERNEL);
1632
1633 if (!active_device_list) {
1634 status = -ENOMEM; 1627 status = -ENOMEM;
1635 goto out; 1628 goto out;
1636 } 1629 }
@@ -1640,23 +1633,24 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1640 obj = &dod->package.elements[i]; 1633 obj = &dod->package.elements[i];
1641 1634
1642 if (obj->type != ACPI_TYPE_INTEGER) { 1635 if (obj->type != ACPI_TYPE_INTEGER) {
1643 printk(KERN_ERR PREFIX "Invalid _DOD data\n"); 1636 printk(KERN_ERR PREFIX
1644 active_device_list[i].value.int_val = 1637 "Invalid _DOD data in element %d\n", i);
1645 ACPI_VIDEO_HEAD_INVALID; 1638 continue;
1646 } 1639 }
1647 active_device_list[i].value.int_val = obj->integer.value; 1640
1648 active_device_list[i].bind_info = NULL; 1641 active_list[count].value.int_val = obj->integer.value;
1642 active_list[count].bind_info = NULL;
1649 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, 1643 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
1650 (int)obj->integer.value)); 1644 (int)obj->integer.value));
1651 count++; 1645 count++;
1652 } 1646 }
1653 active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
1654 1647
1655 kfree(video->attached_array); 1648 kfree(video->attached_array);
1656 1649
1657 video->attached_array = active_device_list; 1650 video->attached_array = active_list;
1658 video->attached_count = count; 1651 video->attached_count = count;
1659 out: 1652
1653 out:
1660 kfree(buffer.pointer); 1654 kfree(buffer.pointer);
1661 return status; 1655 return status;
1662} 1656}