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.c771
1 files changed, 1 insertions, 770 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 67dec0c675aa..5cd0228d2daa 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -30,8 +30,6 @@
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/mutex.h>
33#include <linux/proc_fs.h>
34#include <linux/seq_file.h>
35#include <linux/input.h> 33#include <linux/input.h>
36#include <linux/backlight.h> 34#include <linux/backlight.h>
37#include <linux/thermal.h> 35#include <linux/thermal.h>
@@ -152,9 +150,6 @@ struct acpi_video_bus {
152 struct acpi_video_bus_flags flags; 150 struct acpi_video_bus_flags flags;
153 struct list_head video_device_list; 151 struct list_head video_device_list;
154 struct mutex device_list_lock; /* protects video_device_list */ 152 struct mutex device_list_lock; /* protects video_device_list */
155#ifdef CONFIG_ACPI_PROCFS
156 struct proc_dir_entry *dir;
157#endif
158 struct input_dev *input; 153 struct input_dev *input;
159 char phys[32]; /* for input device */ 154 char phys[32]; /* for input device */
160 struct notifier_block pm_nb; 155 struct notifier_block pm_nb;
@@ -210,108 +205,6 @@ struct acpi_video_device {
210 struct output_device *output_dev; 205 struct output_device *output_dev;
211}; 206};
212 207
213#ifdef CONFIG_ACPI_PROCFS
214/* bus */
215static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
216static const struct file_operations acpi_video_bus_info_fops = {
217 .owner = THIS_MODULE,
218 .open = acpi_video_bus_info_open_fs,
219 .read = seq_read,
220 .llseek = seq_lseek,
221 .release = single_release,
222};
223
224static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
225static const struct file_operations acpi_video_bus_ROM_fops = {
226 .owner = THIS_MODULE,
227 .open = acpi_video_bus_ROM_open_fs,
228 .read = seq_read,
229 .llseek = seq_lseek,
230 .release = single_release,
231};
232
233static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
234 struct file *file);
235static const struct file_operations acpi_video_bus_POST_info_fops = {
236 .owner = THIS_MODULE,
237 .open = acpi_video_bus_POST_info_open_fs,
238 .read = seq_read,
239 .llseek = seq_lseek,
240 .release = single_release,
241};
242
243static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
244static ssize_t acpi_video_bus_write_POST(struct file *file,
245 const char __user *buffer, size_t count, loff_t *data);
246static const struct file_operations acpi_video_bus_POST_fops = {
247 .owner = THIS_MODULE,
248 .open = acpi_video_bus_POST_open_fs,
249 .read = seq_read,
250 .write = acpi_video_bus_write_POST,
251 .llseek = seq_lseek,
252 .release = single_release,
253};
254
255static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
256static ssize_t acpi_video_bus_write_DOS(struct file *file,
257 const char __user *buffer, size_t count, loff_t *data);
258static const struct file_operations acpi_video_bus_DOS_fops = {
259 .owner = THIS_MODULE,
260 .open = acpi_video_bus_DOS_open_fs,
261 .read = seq_read,
262 .write = acpi_video_bus_write_DOS,
263 .llseek = seq_lseek,
264 .release = single_release,
265};
266
267/* device */
268static int acpi_video_device_info_open_fs(struct inode *inode,
269 struct file *file);
270static const struct file_operations acpi_video_device_info_fops = {
271 .owner = THIS_MODULE,
272 .open = acpi_video_device_info_open_fs,
273 .read = seq_read,
274 .llseek = seq_lseek,
275 .release = single_release,
276};
277
278static int acpi_video_device_state_open_fs(struct inode *inode,
279 struct file *file);
280static ssize_t acpi_video_device_write_state(struct file *file,
281 const char __user *buffer, size_t count, loff_t *data);
282static const struct file_operations acpi_video_device_state_fops = {
283 .owner = THIS_MODULE,
284 .open = acpi_video_device_state_open_fs,
285 .read = seq_read,
286 .write = acpi_video_device_write_state,
287 .llseek = seq_lseek,
288 .release = single_release,
289};
290
291static int acpi_video_device_brightness_open_fs(struct inode *inode,
292 struct file *file);
293static ssize_t acpi_video_device_write_brightness(struct file *file,
294 const char __user *buffer, size_t count, loff_t *data);
295static const struct file_operations acpi_video_device_brightness_fops = {
296 .owner = THIS_MODULE,
297 .open = acpi_video_device_brightness_open_fs,
298 .read = seq_read,
299 .write = acpi_video_device_write_brightness,
300 .llseek = seq_lseek,
301 .release = single_release,
302};
303
304static int acpi_video_device_EDID_open_fs(struct inode *inode,
305 struct file *file);
306static const struct file_operations acpi_video_device_EDID_fops = {
307 .owner = THIS_MODULE,
308 .open = acpi_video_device_EDID_open_fs,
309 .read = seq_read,
310 .llseek = seq_lseek,
311 .release = single_release,
312};
313#endif /* CONFIG_ACPI_PROCFS */
314
315static const char device_decode[][30] = { 208static const char device_decode[][30] = {
316 "motherboard VGA device", 209 "motherboard VGA device",
317 "PCI VGA device", 210 "PCI VGA device",
@@ -1111,646 +1004,6 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
1111} 1004}
1112 1005
1113/* -------------------------------------------------------------------------- 1006/* --------------------------------------------------------------------------
1114 FS Interface (/proc)
1115 -------------------------------------------------------------------------- */
1116#ifdef CONFIG_ACPI_PROCFS
1117
1118static struct proc_dir_entry *acpi_video_dir;
1119
1120/* video devices */
1121
1122static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
1123{
1124 struct acpi_video_device *dev = seq->private;
1125
1126
1127 if (!dev)
1128 goto end;
1129
1130 seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id);
1131 seq_printf(seq, "type: ");
1132 if (dev->flags.crt)
1133 seq_printf(seq, "CRT\n");
1134 else if (dev->flags.lcd)
1135 seq_printf(seq, "LCD\n");
1136 else if (dev->flags.tvout)
1137 seq_printf(seq, "TVOUT\n");
1138 else if (dev->flags.dvi)
1139 seq_printf(seq, "DVI\n");
1140 else
1141 seq_printf(seq, "UNKNOWN\n");
1142
1143 seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no");
1144
1145 end:
1146 return 0;
1147}
1148
1149static int
1150acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
1151{
1152 return single_open(file, acpi_video_device_info_seq_show,
1153 PDE(inode)->data);
1154}
1155
1156static int
1157acpi_video_device_query(struct acpi_video_device *device,
1158 unsigned long long *state)
1159{
1160 int status;
1161
1162 status = acpi_evaluate_integer(device->dev->handle, "_DGS",
1163 NULL, state);
1164
1165 return status;
1166}
1167
1168static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
1169{
1170 int status;
1171 struct acpi_video_device *dev = seq->private;
1172 unsigned long long state;
1173
1174
1175 if (!dev)
1176 goto end;
1177
1178 status = acpi_video_device_get_state(dev, &state);
1179 seq_printf(seq, "state: ");
1180 if (ACPI_SUCCESS(status))
1181 seq_printf(seq, "0x%02llx\n", state);
1182 else
1183 seq_printf(seq, "<not supported>\n");
1184
1185 status = acpi_video_device_query(dev, &state);
1186 seq_printf(seq, "query: ");
1187 if (ACPI_SUCCESS(status))
1188 seq_printf(seq, "0x%02llx\n", state);
1189 else
1190 seq_printf(seq, "<not supported>\n");
1191
1192 end:
1193 return 0;
1194}
1195
1196static int
1197acpi_video_device_state_open_fs(struct inode *inode, struct file *file)
1198{
1199 return single_open(file, acpi_video_device_state_seq_show,
1200 PDE(inode)->data);
1201}
1202
1203static ssize_t
1204acpi_video_device_write_state(struct file *file,
1205 const char __user * buffer,
1206 size_t count, loff_t * data)
1207{
1208 int status;
1209 struct seq_file *m = file->private_data;
1210 struct acpi_video_device *dev = m->private;
1211 char str[12] = { 0 };
1212 u32 state = 0;
1213
1214
1215 if (!dev || count >= sizeof(str))
1216 return -EINVAL;
1217
1218 if (copy_from_user(str, buffer, count))
1219 return -EFAULT;
1220
1221 str[count] = 0;
1222 state = simple_strtoul(str, NULL, 0);
1223 state &= ((1ul << 31) | (1ul << 30) | (1ul << 0));
1224
1225 status = acpi_video_device_set_state(dev, state);
1226
1227 if (status)
1228 return -EFAULT;
1229
1230 return count;
1231}
1232
1233static int
1234acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
1235{
1236 struct acpi_video_device *dev = seq->private;
1237 int i;
1238
1239
1240 if (!dev || !dev->brightness) {
1241 seq_printf(seq, "<not supported>\n");
1242 return 0;
1243 }
1244
1245 seq_printf(seq, "levels: ");
1246 for (i = 2; i < dev->brightness->count; i++)
1247 seq_printf(seq, " %d", dev->brightness->levels[i]);
1248 seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
1249
1250 return 0;
1251}
1252
1253static int
1254acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file)
1255{
1256 return single_open(file, acpi_video_device_brightness_seq_show,
1257 PDE(inode)->data);
1258}
1259
1260static ssize_t
1261acpi_video_device_write_brightness(struct file *file,
1262 const char __user * buffer,
1263 size_t count, loff_t * data)
1264{
1265 struct seq_file *m = file->private_data;
1266 struct acpi_video_device *dev = m->private;
1267 char str[5] = { 0 };
1268 unsigned int level = 0;
1269 int i;
1270
1271
1272 if (!dev || !dev->brightness || count >= sizeof(str))
1273 return -EINVAL;
1274
1275 if (copy_from_user(str, buffer, count))
1276 return -EFAULT;
1277
1278 str[count] = 0;
1279 level = simple_strtoul(str, NULL, 0);
1280
1281 if (level > 100)
1282 return -EFAULT;
1283
1284 /* validate through the list of available levels */
1285 for (i = 2; i < dev->brightness->count; i++)
1286 if (level == dev->brightness->levels[i]) {
1287 if (!acpi_video_device_lcd_set_level(dev, level))
1288 return count;
1289 break;
1290 }
1291
1292 return -EINVAL;
1293}
1294
1295static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
1296{
1297 struct acpi_video_device *dev = seq->private;
1298 int status;
1299 int i;
1300 union acpi_object *edid = NULL;
1301
1302
1303 if (!dev)
1304 goto out;
1305
1306 status = acpi_video_device_EDID(dev, &edid, 128);
1307 if (ACPI_FAILURE(status)) {
1308 status = acpi_video_device_EDID(dev, &edid, 256);
1309 }
1310
1311 if (ACPI_FAILURE(status)) {
1312 goto out;
1313 }
1314
1315 if (edid && edid->type == ACPI_TYPE_BUFFER) {
1316 for (i = 0; i < edid->buffer.length; i++)
1317 seq_putc(seq, edid->buffer.pointer[i]);
1318 }
1319
1320 out:
1321 if (!edid)
1322 seq_printf(seq, "<not supported>\n");
1323 else
1324 kfree(edid);
1325
1326 return 0;
1327}
1328
1329static int
1330acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
1331{
1332 return single_open(file, acpi_video_device_EDID_seq_show,
1333 PDE(inode)->data);
1334}
1335
1336static int acpi_video_device_add_fs(struct acpi_device *device)
1337{
1338 struct proc_dir_entry *entry, *device_dir;
1339 struct acpi_video_device *vid_dev;
1340
1341 vid_dev = acpi_driver_data(device);
1342 if (!vid_dev)
1343 return -ENODEV;
1344
1345 device_dir = proc_mkdir(acpi_device_bid(device),
1346 vid_dev->video->dir);
1347 if (!device_dir)
1348 return -ENOMEM;
1349
1350 /* 'info' [R] */
1351 entry = proc_create_data("info", S_IRUGO, device_dir,
1352 &acpi_video_device_info_fops, acpi_driver_data(device));
1353 if (!entry)
1354 goto err_remove_dir;
1355
1356 /* 'state' [R/W] */
1357 entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
1358 device_dir,
1359 &acpi_video_device_state_fops,
1360 acpi_driver_data(device));
1361 if (!entry)
1362 goto err_remove_info;
1363
1364 /* 'brightness' [R/W] */
1365 entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
1366 device_dir,
1367 &acpi_video_device_brightness_fops,
1368 acpi_driver_data(device));
1369 if (!entry)
1370 goto err_remove_state;
1371
1372 /* 'EDID' [R] */
1373 entry = proc_create_data("EDID", S_IRUGO, device_dir,
1374 &acpi_video_device_EDID_fops,
1375 acpi_driver_data(device));
1376 if (!entry)
1377 goto err_remove_brightness;
1378
1379 acpi_device_dir(device) = device_dir;
1380
1381 return 0;
1382
1383 err_remove_brightness:
1384 remove_proc_entry("brightness", device_dir);
1385 err_remove_state:
1386 remove_proc_entry("state", device_dir);
1387 err_remove_info:
1388 remove_proc_entry("info", device_dir);
1389 err_remove_dir:
1390 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1391 return -ENOMEM;
1392}
1393
1394static int acpi_video_device_remove_fs(struct acpi_device *device)
1395{
1396 struct acpi_video_device *vid_dev;
1397 struct proc_dir_entry *device_dir;
1398
1399 vid_dev = acpi_driver_data(device);
1400 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
1401 return -ENODEV;
1402
1403 device_dir = acpi_device_dir(device);
1404 if (device_dir) {
1405 remove_proc_entry("info", device_dir);
1406 remove_proc_entry("state", device_dir);
1407 remove_proc_entry("brightness", device_dir);
1408 remove_proc_entry("EDID", device_dir);
1409 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1410 acpi_device_dir(device) = NULL;
1411 }
1412
1413 return 0;
1414}
1415
1416/* video bus */
1417static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
1418{
1419 struct acpi_video_bus *video = seq->private;
1420
1421
1422 if (!video)
1423 goto end;
1424
1425 seq_printf(seq, "Switching heads: %s\n",
1426 video->flags.multihead ? "yes" : "no");
1427 seq_printf(seq, "Video ROM: %s\n",
1428 video->flags.rom ? "yes" : "no");
1429 seq_printf(seq, "Device to be POSTed on boot: %s\n",
1430 video->flags.post ? "yes" : "no");
1431
1432 end:
1433 return 0;
1434}
1435
1436static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
1437{
1438 return single_open(file, acpi_video_bus_info_seq_show,
1439 PDE(inode)->data);
1440}
1441
1442static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
1443{
1444 struct acpi_video_bus *video = seq->private;
1445
1446
1447 if (!video)
1448 goto end;
1449
1450 printk(KERN_INFO PREFIX "Please implement %s\n", __func__);
1451 seq_printf(seq, "<TODO>\n");
1452
1453 end:
1454 return 0;
1455}
1456
1457static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
1458{
1459 return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);
1460}
1461
1462static int
1463acpi_video_bus_POST_options(struct acpi_video_bus *video,
1464 unsigned long long *options)
1465{
1466 int status;
1467
1468 status = acpi_evaluate_integer(video->device->handle, "_VPO",
1469 NULL, options);
1470 *options &= 3;
1471
1472 return status;
1473}
1474
1475static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
1476{
1477 struct acpi_video_bus *video = seq->private;
1478 unsigned long long options;
1479 int status;
1480
1481
1482 if (!video)
1483 goto end;
1484
1485 status = acpi_video_bus_POST_options(video, &options);
1486 if (ACPI_SUCCESS(status)) {
1487 if (!(options & 1)) {
1488 printk(KERN_WARNING PREFIX
1489 "The motherboard VGA device is not listed as a possible POST device.\n");
1490 printk(KERN_WARNING PREFIX
1491 "This indicates a BIOS bug. Please contact the manufacturer.\n");
1492 }
1493 printk(KERN_WARNING "%llx\n", options);
1494 seq_printf(seq, "can POST: <integrated video>");
1495 if (options & 2)
1496 seq_printf(seq, " <PCI video>");
1497 if (options & 4)
1498 seq_printf(seq, " <AGP video>");
1499 seq_putc(seq, '\n');
1500 } else
1501 seq_printf(seq, "<not supported>\n");
1502 end:
1503 return 0;
1504}
1505
1506static int
1507acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
1508{
1509 return single_open(file, acpi_video_bus_POST_info_seq_show,
1510 PDE(inode)->data);
1511}
1512
1513static int
1514acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
1515{
1516 int status;
1517
1518 status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id);
1519
1520 return status;
1521}
1522
1523static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
1524{
1525 struct acpi_video_bus *video = seq->private;
1526 int status;
1527 unsigned long long id;
1528
1529
1530 if (!video)
1531 goto end;
1532
1533 status = acpi_video_bus_get_POST(video, &id);
1534 if (!ACPI_SUCCESS(status)) {
1535 seq_printf(seq, "<not supported>\n");
1536 goto end;
1537 }
1538 seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]);
1539
1540 end:
1541 return 0;
1542}
1543
1544static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
1545{
1546 struct acpi_video_bus *video = seq->private;
1547
1548
1549 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
1550
1551 return 0;
1552}
1553
1554static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file)
1555{
1556 return single_open(file, acpi_video_bus_POST_seq_show,
1557 PDE(inode)->data);
1558}
1559
1560static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file)
1561{
1562 return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);
1563}
1564
1565static int
1566acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
1567{
1568 int status;
1569 unsigned long long tmp;
1570 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
1571 struct acpi_object_list args = { 1, &arg0 };
1572
1573
1574 arg0.integer.value = option;
1575
1576 status = acpi_evaluate_integer(video->device->handle, "_SPD",
1577 &args, &tmp);
1578 if (ACPI_SUCCESS(status))
1579 status = tmp ? (-EINVAL) : (AE_OK);
1580
1581 return status;
1582}
1583
1584static ssize_t
1585acpi_video_bus_write_POST(struct file *file,
1586 const char __user * buffer,
1587 size_t count, loff_t * data)
1588{
1589 int status;
1590 struct seq_file *m = file->private_data;
1591 struct acpi_video_bus *video = m->private;
1592 char str[12] = { 0 };
1593 unsigned long long opt, options;
1594
1595
1596 if (!video || count >= sizeof(str))
1597 return -EINVAL;
1598
1599 status = acpi_video_bus_POST_options(video, &options);
1600 if (!ACPI_SUCCESS(status))
1601 return -EINVAL;
1602
1603 if (copy_from_user(str, buffer, count))
1604 return -EFAULT;
1605
1606 str[count] = 0;
1607 opt = strtoul(str, NULL, 0);
1608 if (opt > 3)
1609 return -EFAULT;
1610
1611 /* just in case an OEM 'forgot' the motherboard... */
1612 options |= 1;
1613
1614 if (options & (1ul << opt)) {
1615 status = acpi_video_bus_set_POST(video, opt);
1616 if (!ACPI_SUCCESS(status))
1617 return -EFAULT;
1618
1619 }
1620
1621 return count;
1622}
1623
1624static ssize_t
1625acpi_video_bus_write_DOS(struct file *file,
1626 const char __user * buffer,
1627 size_t count, loff_t * data)
1628{
1629 int status;
1630 struct seq_file *m = file->private_data;
1631 struct acpi_video_bus *video = m->private;
1632 char str[12] = { 0 };
1633 unsigned long opt;
1634
1635
1636 if (!video || count >= sizeof(str))
1637 return -EINVAL;
1638
1639 if (copy_from_user(str, buffer, count))
1640 return -EFAULT;
1641
1642 str[count] = 0;
1643 opt = strtoul(str, NULL, 0);
1644 if (opt > 7)
1645 return -EFAULT;
1646
1647 status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2);
1648
1649 if (!ACPI_SUCCESS(status))
1650 return -EFAULT;
1651
1652 return count;
1653}
1654
1655static int acpi_video_bus_add_fs(struct acpi_device *device)
1656{
1657 struct acpi_video_bus *video = acpi_driver_data(device);
1658 struct proc_dir_entry *device_dir;
1659 struct proc_dir_entry *entry;
1660
1661 device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
1662 if (!device_dir)
1663 return -ENOMEM;
1664
1665 /* 'info' [R] */
1666 entry = proc_create_data("info", S_IRUGO, device_dir,
1667 &acpi_video_bus_info_fops,
1668 acpi_driver_data(device));
1669 if (!entry)
1670 goto err_remove_dir;
1671
1672 /* 'ROM' [R] */
1673 entry = proc_create_data("ROM", S_IRUGO, device_dir,
1674 &acpi_video_bus_ROM_fops,
1675 acpi_driver_data(device));
1676 if (!entry)
1677 goto err_remove_info;
1678
1679 /* 'POST_info' [R] */
1680 entry = proc_create_data("POST_info", S_IRUGO, device_dir,
1681 &acpi_video_bus_POST_info_fops,
1682 acpi_driver_data(device));
1683 if (!entry)
1684 goto err_remove_rom;
1685
1686 /* 'POST' [R/W] */
1687 entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
1688 device_dir,
1689 &acpi_video_bus_POST_fops,
1690 acpi_driver_data(device));
1691 if (!entry)
1692 goto err_remove_post_info;
1693
1694 /* 'DOS' [R/W] */
1695 entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
1696 device_dir,
1697 &acpi_video_bus_DOS_fops,
1698 acpi_driver_data(device));
1699 if (!entry)
1700 goto err_remove_post;
1701
1702 video->dir = acpi_device_dir(device) = device_dir;
1703 return 0;
1704
1705 err_remove_post:
1706 remove_proc_entry("POST", device_dir);
1707 err_remove_post_info:
1708 remove_proc_entry("POST_info", device_dir);
1709 err_remove_rom:
1710 remove_proc_entry("ROM", device_dir);
1711 err_remove_info:
1712 remove_proc_entry("info", device_dir);
1713 err_remove_dir:
1714 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1715 return -ENOMEM;
1716}
1717
1718static int acpi_video_bus_remove_fs(struct acpi_device *device)
1719{
1720 struct proc_dir_entry *device_dir = acpi_device_dir(device);
1721
1722 if (device_dir) {
1723 remove_proc_entry("info", device_dir);
1724 remove_proc_entry("ROM", device_dir);
1725 remove_proc_entry("POST_info", device_dir);
1726 remove_proc_entry("POST", device_dir);
1727 remove_proc_entry("DOS", device_dir);
1728 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1729 acpi_device_dir(device) = NULL;
1730 }
1731
1732 return 0;
1733}
1734#else
1735static inline int acpi_video_device_add_fs(struct acpi_device *device)
1736{
1737 return 0;
1738}
1739static inline int acpi_video_device_remove_fs(struct acpi_device *device)
1740{
1741 return 0;
1742}
1743static inline int acpi_video_bus_add_fs(struct acpi_device *device)
1744{
1745 return 0;
1746}
1747static inline int acpi_video_bus_remove_fs(struct acpi_device *device)
1748{
1749 return 0;
1750}
1751#endif /* CONFIG_ACPI_PROCFS */
1752
1753/* --------------------------------------------------------------------------
1754 Driver Interface 1007 Driver Interface
1755 -------------------------------------------------------------------------- */ 1008 -------------------------------------------------------------------------- */
1756 1009
@@ -1877,8 +1130,6 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1877 list_add_tail(&data->entry, &video->video_device_list); 1130 list_add_tail(&data->entry, &video->video_device_list);
1878 mutex_unlock(&video->device_list_lock); 1131 mutex_unlock(&video->device_list_lock);
1879 1132
1880 acpi_video_device_add_fs(device);
1881
1882 return 0; 1133 return 0;
1883 } 1134 }
1884 1135
@@ -2181,8 +1432,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
2181 if (!device || !device->video) 1432 if (!device || !device->video)
2182 return -ENOENT; 1433 return -ENOENT;
2183 1434
2184 acpi_video_device_remove_fs(device->dev);
2185
2186 status = acpi_remove_notify_handler(device->dev->handle, 1435 status = acpi_remove_notify_handler(device->dev->handle,
2187 ACPI_DEVICE_NOTIFY, 1436 ACPI_DEVICE_NOTIFY,
2188 acpi_video_device_notify); 1437 acpi_video_device_notify);
@@ -2466,10 +1715,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
2466 if (error) 1715 if (error)
2467 goto err_free_video; 1716 goto err_free_video;
2468 1717
2469 error = acpi_video_bus_add_fs(device);
2470 if (error)
2471 goto err_free_video;
2472
2473 mutex_init(&video->device_list_lock); 1718 mutex_init(&video->device_list_lock);
2474 INIT_LIST_HEAD(&video->video_device_list); 1719 INIT_LIST_HEAD(&video->video_device_list);
2475 1720
@@ -2522,7 +1767,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
2522 acpi_video_bus_stop_devices(video); 1767 acpi_video_bus_stop_devices(video);
2523 acpi_video_bus_put_devices(video); 1768 acpi_video_bus_put_devices(video);
2524 kfree(video->attached_array); 1769 kfree(video->attached_array);
2525 acpi_video_bus_remove_fs(device);
2526 err_free_video: 1770 err_free_video:
2527 kfree(video); 1771 kfree(video);
2528 device->driver_data = NULL; 1772 device->driver_data = NULL;
@@ -2544,7 +1788,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
2544 1788
2545 acpi_video_bus_stop_devices(video); 1789 acpi_video_bus_stop_devices(video);
2546 acpi_video_bus_put_devices(video); 1790 acpi_video_bus_put_devices(video);
2547 acpi_video_bus_remove_fs(device);
2548 1791
2549 input_unregister_device(video->input); 1792 input_unregister_device(video->input);
2550 kfree(video->attached_array); 1793 kfree(video->attached_array);
@@ -2584,17 +1827,9 @@ int acpi_video_register(void)
2584 return 0; 1827 return 0;
2585 } 1828 }
2586 1829
2587#ifdef CONFIG_ACPI_PROCFS
2588 acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
2589 if (!acpi_video_dir)
2590 return -ENODEV;
2591#endif
2592
2593 result = acpi_bus_register_driver(&acpi_video_bus); 1830 result = acpi_bus_register_driver(&acpi_video_bus);
2594 if (result < 0) { 1831 if (result < 0)
2595 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2596 return -ENODEV; 1832 return -ENODEV;
2597 }
2598 1833
2599 /* 1834 /*
2600 * When the acpi_video_bus is loaded successfully, increase 1835 * When the acpi_video_bus is loaded successfully, increase
@@ -2617,10 +1852,6 @@ void acpi_video_unregister(void)
2617 } 1852 }
2618 acpi_bus_unregister_driver(&acpi_video_bus); 1853 acpi_bus_unregister_driver(&acpi_video_bus);
2619 1854
2620#ifdef CONFIG_ACPI_PROCFS
2621 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2622#endif
2623
2624 register_count = 0; 1855 register_count = 0;
2625 1856
2626 return; 1857 return;