diff options
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r-- | drivers/acpi/video.c | 77 |
1 files changed, 68 insertions, 9 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 810cca90ca7f..8851315ce858 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -76,6 +76,7 @@ MODULE_LICENSE("GPL"); | |||
76 | static int brightness_switch_enabled = 1; | 76 | static int brightness_switch_enabled = 1; |
77 | module_param(brightness_switch_enabled, bool, 0644); | 77 | module_param(brightness_switch_enabled, bool, 0644); |
78 | 78 | ||
79 | static int register_count = 0; | ||
79 | static int acpi_video_bus_add(struct acpi_device *device); | 80 | static int acpi_video_bus_add(struct acpi_device *device); |
80 | static int acpi_video_bus_remove(struct acpi_device *device, int type); | 81 | static int acpi_video_bus_remove(struct acpi_device *device, int type); |
81 | static int acpi_video_resume(struct acpi_device *device); | 82 | static int acpi_video_resume(struct acpi_device *device); |
@@ -570,6 +571,30 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
570 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"), | 571 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"), |
571 | }, | 572 | }, |
572 | }, | 573 | }, |
574 | { | ||
575 | .callback = video_set_bqc_offset, | ||
576 | .ident = "eMachines E510", | ||
577 | .matches = { | ||
578 | DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"), | ||
579 | DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"), | ||
580 | }, | ||
581 | }, | ||
582 | { | ||
583 | .callback = video_set_bqc_offset, | ||
584 | .ident = "Acer Aspire 5315", | ||
585 | .matches = { | ||
586 | DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), | ||
587 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), | ||
588 | }, | ||
589 | }, | ||
590 | { | ||
591 | .callback = video_set_bqc_offset, | ||
592 | .ident = "Acer Aspire 7720", | ||
593 | .matches = { | ||
594 | DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), | ||
595 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), | ||
596 | }, | ||
597 | }, | ||
573 | {} | 598 | {} |
574 | }; | 599 | }; |
575 | 600 | ||
@@ -960,6 +985,11 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
960 | device->backlight->props.max_brightness = device->brightness->count-3; | 985 | device->backlight->props.max_brightness = device->brightness->count-3; |
961 | kfree(name); | 986 | kfree(name); |
962 | 987 | ||
988 | result = sysfs_create_link(&device->backlight->dev.kobj, | ||
989 | &device->dev->dev.kobj, "device"); | ||
990 | if (result) | ||
991 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
992 | |||
963 | device->cdev = thermal_cooling_device_register("LCD", | 993 | device->cdev = thermal_cooling_device_register("LCD", |
964 | device->dev, &video_cooling_ops); | 994 | device->dev, &video_cooling_ops); |
965 | if (IS_ERR(device->cdev)) | 995 | if (IS_ERR(device->cdev)) |
@@ -1038,15 +1068,15 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
1038 | static int acpi_video_bus_check(struct acpi_video_bus *video) | 1068 | static int acpi_video_bus_check(struct acpi_video_bus *video) |
1039 | { | 1069 | { |
1040 | acpi_status status = -ENOENT; | 1070 | acpi_status status = -ENOENT; |
1041 | struct device *dev; | 1071 | struct pci_dev *dev; |
1042 | 1072 | ||
1043 | if (!video) | 1073 | if (!video) |
1044 | return -EINVAL; | 1074 | return -EINVAL; |
1045 | 1075 | ||
1046 | dev = acpi_get_physical_pci_device(video->device->handle); | 1076 | dev = acpi_get_pci_dev(video->device->handle); |
1047 | if (!dev) | 1077 | if (!dev) |
1048 | return -ENODEV; | 1078 | return -ENODEV; |
1049 | put_device(dev); | 1079 | pci_dev_put(dev); |
1050 | 1080 | ||
1051 | /* Since there is no HID, CID and so on for VGA driver, we have | 1081 | /* Since there is no HID, CID and so on for VGA driver, we have |
1052 | * to check well known required nodes. | 1082 | * to check well known required nodes. |
@@ -1974,6 +2004,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1974 | status = acpi_remove_notify_handler(device->dev->handle, | 2004 | status = acpi_remove_notify_handler(device->dev->handle, |
1975 | ACPI_DEVICE_NOTIFY, | 2005 | ACPI_DEVICE_NOTIFY, |
1976 | acpi_video_device_notify); | 2006 | acpi_video_device_notify); |
2007 | sysfs_remove_link(&device->backlight->dev.kobj, "device"); | ||
1977 | backlight_device_unregister(device->backlight); | 2008 | backlight_device_unregister(device->backlight); |
1978 | if (device->cdev) { | 2009 | if (device->cdev) { |
1979 | sysfs_remove_link(&device->dev->dev.kobj, | 2010 | sysfs_remove_link(&device->dev->dev.kobj, |
@@ -2302,6 +2333,13 @@ static int __init intel_opregion_present(void) | |||
2302 | int acpi_video_register(void) | 2333 | int acpi_video_register(void) |
2303 | { | 2334 | { |
2304 | int result = 0; | 2335 | int result = 0; |
2336 | if (register_count) { | ||
2337 | /* | ||
2338 | * if the function of acpi_video_register is already called, | ||
2339 | * don't register the acpi_vide_bus again and return no error. | ||
2340 | */ | ||
2341 | return 0; | ||
2342 | } | ||
2305 | 2343 | ||
2306 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); | 2344 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); |
2307 | if (!acpi_video_dir) | 2345 | if (!acpi_video_dir) |
@@ -2313,10 +2351,35 @@ int acpi_video_register(void) | |||
2313 | return -ENODEV; | 2351 | return -ENODEV; |
2314 | } | 2352 | } |
2315 | 2353 | ||
2354 | /* | ||
2355 | * When the acpi_video_bus is loaded successfully, increase | ||
2356 | * the counter reference. | ||
2357 | */ | ||
2358 | register_count = 1; | ||
2359 | |||
2316 | return 0; | 2360 | return 0; |
2317 | } | 2361 | } |
2318 | EXPORT_SYMBOL(acpi_video_register); | 2362 | EXPORT_SYMBOL(acpi_video_register); |
2319 | 2363 | ||
2364 | void acpi_video_unregister(void) | ||
2365 | { | ||
2366 | if (!register_count) { | ||
2367 | /* | ||
2368 | * If the acpi video bus is already unloaded, don't | ||
2369 | * unload it again and return directly. | ||
2370 | */ | ||
2371 | return; | ||
2372 | } | ||
2373 | acpi_bus_unregister_driver(&acpi_video_bus); | ||
2374 | |||
2375 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | ||
2376 | |||
2377 | register_count = 0; | ||
2378 | |||
2379 | return; | ||
2380 | } | ||
2381 | EXPORT_SYMBOL(acpi_video_unregister); | ||
2382 | |||
2320 | /* | 2383 | /* |
2321 | * This is kind of nasty. Hardware using Intel chipsets may require | 2384 | * This is kind of nasty. Hardware using Intel chipsets may require |
2322 | * the video opregion code to be run first in order to initialise | 2385 | * the video opregion code to be run first in order to initialise |
@@ -2334,16 +2397,12 @@ static int __init acpi_video_init(void) | |||
2334 | return acpi_video_register(); | 2397 | return acpi_video_register(); |
2335 | } | 2398 | } |
2336 | 2399 | ||
2337 | void __exit acpi_video_exit(void) | 2400 | static void __exit acpi_video_exit(void) |
2338 | { | 2401 | { |
2339 | 2402 | acpi_video_unregister(); | |
2340 | acpi_bus_unregister_driver(&acpi_video_bus); | ||
2341 | |||
2342 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | ||
2343 | 2403 | ||
2344 | return; | 2404 | return; |
2345 | } | 2405 | } |
2346 | EXPORT_SYMBOL(acpi_video_exit); | ||
2347 | 2406 | ||
2348 | module_init(acpi_video_init); | 2407 | module_init(acpi_video_init); |
2349 | module_exit(acpi_video_exit); | 2408 | module_exit(acpi_video_exit); |