aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-20 13:17:32 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-20 13:17:32 -0500
commita5527c6a586537c1af7ae6db30bb444ee4abdfe8 (patch)
treef0682de5c461c270f5f58b7304fd5ea5b5d6fb38 /drivers
parent4afffe5eabc4005674a1ef4f4c96f1ae9f4a979b (diff)
parent8f27489d1105c2386e6ed71c35e74e0e69603cbc (diff)
Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-backlight
* 'for-linus' of git://git.o-hand.com/linux-rpurdie-backlight: backlight: Remove bogus SYSFS dependency backlight: simplify corgi_bl locking backlight: Separate backlight properties from backlight ops pointers backlight: Clean up pmac_backlight handling backlight: Improve backlight selection for fbdev drivers backlight: Rework backlight/fb interaction simplifying, lots backlight: Remove unneeded backlight update_status calls backlight: Remove uneeded update_status call from chipsfb.c backlight/fbcon: Add FB_EVENT_CONBLANK backlight: Fix Kconfig entries backlight: Remove uneeded nvidia set_power calls backlight: Convert semaphore -> mutex backlight: Fix external uses of backlight internal semaphore backlight: Minor code cleanups for hp680_bl.c backlight: Minor code cleanups for corgi_bl.c backlight: Remove excessive (un)likelys backlight: Remove unneeded owner field backlight: Fix error handling backlight: Add Frontpath ProGear HX1050+ driver backlight: Add maintainer entry
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/asus_acpi.c7
-rw-r--r--drivers/acpi/ibm_acpi.c8
-rw-r--r--drivers/acpi/toshiba_acpi.c7
-rw-r--r--drivers/acpi/video.c36
-rw-r--r--drivers/macintosh/via-pmu-backlight.c33
-rw-r--r--drivers/misc/asus-laptop.c31
-rw-r--r--drivers/misc/msi-laptop.c10
-rw-r--r--drivers/misc/sony-laptop.c16
-rw-r--r--drivers/usb/misc/appledisplay.c18
-rw-r--r--drivers/video/Kconfig71
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/aty/aty128fb.c102
-rw-r--r--drivers/video/aty/atyfb_base.c100
-rw-r--r--drivers/video/aty/radeon_backlight.c59
-rw-r--r--drivers/video/aty/radeon_base.c3
-rw-r--r--drivers/video/backlight/Kconfig23
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/backlight.c123
-rw-r--r--drivers/video/backlight/corgi_bl.c54
-rw-r--r--drivers/video/backlight/hp680_bl.c50
-rw-r--r--drivers/video/backlight/lcd.c83
-rw-r--r--drivers/video/backlight/locomolcd.c13
-rw-r--r--drivers/video/backlight/progear_bl.c153
-rw-r--r--drivers/video/chipsfb.c26
-rw-r--r--drivers/video/console/fbcon.c7
-rw-r--r--drivers/video/fbsysfs.c14
-rw-r--r--drivers/video/nvidia/nv_backlight.c92
-rw-r--r--drivers/video/nvidia/nv_proto.h2
-rw-r--r--drivers/video/nvidia/nvidia.c5
-rw-r--r--drivers/video/riva/fbdev.c100
30 files changed, 532 insertions, 717 deletions
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 772299fb5f9d..b770deab968c 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -848,7 +848,7 @@ out:
848 848
849static int set_brightness_status(struct backlight_device *bd) 849static int set_brightness_status(struct backlight_device *bd)
850{ 850{
851 return set_brightness(bd->props->brightness); 851 return set_brightness(bd->props.brightness);
852} 852}
853 853
854static int 854static int
@@ -1352,11 +1352,9 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
1352 return 0; 1352 return 0;
1353} 1353}
1354 1354
1355static struct backlight_properties asus_backlight_data = { 1355static struct backlight_ops asus_backlight_data = {
1356 .owner = THIS_MODULE,
1357 .get_brightness = read_brightness, 1356 .get_brightness = read_brightness,
1358 .update_status = set_brightness_status, 1357 .update_status = set_brightness_status,
1359 .max_brightness = 15,
1360}; 1358};
1361 1359
1362static void __exit asus_acpi_exit(void) 1360static void __exit asus_acpi_exit(void)
@@ -1410,6 +1408,7 @@ static int __init asus_acpi_init(void)
1410 asus_backlight_device = NULL; 1408 asus_backlight_device = NULL;
1411 asus_acpi_exit(); 1409 asus_acpi_exit();
1412 } 1410 }
1411 asus_backlight_device->props.max_brightness = 15;
1413 1412
1414 return 0; 1413 return 0;
1415} 1414}
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 1a0ed3dc409c..4cc534e36e81 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1701,14 +1701,12 @@ static int brightness_write(char *buf)
1701 1701
1702static int brightness_update_status(struct backlight_device *bd) 1702static int brightness_update_status(struct backlight_device *bd)
1703{ 1703{
1704 return brightness_set(bd->props->brightness); 1704 return brightness_set(bd->props.brightness);
1705} 1705}
1706 1706
1707static struct backlight_properties ibm_backlight_data = { 1707static struct backlight_ops ibm_backlight_data = {
1708 .owner = THIS_MODULE,
1709 .get_brightness = brightness_get, 1708 .get_brightness = brightness_get,
1710 .update_status = brightness_update_status, 1709 .update_status = brightness_update_status,
1711 .max_brightness = 7,
1712}; 1710};
1713 1711
1714static int brightness_init(void) 1712static int brightness_init(void)
@@ -1720,6 +1718,8 @@ static int brightness_init(void)
1720 return PTR_ERR(ibm_backlight_device); 1718 return PTR_ERR(ibm_backlight_device);
1721 } 1719 }
1722 1720
1721 ibm_backlight_device->props.max_brightness = 7;
1722
1723 return 0; 1723 return 0;
1724} 1724}
1725 1725
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index faf8a5232d8e..3906d47b9783 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -315,7 +315,7 @@ static int set_lcd(int value)
315 315
316static int set_lcd_status(struct backlight_device *bd) 316static int set_lcd_status(struct backlight_device *bd)
317{ 317{
318 return set_lcd(bd->props->brightness); 318 return set_lcd(bd->props.brightness);
319} 319}
320 320
321static unsigned long write_lcd(const char *buffer, unsigned long count) 321static unsigned long write_lcd(const char *buffer, unsigned long count)
@@ -533,11 +533,9 @@ static acpi_status __exit remove_device(void)
533 return AE_OK; 533 return AE_OK;
534} 534}
535 535
536static struct backlight_properties toshiba_backlight_data = { 536static struct backlight_ops toshiba_backlight_data = {
537 .owner = THIS_MODULE,
538 .get_brightness = get_lcd, 537 .get_brightness = get_lcd,
539 .update_status = set_lcd_status, 538 .update_status = set_lcd_status,
540 .max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1,
541}; 539};
542 540
543static void __exit toshiba_acpi_exit(void) 541static void __exit toshiba_acpi_exit(void)
@@ -597,6 +595,7 @@ static int __init toshiba_acpi_init(void)
597 toshiba_backlight_device = NULL; 595 toshiba_backlight_device = NULL;
598 toshiba_acpi_exit(); 596 toshiba_acpi_exit();
599 } 597 }
598 toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
600 599
601 return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; 600 return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
602} 601}
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bf525cca3b63..0771b434feb2 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -169,7 +169,6 @@ struct acpi_video_device {
169 struct acpi_device *dev; 169 struct acpi_device *dev;
170 struct acpi_video_device_brightness *brightness; 170 struct acpi_video_device_brightness *brightness;
171 struct backlight_device *backlight; 171 struct backlight_device *backlight;
172 struct backlight_properties *data;
173}; 172};
174 173
175/* bus */ 174/* bus */
@@ -286,13 +285,18 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
286 285
287static int acpi_video_set_brightness(struct backlight_device *bd) 286static int acpi_video_set_brightness(struct backlight_device *bd)
288{ 287{
289 int request_level = bd->props->brightness; 288 int request_level = bd->props.brightness;
290 struct acpi_video_device *vd = 289 struct acpi_video_device *vd =
291 (struct acpi_video_device *)class_get_devdata(&bd->class_dev); 290 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
292 acpi_video_device_lcd_set_level(vd, request_level); 291 acpi_video_device_lcd_set_level(vd, request_level);
293 return 0; 292 return 0;
294} 293}
295 294
295static struct backlight_ops acpi_backlight_ops = {
296 .get_brightness = acpi_video_get_brightness,
297 .update_status = acpi_video_set_brightness,
298};
299
296/* -------------------------------------------------------------------------- 300/* --------------------------------------------------------------------------
297 Video Management 301 Video Management
298 -------------------------------------------------------------------------- */ 302 -------------------------------------------------------------------------- */
@@ -608,31 +612,18 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
608 unsigned long tmp; 612 unsigned long tmp;
609 static int count = 0; 613 static int count = 0;
610 char *name; 614 char *name;
611 struct backlight_properties *acpi_video_data;
612
613 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 615 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
614 if (!name) 616 if (!name)
615 return; 617 return;
616 618
617 acpi_video_data = kzalloc(
618 sizeof(struct backlight_properties),
619 GFP_KERNEL);
620 if (!acpi_video_data){
621 kfree(name);
622 return;
623 }
624 acpi_video_data->owner = THIS_MODULE;
625 acpi_video_data->get_brightness =
626 acpi_video_get_brightness;
627 acpi_video_data->update_status =
628 acpi_video_set_brightness;
629 sprintf(name, "acpi_video%d", count++); 619 sprintf(name, "acpi_video%d", count++);
630 device->data = acpi_video_data;
631 acpi_video_data->max_brightness = max_level;
632 acpi_video_device_lcd_get_level_current(device, &tmp); 620 acpi_video_device_lcd_get_level_current(device, &tmp);
633 acpi_video_data->brightness = (int)tmp;
634 device->backlight = backlight_device_register(name, 621 device->backlight = backlight_device_register(name,
635 NULL, device, acpi_video_data); 622 NULL, device, &acpi_backlight_ops);
623 device->backlight->props.max_brightness = max_level;
624 device->backlight->props.brightness = (int)tmp;
625 backlight_update_status(device->backlight);
626
636 kfree(name); 627 kfree(name);
637 } 628 }
638 return; 629 return;
@@ -1677,10 +1668,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1677 status = acpi_remove_notify_handler(device->dev->handle, 1668 status = acpi_remove_notify_handler(device->dev->handle,
1678 ACPI_DEVICE_NOTIFY, 1669 ACPI_DEVICE_NOTIFY,
1679 acpi_video_device_notify); 1670 acpi_video_device_notify);
1680 if (device->backlight){ 1671 backlight_device_unregister(device->backlight);
1681 backlight_device_unregister(device->backlight);
1682 kfree(device->data);
1683 }
1684 return 0; 1672 return 0;
1685} 1673}
1686 1674
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index 801a974342f9..7e27071746e4 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -15,7 +15,7 @@
15 15
16#define MAX_PMU_LEVEL 0xFF 16#define MAX_PMU_LEVEL 0xFF
17 17
18static struct backlight_properties pmu_backlight_data; 18static struct backlight_ops pmu_backlight_data;
19static DEFINE_SPINLOCK(pmu_backlight_lock); 19static DEFINE_SPINLOCK(pmu_backlight_lock);
20static int sleeping; 20static int sleeping;
21static u8 bl_curve[FB_BACKLIGHT_LEVELS]; 21static u8 bl_curve[FB_BACKLIGHT_LEVELS];
@@ -72,7 +72,7 @@ static int pmu_backlight_update_status(struct backlight_device *bd)
72{ 72{
73 struct adb_request req; 73 struct adb_request req;
74 unsigned long flags; 74 unsigned long flags;
75 int level = bd->props->brightness; 75 int level = bd->props.brightness;
76 76
77 spin_lock_irqsave(&pmu_backlight_lock, flags); 77 spin_lock_irqsave(&pmu_backlight_lock, flags);
78 78
@@ -80,8 +80,8 @@ static int pmu_backlight_update_status(struct backlight_device *bd)
80 if (sleeping) 80 if (sleeping)
81 goto out; 81 goto out;
82 82
83 if (bd->props->power != FB_BLANK_UNBLANK || 83 if (bd->props.power != FB_BLANK_UNBLANK ||
84 bd->props->fb_blank != FB_BLANK_UNBLANK) 84 bd->props.fb_blank != FB_BLANK_UNBLANK)
85 level = 0; 85 level = 0;
86 86
87 if (level > 0) { 87 if (level > 0) {
@@ -107,14 +107,13 @@ out:
107 107
108static int pmu_backlight_get_brightness(struct backlight_device *bd) 108static int pmu_backlight_get_brightness(struct backlight_device *bd)
109{ 109{
110 return bd->props->brightness; 110 return bd->props.brightness;
111} 111}
112 112
113static struct backlight_properties pmu_backlight_data = { 113static struct backlight_ops pmu_backlight_data = {
114 .owner = THIS_MODULE,
115 .get_brightness = pmu_backlight_get_brightness, 114 .get_brightness = pmu_backlight_get_brightness,
116 .update_status = pmu_backlight_update_status, 115 .update_status = pmu_backlight_update_status,
117 .max_brightness = (FB_BACKLIGHT_LEVELS - 1), 116
118}; 117};
119 118
120#ifdef CONFIG_PM 119#ifdef CONFIG_PM
@@ -152,9 +151,10 @@ void __init pmu_backlight_init()
152 printk("pmubl: Backlight registration failed\n"); 151 printk("pmubl: Backlight registration failed\n");
153 goto error; 152 goto error;
154 } 153 }
154 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
155 pmu_backlight_init_curve(0x7F, 0x46, 0x0E); 155 pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
156 156
157 level = pmu_backlight_data.max_brightness; 157 level = bd->props.max_brightness;
158 158
159 if (autosave) { 159 if (autosave) {
160 /* read autosaved value if available */ 160 /* read autosaved value if available */
@@ -164,19 +164,12 @@ void __init pmu_backlight_init()
164 164
165 level = pmu_backlight_curve_lookup( 165 level = pmu_backlight_curve_lookup(
166 (req.reply[0] >> 4) * 166 (req.reply[0] >> 4) *
167 pmu_backlight_data.max_brightness / 15); 167 bd->props.max_brightness / 15);
168 } 168 }
169 169
170 down(&bd->sem); 170 bd->props.brightness = level;
171 bd->props->brightness = level; 171 bd->props.power = FB_BLANK_UNBLANK;
172 bd->props->power = FB_BLANK_UNBLANK; 172 backlight_update_status(bd);
173 bd->props->update_status(bd);
174 up(&bd->sem);
175
176 mutex_lock(&pmac_backlight_mutex);
177 if (!pmac_backlight)
178 pmac_backlight = bd;
179 mutex_unlock(&pmac_backlight_mutex);
180 173
181 printk("pmubl: Backlight initialized (%s)\n", name); 174 printk("pmubl: Backlight initialized (%s)\n", name);
182 175
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index e4e2b707a353..295e931c0dfb 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -195,11 +195,9 @@ static struct backlight_device *asus_backlight_device;
195 */ 195 */
196static int read_brightness(struct backlight_device *bd); 196static int read_brightness(struct backlight_device *bd);
197static int update_bl_status(struct backlight_device *bd); 197static int update_bl_status(struct backlight_device *bd);
198static struct backlight_properties asusbl_data = { 198static struct backlight_ops asusbl_ops = {
199 .owner = THIS_MODULE,
200 .get_brightness = read_brightness, 199 .get_brightness = read_brightness,
201 .update_status = update_bl_status, 200 .update_status = update_bl_status,
202 .max_brightness = 15,
203}; 201};
204 202
205/* These functions actually update the LED's, and are called from a 203/* These functions actually update the LED's, and are called from a
@@ -349,13 +347,8 @@ static void lcd_blank(int blank)
349 struct backlight_device *bd = asus_backlight_device; 347 struct backlight_device *bd = asus_backlight_device;
350 348
351 if (bd) { 349 if (bd) {
352 down(&bd->sem); 350 bd->props.power = blank;
353 if (likely(bd->props)) { 351 backlight_update_status(bd);
354 bd->props->power = blank;
355 if (likely(bd->props->update_status))
356 bd->props->update_status(bd);
357 }
358 up(&bd->sem);
359 } 352 }
360} 353}
361 354
@@ -387,13 +380,13 @@ static int set_brightness(struct backlight_device *bd, int value)
387static int update_bl_status(struct backlight_device *bd) 380static int update_bl_status(struct backlight_device *bd)
388{ 381{
389 int rv; 382 int rv;
390 int value = bd->props->brightness; 383 int value = bd->props.brightness;
391 384
392 rv = set_brightness(bd, value); 385 rv = set_brightness(bd, value);
393 if (rv) 386 if (rv)
394 return rv; 387 return rv;
395 388
396 value = (bd->props->power == FB_BLANK_UNBLANK) ? 1 : 0; 389 value = (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0;
397 return set_lcd_state(value); 390 return set_lcd_state(value);
398} 391}
399 392
@@ -1019,7 +1012,7 @@ static int asus_backlight_init(struct device *dev)
1019 1012
1020 if (brightness_set_handle && lcd_switch_handle) { 1013 if (brightness_set_handle && lcd_switch_handle) {
1021 bd = backlight_device_register(ASUS_HOTK_FILE, dev, 1014 bd = backlight_device_register(ASUS_HOTK_FILE, dev,
1022 NULL, &asusbl_data); 1015 NULL, &asusbl_ops);
1023 if (IS_ERR(bd)) { 1016 if (IS_ERR(bd)) {
1024 printk(ASUS_ERR 1017 printk(ASUS_ERR
1025 "Could not register asus backlight device\n"); 1018 "Could not register asus backlight device\n");
@@ -1029,14 +1022,10 @@ static int asus_backlight_init(struct device *dev)
1029 1022
1030 asus_backlight_device = bd; 1023 asus_backlight_device = bd;
1031 1024
1032 down(&bd->sem); 1025 bd->props.max_brightness = 15;
1033 if (likely(bd->props)) { 1026 bd->props.brightness = read_brightness(NULL);
1034 bd->props->brightness = read_brightness(NULL); 1027 bd->props.power = FB_BLANK_UNBLANK;
1035 bd->props->power = FB_BLANK_UNBLANK; 1028 backlight_update_status(bd);
1036 if (likely(bd->props->update_status))
1037 bd->props->update_status(bd);
1038 }
1039 up(&bd->sem);
1040 } 1029 }
1041 return 0; 1030 return 0;
1042} 1031}
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
index 8e5e07e4c1cf..68c4b58525ba 100644
--- a/drivers/misc/msi-laptop.c
+++ b/drivers/misc/msi-laptop.c
@@ -157,14 +157,12 @@ static int bl_get_brightness(struct backlight_device *b)
157 157
158static int bl_update_status(struct backlight_device *b) 158static int bl_update_status(struct backlight_device *b)
159{ 159{
160 return set_lcd_level(b->props->brightness); 160 return set_lcd_level(b->props.brightness);
161} 161}
162 162
163static struct backlight_properties msibl_props = { 163static struct backlight_ops msibl_ops = {
164 .owner = THIS_MODULE,
165 .get_brightness = bl_get_brightness, 164 .get_brightness = bl_get_brightness,
166 .update_status = bl_update_status, 165 .update_status = bl_update_status,
167 .max_brightness = MSI_LCD_LEVEL_MAX-1,
168}; 166};
169 167
170static struct backlight_device *msibl_device; 168static struct backlight_device *msibl_device;
@@ -318,10 +316,12 @@ static int __init msi_init(void)
318 /* Register backlight stuff */ 316 /* Register backlight stuff */
319 317
320 msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL, 318 msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL,
321 &msibl_props); 319 &msibl_ops);
322 if (IS_ERR(msibl_device)) 320 if (IS_ERR(msibl_device))
323 return PTR_ERR(msibl_device); 321 return PTR_ERR(msibl_device);
324 322
323 msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1,
324
325 ret = platform_driver_register(&msipf_driver); 325 ret = platform_driver_register(&msipf_driver);
326 if (ret) 326 if (ret)
327 goto fail_backlight; 327 goto fail_backlight;
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index cabbed0015e4..2ebe240dd537 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -384,7 +384,7 @@ static void sony_snc_pf_remove(void)
384static int sony_backlight_update_status(struct backlight_device *bd) 384static int sony_backlight_update_status(struct backlight_device *bd)
385{ 385{
386 return acpi_callsetfunc(sony_acpi_handle, "SBRT", 386 return acpi_callsetfunc(sony_acpi_handle, "SBRT",
387 bd->props->brightness + 1, NULL); 387 bd->props.brightness + 1, NULL);
388} 388}
389 389
390static int sony_backlight_get_brightness(struct backlight_device *bd) 390static int sony_backlight_get_brightness(struct backlight_device *bd)
@@ -398,11 +398,9 @@ static int sony_backlight_get_brightness(struct backlight_device *bd)
398} 398}
399 399
400static struct backlight_device *sony_backlight_device; 400static struct backlight_device *sony_backlight_device;
401static struct backlight_properties sony_backlight_properties = { 401static struct backlight_ops sony_backlight_ops = {
402 .owner = THIS_MODULE,
403 .update_status = sony_backlight_update_status, 402 .update_status = sony_backlight_update_status,
404 .get_brightness = sony_backlight_get_brightness, 403 .get_brightness = sony_backlight_get_brightness,
405 .max_brightness = SONY_MAX_BRIGHTNESS - 1,
406}; 404};
407 405
408/* 406/*
@@ -484,15 +482,19 @@ static int sony_acpi_add(struct acpi_device *device)
484 if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) { 482 if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) {
485 sony_backlight_device = backlight_device_register("sony", NULL, 483 sony_backlight_device = backlight_device_register("sony", NULL,
486 NULL, 484 NULL,
487 &sony_backlight_properties); 485 &sony_backlight_ops);
488 486
489 if (IS_ERR(sony_backlight_device)) { 487 if (IS_ERR(sony_backlight_device)) {
490 printk(LOG_PFX "unable to register backlight device\n"); 488 printk(LOG_PFX "unable to register backlight device\n");
491 sony_backlight_device = NULL; 489 sony_backlight_device = NULL;
492 } else 490 } else {
493 sony_backlight_properties.brightness = 491 sony_backlight_device->props.brightness =
494 sony_backlight_get_brightness 492 sony_backlight_get_brightness
495 (sony_backlight_device); 493 (sony_backlight_device);
494 sony_backlight_device->props.max_brightness =
495 SONY_MAX_BRIGHTNESS - 1;
496 }
497
496 } 498 }
497 499
498 if (sony_snc_pf_add()) 500 if (sony_snc_pf_add())
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index e573c8ba9785..cf70c16f0e3f 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -141,7 +141,7 @@ static int appledisplay_bl_update_status(struct backlight_device *bd)
141 int retval; 141 int retval;
142 142
143 pdata->msgdata[0] = 0x10; 143 pdata->msgdata[0] = 0x10;
144 pdata->msgdata[1] = bd->props->brightness; 144 pdata->msgdata[1] = bd->props.brightness;
145 145
146 retval = usb_control_msg( 146 retval = usb_control_msg(
147 pdata->udev, 147 pdata->udev,
@@ -177,11 +177,9 @@ static int appledisplay_bl_get_brightness(struct backlight_device *bd)
177 return pdata->msgdata[1]; 177 return pdata->msgdata[1];
178} 178}
179 179
180static struct backlight_properties appledisplay_bl_data = { 180static struct backlight_ops appledisplay_bl_data = {
181 .owner = THIS_MODULE,
182 .get_brightness = appledisplay_bl_get_brightness, 181 .get_brightness = appledisplay_bl_get_brightness,
183 .update_status = appledisplay_bl_update_status, 182 .update_status = appledisplay_bl_update_status,
184 .max_brightness = 0xFF
185}; 183};
186 184
187static void appledisplay_work(struct work_struct *work) 185static void appledisplay_work(struct work_struct *work)
@@ -190,11 +188,9 @@ static void appledisplay_work(struct work_struct *work)
190 container_of(work, struct appledisplay, work.work); 188 container_of(work, struct appledisplay, work.work);
191 int retval; 189 int retval;
192 190
193 up(&pdata->bd->sem);
194 retval = appledisplay_bl_get_brightness(pdata->bd); 191 retval = appledisplay_bl_get_brightness(pdata->bd);
195 if (retval >= 0) 192 if (retval >= 0)
196 pdata->bd->props->brightness = retval; 193 pdata->bd->props.brightness = retval;
197 down(&pdata->bd->sem);
198 194
199 /* Poll again in about 125ms if there's still a button pressed */ 195 /* Poll again in about 125ms if there's still a button pressed */
200 if (pdata->button_pressed) 196 if (pdata->button_pressed)
@@ -288,10 +284,10 @@ static int appledisplay_probe(struct usb_interface *iface,
288 goto error; 284 goto error;
289 } 285 }
290 286
287 pdata->bd->props.max_brightness = 0xff;
288
291 /* Try to get brightness */ 289 /* Try to get brightness */
292 up(&pdata->bd->sem);
293 brightness = appledisplay_bl_get_brightness(pdata->bd); 290 brightness = appledisplay_bl_get_brightness(pdata->bd);
294 down(&pdata->bd->sem);
295 291
296 if (brightness < 0) { 292 if (brightness < 0) {
297 retval = brightness; 293 retval = brightness;
@@ -300,9 +296,7 @@ static int appledisplay_probe(struct usb_interface *iface,
300 } 296 }
301 297
302 /* Set brightness in backlight device */ 298 /* Set brightness in backlight device */
303 up(&pdata->bd->sem); 299 pdata->bd->props.brightness = brightness;
304 pdata->bd->props->brightness = brightness;
305 down(&pdata->bd->sem);
306 300
307 /* save our data pointer in the interface device */ 301 /* save our data pointer in the interface device */
308 usb_set_intfdata(iface, pdata); 302 usb_set_intfdata(iface, pdata);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 8874cf2fd279..f8bc43c1e7a7 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -4,20 +4,7 @@
4 4
5menu "Graphics support" 5menu "Graphics support"
6 6
7config FIRMWARE_EDID 7source "drivers/video/backlight/Kconfig"
8 bool "Enable firmware EDID"
9 default y
10 ---help---
11 This enables access to the EDID transferred from the firmware.
12 On the i386, this is from the Video BIOS. Enable this if DDC/I2C
13 transfers do not work for your driver and if you are using
14 nvidiafb, i810fb or savagefb.
15
16 In general, choosing Y for this option is safe. If you
17 experience extremely long delays while booting before you get
18 something on your display, try setting this to N. Matrox cards in
19 combination with certain motherboards and monitors are known to
20 suffer from this problem.
21 8
22config FB 9config FB
23 tristate "Support for frame buffer devices" 10 tristate "Support for frame buffer devices"
@@ -53,9 +40,27 @@ config FB
53 (e.g. an accelerated X server) and that are not frame buffer 40 (e.g. an accelerated X server) and that are not frame buffer
54 device-aware may cause unexpected results. If unsure, say N. 41 device-aware may cause unexpected results. If unsure, say N.
55 42
43config FIRMWARE_EDID
44 bool "Enable firmware EDID"
45 depends on FB
46 default n
47 ---help---
48 This enables access to the EDID transferred from the firmware.
49 On the i386, this is from the Video BIOS. Enable this if DDC/I2C
50 transfers do not work for your driver and if you are using
51 nvidiafb, i810fb or savagefb.
52
53 In general, choosing Y for this option is safe. If you
54 experience extremely long delays while booting before you get
55 something on your display, try setting this to N. Matrox cards in
56 combination with certain motherboards and monitors are known to
57 suffer from this problem.
58
56config FB_DDC 59config FB_DDC
57 tristate 60 tristate
58 depends on FB && I2C && I2C_ALGOBIT 61 depends on FB
62 select I2C_ALGOBIT
63 select I2C
59 default n 64 default n
60 65
61config FB_CFB_FILLRECT 66config FB_CFB_FILLRECT
@@ -134,6 +139,9 @@ config FB_TILEBLITTING
134 This is particularly important to one driver, matroxfb. If 139 This is particularly important to one driver, matroxfb. If
135 unsure, say N. 140 unsure, say N.
136 141
142comment "Frambuffer hardware drivers"
143 depends on FB
144
137config FB_CIRRUS 145config FB_CIRRUS
138 tristate "Cirrus Logic support" 146 tristate "Cirrus Logic support"
139 depends on FB && (ZORRO || PCI) 147 depends on FB && (ZORRO || PCI)
@@ -671,6 +679,7 @@ config FB_NVIDIA
671 depends on FB && PCI 679 depends on FB && PCI
672 select I2C_ALGOBIT if FB_NVIDIA_I2C 680 select I2C_ALGOBIT if FB_NVIDIA_I2C
673 select I2C if FB_NVIDIA_I2C 681 select I2C if FB_NVIDIA_I2C
682 select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT
674 select FB_MODE_HELPERS 683 select FB_MODE_HELPERS
675 select FB_CFB_FILLRECT 684 select FB_CFB_FILLRECT
676 select FB_CFB_COPYAREA 685 select FB_CFB_COPYAREA
@@ -699,8 +708,7 @@ config FB_NVIDIA_I2C
699 708
700config FB_NVIDIA_BACKLIGHT 709config FB_NVIDIA_BACKLIGHT
701 bool "Support for backlight control" 710 bool "Support for backlight control"
702 depends on FB_NVIDIA && PMAC_BACKLIGHT 711 depends on FB_NVIDIA
703 select FB_BACKLIGHT
704 default y 712 default y
705 help 713 help
706 Say Y here if you want to control the backlight of your display. 714 Say Y here if you want to control the backlight of your display.
@@ -708,9 +716,8 @@ config FB_NVIDIA_BACKLIGHT
708config FB_RIVA 716config FB_RIVA
709 tristate "nVidia Riva support" 717 tristate "nVidia Riva support"
710 depends on FB && PCI 718 depends on FB && PCI
711 select I2C_ALGOBIT if FB_RIVA_I2C
712 select I2C if FB_RIVA_I2C
713 select FB_DDC if FB_RIVA_I2C 719 select FB_DDC if FB_RIVA_I2C
720 select FB_BACKLIGHT if FB_RIVA_BACKLIGHT
714 select FB_MODE_HELPERS 721 select FB_MODE_HELPERS
715 select FB_CFB_FILLRECT 722 select FB_CFB_FILLRECT
716 select FB_CFB_COPYAREA 723 select FB_CFB_COPYAREA
@@ -747,8 +754,7 @@ config FB_RIVA_DEBUG
747 754
748config FB_RIVA_BACKLIGHT 755config FB_RIVA_BACKLIGHT
749 bool "Support for backlight control" 756 bool "Support for backlight control"
750 depends on FB_RIVA && PMAC_BACKLIGHT 757 depends on FB_RIVA
751 select FB_BACKLIGHT
752 default y 758 default y
753 help 759 help
754 Say Y here if you want to control the backlight of your display. 760 Say Y here if you want to control the backlight of your display.
@@ -798,8 +804,6 @@ config FB_I810_GTF
798config FB_I810_I2C 804config FB_I810_I2C
799 bool "Enable DDC Support" 805 bool "Enable DDC Support"
800 depends on FB_I810 && FB_I810_GTF 806 depends on FB_I810 && FB_I810_GTF
801 select I2C
802 select I2C_ALGOBIT
803 select FB_DDC 807 select FB_DDC
804 help 808 help
805 809
@@ -989,9 +993,8 @@ config FB_MATROX_MULTIHEAD
989config FB_RADEON 993config FB_RADEON
990 tristate "ATI Radeon display support" 994 tristate "ATI Radeon display support"
991 depends on FB && PCI 995 depends on FB && PCI
992 select I2C_ALGOBIT if FB_RADEON_I2C
993 select I2C if FB_RADEON_I2C
994 select FB_DDC if FB_RADEON_I2C 996 select FB_DDC if FB_RADEON_I2C
997 select FB_BACKLIGHT if FB_RADEON_BACKLIGHT
995 select FB_MODE_HELPERS 998 select FB_MODE_HELPERS
996 select FB_CFB_FILLRECT 999 select FB_CFB_FILLRECT
997 select FB_CFB_COPYAREA 1000 select FB_CFB_COPYAREA
@@ -1021,8 +1024,7 @@ config FB_RADEON_I2C
1021 1024
1022config FB_RADEON_BACKLIGHT 1025config FB_RADEON_BACKLIGHT
1023 bool "Support for backlight control" 1026 bool "Support for backlight control"
1024 depends on FB_RADEON && PMAC_BACKLIGHT 1027 depends on FB_RADEON
1025 select FB_BACKLIGHT
1026 default y 1028 default y
1027 help 1029 help
1028 Say Y here if you want to control the backlight of your display. 1030 Say Y here if you want to control the backlight of your display.
@@ -1042,6 +1044,7 @@ config FB_ATY128
1042 select FB_CFB_FILLRECT 1044 select FB_CFB_FILLRECT
1043 select FB_CFB_COPYAREA 1045 select FB_CFB_COPYAREA
1044 select FB_CFB_IMAGEBLIT 1046 select FB_CFB_IMAGEBLIT
1047 select FB_BACKLIGHT if FB_ATY128_BACKLIGHT
1045 select FB_MACMODES if PPC_PMAC 1048 select FB_MACMODES if PPC_PMAC
1046 help 1049 help
1047 This driver supports graphics boards with the ATI Rage128 chips. 1050 This driver supports graphics boards with the ATI Rage128 chips.
@@ -1053,8 +1056,7 @@ config FB_ATY128
1053 1056
1054config FB_ATY128_BACKLIGHT 1057config FB_ATY128_BACKLIGHT
1055 bool "Support for backlight control" 1058 bool "Support for backlight control"
1056 depends on FB_ATY128 && PMAC_BACKLIGHT 1059 depends on FB_ATY128
1057 select FB_BACKLIGHT
1058 default y 1060 default y
1059 help 1061 help
1060 Say Y here if you want to control the backlight of your display. 1062 Say Y here if you want to control the backlight of your display.
@@ -1065,6 +1067,7 @@ config FB_ATY
1065 select FB_CFB_FILLRECT 1067 select FB_CFB_FILLRECT
1066 select FB_CFB_COPYAREA 1068 select FB_CFB_COPYAREA
1067 select FB_CFB_IMAGEBLIT 1069 select FB_CFB_IMAGEBLIT
1070 select FB_BACKLIGHT if FB_ATY_BACKLIGHT
1068 select FB_MACMODES if PPC 1071 select FB_MACMODES if PPC
1069 help 1072 help
1070 This driver supports graphics boards with the ATI Mach64 chips. 1073 This driver supports graphics boards with the ATI Mach64 chips.
@@ -1103,8 +1106,7 @@ config FB_ATY_GX
1103 1106
1104config FB_ATY_BACKLIGHT 1107config FB_ATY_BACKLIGHT
1105 bool "Support for backlight control" 1108 bool "Support for backlight control"
1106 depends on FB_ATY && PMAC_BACKLIGHT 1109 depends on FB_ATY
1107 select FB_BACKLIGHT
1108 default y 1110 default y
1109 help 1111 help
1110 Say Y here if you want to control the backlight of your display. 1112 Say Y here if you want to control the backlight of your display.
@@ -1123,8 +1125,6 @@ config FB_S3
1123config FB_SAVAGE 1125config FB_SAVAGE
1124 tristate "S3 Savage support" 1126 tristate "S3 Savage support"
1125 depends on FB && PCI && EXPERIMENTAL 1127 depends on FB && PCI && EXPERIMENTAL
1126 select I2C_ALGOBIT if FB_SAVAGE_I2C
1127 select I2C if FB_SAVAGE_I2C
1128 select FB_DDC if FB_SAVAGE_I2C 1128 select FB_DDC if FB_SAVAGE_I2C
1129 select FB_MODE_HELPERS 1129 select FB_MODE_HELPERS
1130 select FB_CFB_FILLRECT 1130 select FB_CFB_FILLRECT
@@ -1639,6 +1639,7 @@ config FB_VIRTUAL
1639 the vfb_enable=1 option. 1639 the vfb_enable=1 option.
1640 1640
1641 If unsure, say N. 1641 If unsure, say N.
1642
1642if VT 1643if VT
1643 source "drivers/video/console/Kconfig" 1644 source "drivers/video/console/Kconfig"
1644endif 1645endif
@@ -1647,9 +1648,5 @@ if FB || SGI_NEWPORT_CONSOLE
1647 source "drivers/video/logo/Kconfig" 1648 source "drivers/video/logo/Kconfig"
1648endif 1649endif
1649 1650
1650if SYSFS
1651 source "drivers/video/backlight/Kconfig"
1652endif
1653
1654endmenu 1651endmenu
1655 1652
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 6801edff36d9..1b79a6f13f0c 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -12,7 +12,7 @@ fb-objs := $(fb-y)
12 12
13obj-$(CONFIG_VT) += console/ 13obj-$(CONFIG_VT) += console/
14obj-$(CONFIG_LOGO) += logo/ 14obj-$(CONFIG_LOGO) += logo/
15obj-$(CONFIG_SYSFS) += backlight/ 15obj-y += backlight/
16 16
17obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o 17obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
18obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o 18obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 2e976ffcde0f..8726c3669713 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1695,9 +1695,6 @@ static int __devinit aty128fb_setup(char *options)
1695#ifdef CONFIG_FB_ATY128_BACKLIGHT 1695#ifdef CONFIG_FB_ATY128_BACKLIGHT
1696#define MAX_LEVEL 0xFF 1696#define MAX_LEVEL 0xFF
1697 1697
1698static struct backlight_properties aty128_bl_data;
1699
1700/* Call with fb_info->bl_mutex held */
1701static int aty128_bl_get_level_brightness(struct aty128fb_par *par, 1698static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
1702 int level) 1699 int level)
1703{ 1700{
@@ -1705,6 +1702,7 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
1705 int atylevel; 1702 int atylevel;
1706 1703
1707 /* Get and convert the value */ 1704 /* Get and convert the value */
1705 /* No locking of bl_curve since we read a single value */
1708 atylevel = MAX_LEVEL - 1706 atylevel = MAX_LEVEL -
1709 (info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL); 1707 (info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL);
1710 1708
@@ -1724,19 +1722,18 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
1724/* That one prevents proper CRT output with LCD off */ 1722/* That one prevents proper CRT output with LCD off */
1725#undef BACKLIGHT_DAC_OFF 1723#undef BACKLIGHT_DAC_OFF
1726 1724
1727/* Call with fb_info->bl_mutex held */ 1725static int aty128_bl_update_status(struct backlight_device *bd)
1728static int __aty128_bl_update_status(struct backlight_device *bd)
1729{ 1726{
1730 struct aty128fb_par *par = class_get_devdata(&bd->class_dev); 1727 struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
1731 unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); 1728 unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
1732 int level; 1729 int level;
1733 1730
1734 if (bd->props->power != FB_BLANK_UNBLANK || 1731 if (bd->props.power != FB_BLANK_UNBLANK ||
1735 bd->props->fb_blank != FB_BLANK_UNBLANK || 1732 bd->props.fb_blank != FB_BLANK_UNBLANK ||
1736 !par->lcd_on) 1733 !par->lcd_on)
1737 level = 0; 1734 level = 0;
1738 else 1735 else
1739 level = bd->props->brightness; 1736 level = bd->props.brightness;
1740 1737
1741 reg |= LVDS_BL_MOD_EN | LVDS_BLON; 1738 reg |= LVDS_BL_MOD_EN | LVDS_BLON;
1742 if (level > 0) { 1739 if (level > 0) {
@@ -1778,43 +1775,22 @@ static int __aty128_bl_update_status(struct backlight_device *bd)
1778 return 0; 1775 return 0;
1779} 1776}
1780 1777
1781static int aty128_bl_update_status(struct backlight_device *bd)
1782{
1783 struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
1784 struct fb_info *info = pci_get_drvdata(par->pdev);
1785 int ret;
1786
1787 mutex_lock(&info->bl_mutex);
1788 ret = __aty128_bl_update_status(bd);
1789 mutex_unlock(&info->bl_mutex);
1790
1791 return ret;
1792}
1793
1794static int aty128_bl_get_brightness(struct backlight_device *bd) 1778static int aty128_bl_get_brightness(struct backlight_device *bd)
1795{ 1779{
1796 return bd->props->brightness; 1780 return bd->props.brightness;
1797} 1781}
1798 1782
1799static struct backlight_properties aty128_bl_data = { 1783static struct backlight_ops aty128_bl_data = {
1800 .owner = THIS_MODULE,
1801 .get_brightness = aty128_bl_get_brightness, 1784 .get_brightness = aty128_bl_get_brightness,
1802 .update_status = aty128_bl_update_status, 1785 .update_status = aty128_bl_update_status,
1803 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
1804}; 1786};
1805 1787
1806static void aty128_bl_set_power(struct fb_info *info, int power) 1788static void aty128_bl_set_power(struct fb_info *info, int power)
1807{ 1789{
1808 mutex_lock(&info->bl_mutex);
1809
1810 if (info->bl_dev) { 1790 if (info->bl_dev) {
1811 down(&info->bl_dev->sem); 1791 info->bl_dev->props.power = power;
1812 info->bl_dev->props->power = power; 1792 backlight_update_status(info->bl_dev);
1813 __aty128_bl_update_status(info->bl_dev);
1814 up(&info->bl_dev->sem);
1815 } 1793 }
1816
1817 mutex_unlock(&info->bl_mutex);
1818} 1794}
1819 1795
1820static void aty128_bl_init(struct aty128fb_par *par) 1796static void aty128_bl_init(struct aty128fb_par *par)
@@ -1841,25 +1817,15 @@ static void aty128_bl_init(struct aty128fb_par *par)
1841 goto error; 1817 goto error;
1842 } 1818 }
1843 1819
1844 mutex_lock(&info->bl_mutex);
1845 info->bl_dev = bd; 1820 info->bl_dev = bd;
1846 fb_bl_default_curve(info, 0, 1821 fb_bl_default_curve(info, 0,
1847 63 * FB_BACKLIGHT_MAX / MAX_LEVEL, 1822 63 * FB_BACKLIGHT_MAX / MAX_LEVEL,
1848 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); 1823 219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
1849 mutex_unlock(&info->bl_mutex);
1850 1824
1851 down(&bd->sem); 1825 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
1852 bd->props->brightness = aty128_bl_data.max_brightness; 1826 bd->props.brightness = bd->props.max_brightness;
1853 bd->props->power = FB_BLANK_UNBLANK; 1827 bd->props.power = FB_BLANK_UNBLANK;
1854 bd->props->update_status(bd); 1828 backlight_update_status(bd);
1855 up(&bd->sem);
1856
1857#ifdef CONFIG_PMAC_BACKLIGHT
1858 mutex_lock(&pmac_backlight_mutex);
1859 if (!pmac_backlight)
1860 pmac_backlight = bd;
1861 mutex_unlock(&pmac_backlight_mutex);
1862#endif
1863 1829
1864 printk("aty128: Backlight initialized (%s)\n", name); 1830 printk("aty128: Backlight initialized (%s)\n", name);
1865 1831
@@ -1869,31 +1835,10 @@ error:
1869 return; 1835 return;
1870} 1836}
1871 1837
1872static void aty128_bl_exit(struct aty128fb_par *par) 1838static void aty128_bl_exit(struct backlight_device *bd)
1873{ 1839{
1874 struct fb_info *info = pci_get_drvdata(par->pdev); 1840 backlight_device_unregister(bd);
1875 1841 printk("aty128: Backlight unloaded\n");
1876#ifdef CONFIG_PMAC_BACKLIGHT
1877 mutex_lock(&pmac_backlight_mutex);
1878#endif
1879
1880 mutex_lock(&info->bl_mutex);
1881 if (info->bl_dev) {
1882#ifdef CONFIG_PMAC_BACKLIGHT
1883 if (pmac_backlight == info->bl_dev)
1884 pmac_backlight = NULL;
1885#endif
1886
1887 backlight_device_unregister(info->bl_dev);
1888 info->bl_dev = NULL;
1889
1890 printk("aty128: Backlight unloaded\n");
1891 }
1892 mutex_unlock(&info->bl_mutex);
1893
1894#ifdef CONFIG_PMAC_BACKLIGHT
1895 mutex_unlock(&pmac_backlight_mutex);
1896#endif
1897} 1842}
1898#endif /* CONFIG_FB_ATY128_BACKLIGHT */ 1843#endif /* CONFIG_FB_ATY128_BACKLIGHT */
1899 1844
@@ -2180,11 +2125,12 @@ static void __devexit aty128_remove(struct pci_dev *pdev)
2180 2125
2181 par = info->par; 2126 par = info->par;
2182 2127
2128 unregister_framebuffer(info);
2129
2183#ifdef CONFIG_FB_ATY128_BACKLIGHT 2130#ifdef CONFIG_FB_ATY128_BACKLIGHT
2184 aty128_bl_exit(par); 2131 aty128_bl_exit(info->bl_dev);
2185#endif 2132#endif
2186 2133
2187 unregister_framebuffer(info);
2188#ifdef CONFIG_MTRR 2134#ifdef CONFIG_MTRR
2189 if (par->mtrr.vram_valid) 2135 if (par->mtrr.vram_valid)
2190 mtrr_del(par->mtrr.vram, info->fix.smem_start, 2136 mtrr_del(par->mtrr.vram, info->fix.smem_start,
@@ -2214,11 +2160,6 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
2214 if (par->lock_blank || par->asleep) 2160 if (par->lock_blank || par->asleep)
2215 return 0; 2161 return 0;
2216 2162
2217#ifdef CONFIG_FB_ATY128_BACKLIGHT
2218 if (machine_is(powermac) && blank)
2219 aty128_bl_set_power(fb, FB_BLANK_POWERDOWN);
2220#endif
2221
2222 if (blank & FB_BLANK_VSYNC_SUSPEND) 2163 if (blank & FB_BLANK_VSYNC_SUSPEND)
2223 state |= 2; 2164 state |= 2;
2224 if (blank & FB_BLANK_HSYNC_SUSPEND) 2165 if (blank & FB_BLANK_HSYNC_SUSPEND)
@@ -2233,11 +2174,6 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
2233 aty128_set_lcd_enable(par, par->lcd_on && !blank); 2174 aty128_set_lcd_enable(par, par->lcd_on && !blank);
2234 } 2175 }
2235 2176
2236#ifdef CONFIG_FB_ATY128_BACKLIGHT
2237 if (machine_is(powermac) && !blank)
2238 aty128_bl_set_power(fb, FB_BLANK_UNBLANK);
2239#endif
2240
2241 return 0; 2177 return 0;
2242} 2178}
2243 2179
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 301612cef354..a7e0062233f2 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2114,15 +2114,13 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
2114#ifdef CONFIG_FB_ATY_BACKLIGHT 2114#ifdef CONFIG_FB_ATY_BACKLIGHT
2115#define MAX_LEVEL 0xFF 2115#define MAX_LEVEL 0xFF
2116 2116
2117static struct backlight_properties aty_bl_data;
2118
2119/* Call with fb_info->bl_mutex held */
2120static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) 2117static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2121{ 2118{
2122 struct fb_info *info = pci_get_drvdata(par->pdev); 2119 struct fb_info *info = pci_get_drvdata(par->pdev);
2123 int atylevel; 2120 int atylevel;
2124 2121
2125 /* Get and convert the value */ 2122 /* Get and convert the value */
2123 /* No locking of bl_curve since we read a single value */
2126 atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL; 2124 atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
2127 2125
2128 if (atylevel < 0) 2126 if (atylevel < 0)
@@ -2133,18 +2131,17 @@ static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2133 return atylevel; 2131 return atylevel;
2134} 2132}
2135 2133
2136/* Call with fb_info->bl_mutex held */ 2134static int aty_bl_update_status(struct backlight_device *bd)
2137static int __aty_bl_update_status(struct backlight_device *bd)
2138{ 2135{
2139 struct atyfb_par *par = class_get_devdata(&bd->class_dev); 2136 struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2140 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); 2137 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
2141 int level; 2138 int level;
2142 2139
2143 if (bd->props->power != FB_BLANK_UNBLANK || 2140 if (bd->props.power != FB_BLANK_UNBLANK ||
2144 bd->props->fb_blank != FB_BLANK_UNBLANK) 2141 bd->props.fb_blank != FB_BLANK_UNBLANK)
2145 level = 0; 2142 level = 0;
2146 else 2143 else
2147 level = bd->props->brightness; 2144 level = bd->props.brightness;
2148 2145
2149 reg |= (BLMOD_EN | BIASMOD_EN); 2146 reg |= (BLMOD_EN | BIASMOD_EN);
2150 if (level > 0) { 2147 if (level > 0) {
@@ -2159,45 +2156,16 @@ static int __aty_bl_update_status(struct backlight_device *bd)
2159 return 0; 2156 return 0;
2160} 2157}
2161 2158
2162static int aty_bl_update_status(struct backlight_device *bd)
2163{
2164 struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2165 struct fb_info *info = pci_get_drvdata(par->pdev);
2166 int ret;
2167
2168 mutex_lock(&info->bl_mutex);
2169 ret = __aty_bl_update_status(bd);
2170 mutex_unlock(&info->bl_mutex);
2171
2172 return ret;
2173}
2174
2175static int aty_bl_get_brightness(struct backlight_device *bd) 2159static int aty_bl_get_brightness(struct backlight_device *bd)
2176{ 2160{
2177 return bd->props->brightness; 2161 return bd->props.brightness;
2178} 2162}
2179 2163
2180static struct backlight_properties aty_bl_data = { 2164static struct backlight_ops aty_bl_data = {
2181 .owner = THIS_MODULE,
2182 .get_brightness = aty_bl_get_brightness, 2165 .get_brightness = aty_bl_get_brightness,
2183 .update_status = aty_bl_update_status, 2166 .update_status = aty_bl_update_status,
2184 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
2185}; 2167};
2186 2168
2187static void aty_bl_set_power(struct fb_info *info, int power)
2188{
2189 mutex_lock(&info->bl_mutex);
2190
2191 if (info->bl_dev) {
2192 down(&info->bl_dev->sem);
2193 info->bl_dev->props->power = power;
2194 __aty_bl_update_status(info->bl_dev);
2195 up(&info->bl_dev->sem);
2196 }
2197
2198 mutex_unlock(&info->bl_mutex);
2199}
2200
2201static void aty_bl_init(struct atyfb_par *par) 2169static void aty_bl_init(struct atyfb_par *par)
2202{ 2170{
2203 struct fb_info *info = pci_get_drvdata(par->pdev); 2171 struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -2218,25 +2186,15 @@ static void aty_bl_init(struct atyfb_par *par)
2218 goto error; 2186 goto error;
2219 } 2187 }
2220 2188
2221 mutex_lock(&info->bl_mutex);
2222 info->bl_dev = bd; 2189 info->bl_dev = bd;
2223 fb_bl_default_curve(info, 0, 2190 fb_bl_default_curve(info, 0,
2224 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, 2191 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
2225 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); 2192 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
2226 mutex_unlock(&info->bl_mutex);
2227
2228 down(&bd->sem);
2229 bd->props->brightness = aty_bl_data.max_brightness;
2230 bd->props->power = FB_BLANK_UNBLANK;
2231 bd->props->update_status(bd);
2232 up(&bd->sem);
2233 2193
2234#ifdef CONFIG_PMAC_BACKLIGHT 2194 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
2235 mutex_lock(&pmac_backlight_mutex); 2195 bd->props.brightness = bd->props.max_brightness;
2236 if (!pmac_backlight) 2196 bd->props.power = FB_BLANK_UNBLANK;
2237 pmac_backlight = bd; 2197 backlight_update_status(bd);
2238 mutex_unlock(&pmac_backlight_mutex);
2239#endif
2240 2198
2241 printk("aty: Backlight initialized (%s)\n", name); 2199 printk("aty: Backlight initialized (%s)\n", name);
2242 2200
@@ -2246,30 +2204,10 @@ error:
2246 return; 2204 return;
2247} 2205}
2248 2206
2249static void aty_bl_exit(struct atyfb_par *par) 2207static void aty_bl_exit(struct backlight_device *bd)
2250{ 2208{
2251 struct fb_info *info = pci_get_drvdata(par->pdev); 2209 backlight_device_unregister(bd);
2252 2210 printk("aty: Backlight unloaded\n");
2253#ifdef CONFIG_PMAC_BACKLIGHT
2254 mutex_lock(&pmac_backlight_mutex);
2255#endif
2256
2257 mutex_lock(&info->bl_mutex);
2258 if (info->bl_dev) {
2259#ifdef CONFIG_PMAC_BACKLIGHT
2260 if (pmac_backlight == info->bl_dev)
2261 pmac_backlight = NULL;
2262#endif
2263
2264 backlight_device_unregister(info->bl_dev);
2265
2266 printk("aty: Backlight unloaded\n");
2267 }
2268 mutex_unlock(&info->bl_mutex);
2269
2270#ifdef CONFIG_PMAC_BACKLIGHT
2271 mutex_unlock(&pmac_backlight_mutex);
2272#endif
2273} 2211}
2274 2212
2275#endif /* CONFIG_FB_ATY_BACKLIGHT */ 2213#endif /* CONFIG_FB_ATY_BACKLIGHT */
@@ -2814,8 +2752,6 @@ static int atyfb_blank(int blank, struct fb_info *info)
2814 return 0; 2752 return 0;
2815 2753
2816#ifdef CONFIG_FB_ATY_BACKLIGHT 2754#ifdef CONFIG_FB_ATY_BACKLIGHT
2817 if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
2818 aty_bl_set_power(info, FB_BLANK_POWERDOWN);
2819#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2755#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2820 if (par->lcd_table && blank > FB_BLANK_NORMAL && 2756 if (par->lcd_table && blank > FB_BLANK_NORMAL &&
2821 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2757 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
@@ -2846,8 +2782,6 @@ static int atyfb_blank(int blank, struct fb_info *info)
2846 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); 2782 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2847 2783
2848#ifdef CONFIG_FB_ATY_BACKLIGHT 2784#ifdef CONFIG_FB_ATY_BACKLIGHT
2849 if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
2850 aty_bl_set_power(info, FB_BLANK_UNBLANK);
2851#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2785#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2852 if (par->lcd_table && blank <= FB_BLANK_NORMAL && 2786 if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
2853 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2787 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
@@ -3726,13 +3660,13 @@ static void __devexit atyfb_remove(struct fb_info *info)
3726 aty_set_crtc(par, &saved_crtc); 3660 aty_set_crtc(par, &saved_crtc);
3727 par->pll_ops->set_pll(info, &saved_pll); 3661 par->pll_ops->set_pll(info, &saved_pll);
3728 3662
3663 unregister_framebuffer(info);
3664
3729#ifdef CONFIG_FB_ATY_BACKLIGHT 3665#ifdef CONFIG_FB_ATY_BACKLIGHT
3730 if (M64_HAS(MOBIL_BUS)) 3666 if (M64_HAS(MOBIL_BUS))
3731 aty_bl_exit(par); 3667 aty_bl_exit(info->bl_dev);
3732#endif 3668#endif
3733 3669
3734 unregister_framebuffer(info);
3735
3736#ifdef CONFIG_MTRR 3670#ifdef CONFIG_MTRR
3737 if (par->mtrr_reg >= 0) { 3671 if (par->mtrr_reg >= 0) {
3738 mtrr_del(par->mtrr_reg, 0, 0); 3672 mtrr_del(par->mtrr_reg, 0, 0);
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 3abfd4a380cc..0be25fa5540c 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -19,8 +19,6 @@
19 19
20#define MAX_RADEON_LEVEL 0xFF 20#define MAX_RADEON_LEVEL 0xFF
21 21
22static struct backlight_properties radeon_bl_data;
23
24struct radeon_bl_privdata { 22struct radeon_bl_privdata {
25 struct radeonfb_info *rinfo; 23 struct radeonfb_info *rinfo;
26 uint8_t negative; 24 uint8_t negative;
@@ -29,17 +27,13 @@ struct radeon_bl_privdata {
29static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, 27static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata,
30 int level) 28 int level)
31{ 29{
32 struct fb_info *info = pdata->rinfo->info;
33 int rlevel; 30 int rlevel;
34 31
35 mutex_lock(&info->bl_mutex);
36
37 /* Get and convert the value */ 32 /* Get and convert the value */
33 /* No locking of bl_curve since we read a single value */
38 rlevel = pdata->rinfo->info->bl_curve[level] * 34 rlevel = pdata->rinfo->info->bl_curve[level] *
39 FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL; 35 FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL;
40 36
41 mutex_unlock(&info->bl_mutex);
42
43 if (rlevel < 0) 37 if (rlevel < 0)
44 rlevel = 0; 38 rlevel = 0;
45 else if (rlevel > MAX_RADEON_LEVEL) 39 else if (rlevel > MAX_RADEON_LEVEL)
@@ -65,11 +59,11 @@ static int radeon_bl_update_status(struct backlight_device *bd)
65 * backlight. This provides some greater power saving and the display 59 * backlight. This provides some greater power saving and the display
66 * is useless without backlight anyway. 60 * is useless without backlight anyway.
67 */ 61 */
68 if (bd->props->power != FB_BLANK_UNBLANK || 62 if (bd->props.power != FB_BLANK_UNBLANK ||
69 bd->props->fb_blank != FB_BLANK_UNBLANK) 63 bd->props.fb_blank != FB_BLANK_UNBLANK)
70 level = 0; 64 level = 0;
71 else 65 else
72 level = bd->props->brightness; 66 level = bd->props.brightness;
73 67
74 del_timer_sync(&rinfo->lvds_timer); 68 del_timer_sync(&rinfo->lvds_timer);
75 radeon_engine_idle(); 69 radeon_engine_idle();
@@ -130,14 +124,12 @@ static int radeon_bl_update_status(struct backlight_device *bd)
130 124
131static int radeon_bl_get_brightness(struct backlight_device *bd) 125static int radeon_bl_get_brightness(struct backlight_device *bd)
132{ 126{
133 return bd->props->brightness; 127 return bd->props.brightness;
134} 128}
135 129
136static struct backlight_properties radeon_bl_data = { 130static struct backlight_ops radeon_bl_data = {
137 .owner = THIS_MODULE,
138 .get_brightness = radeon_bl_get_brightness, 131 .get_brightness = radeon_bl_get_brightness,
139 .update_status = radeon_bl_update_status, 132 .update_status = radeon_bl_update_status,
140 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
141}; 133};
142 134
143void radeonfb_bl_init(struct radeonfb_info *rinfo) 135void radeonfb_bl_init(struct radeonfb_info *rinfo)
@@ -188,25 +180,15 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
188 machine_is_compatible("PowerBook6,5"); 180 machine_is_compatible("PowerBook6,5");
189#endif 181#endif
190 182
191 mutex_lock(&rinfo->info->bl_mutex);
192 rinfo->info->bl_dev = bd; 183 rinfo->info->bl_dev = bd;
193 fb_bl_default_curve(rinfo->info, 0, 184 fb_bl_default_curve(rinfo->info, 0,
194 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL, 185 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL,
195 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); 186 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
196 mutex_unlock(&rinfo->info->bl_mutex);
197 187
198 down(&bd->sem); 188 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
199 bd->props->brightness = radeon_bl_data.max_brightness; 189 bd->props.brightness = bd->props.max_brightness;
200 bd->props->power = FB_BLANK_UNBLANK; 190 bd->props.power = FB_BLANK_UNBLANK;
201 bd->props->update_status(bd); 191 backlight_update_status(bd);
202 up(&bd->sem);
203
204#ifdef CONFIG_PMAC_BACKLIGHT
205 mutex_lock(&pmac_backlight_mutex);
206 if (!pmac_backlight)
207 pmac_backlight = bd;
208 mutex_unlock(&pmac_backlight_mutex);
209#endif
210 192
211 printk("radeonfb: Backlight initialized (%s)\n", name); 193 printk("radeonfb: Backlight initialized (%s)\n", name);
212 194
@@ -219,29 +201,16 @@ error:
219 201
220void radeonfb_bl_exit(struct radeonfb_info *rinfo) 202void radeonfb_bl_exit(struct radeonfb_info *rinfo)
221{ 203{
222#ifdef CONFIG_PMAC_BACKLIGHT 204 struct backlight_device *bd = rinfo->info->bl_dev;
223 mutex_lock(&pmac_backlight_mutex);
224#endif
225 205
226 mutex_lock(&rinfo->info->bl_mutex); 206 if (bd) {
227 if (rinfo->info->bl_dev) {
228 struct radeon_bl_privdata *pdata; 207 struct radeon_bl_privdata *pdata;
229 208
230#ifdef CONFIG_PMAC_BACKLIGHT 209 pdata = class_get_devdata(&bd->class_dev);
231 if (pmac_backlight == rinfo->info->bl_dev) 210 backlight_device_unregister(bd);
232 pmac_backlight = NULL;
233#endif
234
235 pdata = class_get_devdata(&rinfo->info->bl_dev->class_dev);
236 backlight_device_unregister(rinfo->info->bl_dev);
237 kfree(pdata); 211 kfree(pdata);
238 rinfo->info->bl_dev = NULL; 212 rinfo->info->bl_dev = NULL;
239 213
240 printk("radeonfb: Backlight unloaded\n"); 214 printk("radeonfb: Backlight unloaded\n");
241 } 215 }
242 mutex_unlock(&rinfo->info->bl_mutex);
243
244#ifdef CONFIG_PMAC_BACKLIGHT
245 mutex_unlock(&pmac_backlight_mutex);
246#endif
247} 216}
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 0ed577e7cc21..7e228aded4c2 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -2393,7 +2393,6 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
2393 if (!rinfo) 2393 if (!rinfo)
2394 return; 2394 return;
2395 2395
2396 radeonfb_bl_exit(rinfo);
2397 radeonfb_pm_exit(rinfo); 2396 radeonfb_pm_exit(rinfo);
2398 2397
2399 if (rinfo->mon1_EDID) 2398 if (rinfo->mon1_EDID)
@@ -2420,6 +2419,8 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
2420 2419
2421 unregister_framebuffer(info); 2420 unregister_framebuffer(info);
2422 2421
2422 radeonfb_bl_exit(rinfo);
2423
2423 iounmap(rinfo->mmio_base); 2424 iounmap(rinfo->mmio_base);
2424 iounmap(rinfo->fb_base); 2425 iounmap(rinfo->fb_base);
2425 2426
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 02f15297a021..47d15b5d985a 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -19,11 +19,6 @@ config BACKLIGHT_CLASS_DEVICE
19 To have support for your specific LCD panel you will have to 19 To have support for your specific LCD panel you will have to
20 select the proper drivers which depend on this option. 20 select the proper drivers which depend on this option.
21 21
22config BACKLIGHT_DEVICE
23 bool
24 depends on BACKLIGHT_CLASS_DEVICE
25 default y
26
27config LCD_CLASS_DEVICE 22config LCD_CLASS_DEVICE
28 tristate "Lowlevel LCD controls" 23 tristate "Lowlevel LCD controls"
29 depends on BACKLIGHT_LCD_SUPPORT 24 depends on BACKLIGHT_LCD_SUPPORT
@@ -37,14 +32,9 @@ config LCD_CLASS_DEVICE
37 To have support for your specific LCD panel you will have to 32 To have support for your specific LCD panel you will have to
38 select the proper drivers which depend on this option. 33 select the proper drivers which depend on this option.
39 34
40config LCD_DEVICE
41 bool
42 depends on LCD_CLASS_DEVICE
43 default y
44
45config BACKLIGHT_CORGI 35config BACKLIGHT_CORGI
46 tristate "Sharp Corgi Backlight Driver (SL Series)" 36 tristate "Sharp Corgi Backlight Driver (SL Series)"
47 depends on BACKLIGHT_DEVICE && PXA_SHARPSL 37 depends on BACKLIGHT_CLASS_DEVICE && PXA_SHARPSL
48 default y 38 default y
49 help 39 help
50 If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the 40 If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the
@@ -52,7 +42,7 @@ config BACKLIGHT_CORGI
52 42
53config BACKLIGHT_LOCOMO 43config BACKLIGHT_LOCOMO
54 tristate "Sharp LOCOMO LCD/Backlight Driver" 44 tristate "Sharp LOCOMO LCD/Backlight Driver"
55 depends on BACKLIGHT_DEVICE && SHARP_LOCOMO 45 depends on BACKLIGHT_CLASS_DEVICE && SHARP_LOCOMO
56 default y 46 default y
57 help 47 help
58 If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to 48 If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
@@ -60,9 +50,16 @@ config BACKLIGHT_LOCOMO
60 50
61config BACKLIGHT_HP680 51config BACKLIGHT_HP680
62 tristate "HP Jornada 680 Backlight Driver" 52 tristate "HP Jornada 680 Backlight Driver"
63 depends on BACKLIGHT_DEVICE && SH_HP6XX 53 depends on BACKLIGHT_CLASS_DEVICE && SH_HP6XX
64 default y 54 default y
65 help 55 help
66 If you have a HP Jornada 680, say y to enable the 56 If you have a HP Jornada 680, say y to enable the
67 backlight driver. 57 backlight driver.
68 58
59config BACKLIGHT_PROGEAR
60 tristate "Frontpath ProGear Backlight Driver"
61 depends on BACKLIGHT_CLASS_DEVICE && PCI && X86
62 default n
63 help
64 If you have a Frontpath ProGear say Y to enable the
65 backlight driver.
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 65e5553fc849..0c3ce46f5094 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
5obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o 5obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
6obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o 6obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
7obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o 7obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
8obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 9601bfe309ac..c65e81ff3578 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -14,6 +14,9 @@
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/fb.h> 15#include <linux/fb.h>
16 16
17#ifdef CONFIG_PMAC_BACKLIGHT
18#include <asm/backlight.h>
19#endif
17 20
18#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ 21#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
19 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)) 22 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
@@ -28,19 +31,18 @@ static int fb_notifier_callback(struct notifier_block *self,
28 struct fb_event *evdata = data; 31 struct fb_event *evdata = data;
29 32
30 /* If we aren't interested in this event, skip it immediately ... */ 33 /* If we aren't interested in this event, skip it immediately ... */
31 if (event != FB_EVENT_BLANK) 34 if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
32 return 0; 35 return 0;
33 36
34 bd = container_of(self, struct backlight_device, fb_notif); 37 bd = container_of(self, struct backlight_device, fb_notif);
35 down(&bd->sem); 38 mutex_lock(&bd->ops_lock);
36 if (bd->props) 39 if (bd->ops)
37 if (!bd->props->check_fb || 40 if (!bd->ops->check_fb ||
38 bd->props->check_fb(evdata->info)) { 41 bd->ops->check_fb(evdata->info)) {
39 bd->props->fb_blank = *(int *)evdata->data; 42 bd->props.fb_blank = *(int *)evdata->data;
40 if (likely(bd->props && bd->props->update_status)) 43 backlight_update_status(bd);
41 bd->props->update_status(bd);
42 } 44 }
43 up(&bd->sem); 45 mutex_unlock(&bd->ops_lock);
44 return 0; 46 return 0;
45} 47}
46 48
@@ -69,15 +71,9 @@ static inline void backlight_unregister_fb(struct backlight_device *bd)
69 71
70static ssize_t backlight_show_power(struct class_device *cdev, char *buf) 72static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
71{ 73{
72 int rc = -ENXIO;
73 struct backlight_device *bd = to_backlight_device(cdev); 74 struct backlight_device *bd = to_backlight_device(cdev);
74 75
75 down(&bd->sem); 76 return sprintf(buf, "%d\n", bd->props.power);
76 if (likely(bd->props))
77 rc = sprintf(buf, "%d\n", bd->props->power);
78 up(&bd->sem);
79
80 return rc;
81} 77}
82 78
83static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count) 79static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
@@ -93,30 +89,23 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf,
93 if (size != count) 89 if (size != count)
94 return -EINVAL; 90 return -EINVAL;
95 91
96 down(&bd->sem); 92 mutex_lock(&bd->ops_lock);
97 if (likely(bd->props)) { 93 if (bd->ops) {
98 pr_debug("backlight: set power to %d\n", power); 94 pr_debug("backlight: set power to %d\n", power);
99 bd->props->power = power; 95 bd->props.power = power;
100 if (likely(bd->props->update_status)) 96 backlight_update_status(bd);
101 bd->props->update_status(bd);
102 rc = count; 97 rc = count;
103 } 98 }
104 up(&bd->sem); 99 mutex_unlock(&bd->ops_lock);
105 100
106 return rc; 101 return rc;
107} 102}
108 103
109static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) 104static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
110{ 105{
111 int rc = -ENXIO;
112 struct backlight_device *bd = to_backlight_device(cdev); 106 struct backlight_device *bd = to_backlight_device(cdev);
113 107
114 down(&bd->sem); 108 return sprintf(buf, "%d\n", bd->props.brightness);
115 if (likely(bd->props))
116 rc = sprintf(buf, "%d\n", bd->props->brightness);
117 up(&bd->sem);
118
119 return rc;
120} 109}
121 110
122static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count) 111static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
@@ -132,35 +121,28 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char
132 if (size != count) 121 if (size != count)
133 return -EINVAL; 122 return -EINVAL;
134 123
135 down(&bd->sem); 124 mutex_lock(&bd->ops_lock);
136 if (likely(bd->props)) { 125 if (bd->ops) {
137 if (brightness > bd->props->max_brightness) 126 if (brightness > bd->props.max_brightness)
138 rc = -EINVAL; 127 rc = -EINVAL;
139 else { 128 else {
140 pr_debug("backlight: set brightness to %d\n", 129 pr_debug("backlight: set brightness to %d\n",
141 brightness); 130 brightness);
142 bd->props->brightness = brightness; 131 bd->props.brightness = brightness;
143 if (likely(bd->props->update_status)) 132 backlight_update_status(bd);
144 bd->props->update_status(bd);
145 rc = count; 133 rc = count;
146 } 134 }
147 } 135 }
148 up(&bd->sem); 136 mutex_unlock(&bd->ops_lock);
149 137
150 return rc; 138 return rc;
151} 139}
152 140
153static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf) 141static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf)
154{ 142{
155 int rc = -ENXIO;
156 struct backlight_device *bd = to_backlight_device(cdev); 143 struct backlight_device *bd = to_backlight_device(cdev);
157 144
158 down(&bd->sem); 145 return sprintf(buf, "%d\n", bd->props.max_brightness);
159 if (likely(bd->props))
160 rc = sprintf(buf, "%d\n", bd->props->max_brightness);
161 up(&bd->sem);
162
163 return rc;
164} 146}
165 147
166static ssize_t backlight_show_actual_brightness(struct class_device *cdev, 148static ssize_t backlight_show_actual_brightness(struct class_device *cdev,
@@ -169,10 +151,10 @@ static ssize_t backlight_show_actual_brightness(struct class_device *cdev,
169 int rc = -ENXIO; 151 int rc = -ENXIO;
170 struct backlight_device *bd = to_backlight_device(cdev); 152 struct backlight_device *bd = to_backlight_device(cdev);
171 153
172 down(&bd->sem); 154 mutex_lock(&bd->ops_lock);
173 if (likely(bd->props && bd->props->get_brightness)) 155 if (bd->ops && bd->ops->get_brightness)
174 rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd)); 156 rc = sprintf(buf, "%d\n", bd->ops->get_brightness(bd));
175 up(&bd->sem); 157 mutex_unlock(&bd->ops_lock);
176 158
177 return rc; 159 return rc;
178} 160}
@@ -211,7 +193,7 @@ static const struct class_device_attribute bl_class_device_attributes[] = {
211 * respective framebuffer device). 193 * respective framebuffer device).
212 * @devdata: an optional pointer to be stored in the class_device. The 194 * @devdata: an optional pointer to be stored in the class_device. The
213 * methods may retrieve it by using class_get_devdata(&bd->class_dev). 195 * methods may retrieve it by using class_get_devdata(&bd->class_dev).
214 * @bp: the backlight properties structure. 196 * @ops: the backlight operations structure.
215 * 197 *
216 * Creates and registers new backlight class_device. Returns either an 198 * Creates and registers new backlight class_device. Returns either an
217 * ERR_PTR() or a pointer to the newly allocated device. 199 * ERR_PTR() or a pointer to the newly allocated device.
@@ -219,39 +201,42 @@ static const struct class_device_attribute bl_class_device_attributes[] = {
219struct backlight_device *backlight_device_register(const char *name, 201struct backlight_device *backlight_device_register(const char *name,
220 struct device *dev, 202 struct device *dev,
221 void *devdata, 203 void *devdata,
222 struct backlight_properties *bp) 204 struct backlight_ops *ops)
223{ 205{
224 int i, rc; 206 int i, rc;
225 struct backlight_device *new_bd; 207 struct backlight_device *new_bd;
226 208
227 pr_debug("backlight_device_alloc: name=%s\n", name); 209 pr_debug("backlight_device_alloc: name=%s\n", name);
228 210
229 new_bd = kmalloc(sizeof(struct backlight_device), GFP_KERNEL); 211 new_bd = kzalloc(sizeof(struct backlight_device), GFP_KERNEL);
230 if (unlikely(!new_bd)) 212 if (!new_bd)
231 return ERR_PTR(-ENOMEM); 213 return ERR_PTR(-ENOMEM);
232 214
233 init_MUTEX(&new_bd->sem); 215 mutex_init(&new_bd->update_lock);
234 new_bd->props = bp; 216 mutex_init(&new_bd->ops_lock);
235 memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev)); 217 new_bd->ops = ops;
236 new_bd->class_dev.class = &backlight_class; 218 new_bd->class_dev.class = &backlight_class;
237 new_bd->class_dev.dev = dev; 219 new_bd->class_dev.dev = dev;
238 strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN); 220 strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN);
239 class_set_devdata(&new_bd->class_dev, devdata); 221 class_set_devdata(&new_bd->class_dev, devdata);
240 222
241 rc = class_device_register(&new_bd->class_dev); 223 rc = class_device_register(&new_bd->class_dev);
242 if (unlikely(rc)) { 224 if (rc) {
243error: kfree(new_bd); 225 kfree(new_bd);
244 return ERR_PTR(rc); 226 return ERR_PTR(rc);
245 } 227 }
246 228
247 rc = backlight_register_fb(new_bd); 229 rc = backlight_register_fb(new_bd);
248 if (unlikely(rc)) 230 if (rc) {
249 goto error; 231 class_device_unregister(&new_bd->class_dev);
232 return ERR_PTR(rc);
233 }
234
250 235
251 for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++) { 236 for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++) {
252 rc = class_device_create_file(&new_bd->class_dev, 237 rc = class_device_create_file(&new_bd->class_dev,
253 &bl_class_device_attributes[i]); 238 &bl_class_device_attributes[i]);
254 if (unlikely(rc)) { 239 if (rc) {
255 while (--i >= 0) 240 while (--i >= 0)
256 class_device_remove_file(&new_bd->class_dev, 241 class_device_remove_file(&new_bd->class_dev,
257 &bl_class_device_attributes[i]); 242 &bl_class_device_attributes[i]);
@@ -261,6 +246,13 @@ error: kfree(new_bd);
261 } 246 }
262 } 247 }
263 248
249#ifdef CONFIG_PMAC_BACKLIGHT
250 mutex_lock(&pmac_backlight_mutex);
251 if (!pmac_backlight)
252 pmac_backlight = new_bd;
253 mutex_unlock(&pmac_backlight_mutex);
254#endif
255
264 return new_bd; 256 return new_bd;
265} 257}
266EXPORT_SYMBOL(backlight_device_register); 258EXPORT_SYMBOL(backlight_device_register);
@@ -280,13 +272,20 @@ void backlight_device_unregister(struct backlight_device *bd)
280 272
281 pr_debug("backlight_device_unregister: name=%s\n", bd->class_dev.class_id); 273 pr_debug("backlight_device_unregister: name=%s\n", bd->class_dev.class_id);
282 274
275#ifdef CONFIG_PMAC_BACKLIGHT
276 mutex_lock(&pmac_backlight_mutex);
277 if (pmac_backlight == bd)
278 pmac_backlight = NULL;
279 mutex_unlock(&pmac_backlight_mutex);
280#endif
281
283 for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++) 282 for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++)
284 class_device_remove_file(&bd->class_dev, 283 class_device_remove_file(&bd->class_dev,
285 &bl_class_device_attributes[i]); 284 &bl_class_device_attributes[i]);
286 285
287 down(&bd->sem); 286 mutex_lock(&bd->ops_lock);
288 bd->props = NULL; 287 bd->ops = NULL;
289 up(&bd->sem); 288 mutex_unlock(&bd->ops_lock);
290 289
291 backlight_unregister_fb(bd); 290 backlight_unregister_fb(bd);
292 291
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index fde1d9518123..ce00e18a4e5d 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -22,7 +22,6 @@
22#include <asm/hardware/sharpsl_pm.h> 22#include <asm/hardware/sharpsl_pm.h>
23 23
24static int corgibl_intensity; 24static int corgibl_intensity;
25static DEFINE_MUTEX(bl_mutex);
26static struct backlight_properties corgibl_data; 25static struct backlight_properties corgibl_data;
27static struct backlight_device *corgi_backlight_device; 26static struct backlight_device *corgi_backlight_device;
28static struct corgibl_machinfo *bl_machinfo; 27static struct corgibl_machinfo *bl_machinfo;
@@ -34,20 +33,18 @@ static unsigned long corgibl_flags;
34static int corgibl_send_intensity(struct backlight_device *bd) 33static int corgibl_send_intensity(struct backlight_device *bd)
35{ 34{
36 void (*corgi_kick_batt)(void); 35 void (*corgi_kick_batt)(void);
37 int intensity = bd->props->brightness; 36 int intensity = bd->props.brightness;
38 37
39 if (bd->props->power != FB_BLANK_UNBLANK) 38 if (bd->props.power != FB_BLANK_UNBLANK)
40 intensity = 0; 39 intensity = 0;
41 if (bd->props->fb_blank != FB_BLANK_UNBLANK) 40 if (bd->props.fb_blank != FB_BLANK_UNBLANK)
42 intensity = 0; 41 intensity = 0;
43 if (corgibl_flags & CORGIBL_SUSPENDED) 42 if (corgibl_flags & CORGIBL_SUSPENDED)
44 intensity = 0; 43 intensity = 0;
45 if (corgibl_flags & CORGIBL_BATTLOW) 44 if (corgibl_flags & CORGIBL_BATTLOW)
46 intensity &= bl_machinfo->limit_mask; 45 intensity &= bl_machinfo->limit_mask;
47 46
48 mutex_lock(&bl_mutex);
49 bl_machinfo->set_bl_intensity(intensity); 47 bl_machinfo->set_bl_intensity(intensity);
50 mutex_unlock(&bl_mutex);
51 48
52 corgibl_intensity = intensity; 49 corgibl_intensity = intensity;
53 50
@@ -61,17 +58,21 @@ static int corgibl_send_intensity(struct backlight_device *bd)
61} 58}
62 59
63#ifdef CONFIG_PM 60#ifdef CONFIG_PM
64static int corgibl_suspend(struct platform_device *dev, pm_message_t state) 61static int corgibl_suspend(struct platform_device *pdev, pm_message_t state)
65{ 62{
63 struct backlight_device *bd = platform_get_drvdata(pdev);
64
66 corgibl_flags |= CORGIBL_SUSPENDED; 65 corgibl_flags |= CORGIBL_SUSPENDED;
67 corgibl_send_intensity(corgi_backlight_device); 66 backlight_update_status(bd);
68 return 0; 67 return 0;
69} 68}
70 69
71static int corgibl_resume(struct platform_device *dev) 70static int corgibl_resume(struct platform_device *pdev)
72{ 71{
72 struct backlight_device *bd = platform_get_drvdata(pdev);
73
73 corgibl_flags &= ~CORGIBL_SUSPENDED; 74 corgibl_flags &= ~CORGIBL_SUSPENDED;
74 corgibl_send_intensity(corgi_backlight_device); 75 backlight_update_status(bd);
75 return 0; 76 return 0;
76} 77}
77#else 78#else
@@ -84,12 +85,6 @@ static int corgibl_get_intensity(struct backlight_device *bd)
84 return corgibl_intensity; 85 return corgibl_intensity;
85} 86}
86 87
87static int corgibl_set_intensity(struct backlight_device *bd)
88{
89 corgibl_send_intensity(corgi_backlight_device);
90 return 0;
91}
92
93/* 88/*
94 * Called when the battery is low to limit the backlight intensity. 89 * Called when the battery is low to limit the backlight intensity.
95 * If limit==0 clear any limit, otherwise limit the intensity 90 * If limit==0 clear any limit, otherwise limit the intensity
@@ -100,15 +95,14 @@ void corgibl_limit_intensity(int limit)
100 corgibl_flags |= CORGIBL_BATTLOW; 95 corgibl_flags |= CORGIBL_BATTLOW;
101 else 96 else
102 corgibl_flags &= ~CORGIBL_BATTLOW; 97 corgibl_flags &= ~CORGIBL_BATTLOW;
103 corgibl_send_intensity(corgi_backlight_device); 98 backlight_update_status(corgi_backlight_device);
104} 99}
105EXPORT_SYMBOL(corgibl_limit_intensity); 100EXPORT_SYMBOL(corgibl_limit_intensity);
106 101
107 102
108static struct backlight_properties corgibl_data = { 103static struct backlight_ops corgibl_ops = {
109 .owner = THIS_MODULE,
110 .get_brightness = corgibl_get_intensity, 104 .get_brightness = corgibl_get_intensity,
111 .update_status = corgibl_set_intensity, 105 .update_status = corgibl_send_intensity,
112}; 106};
113 107
114static int corgibl_probe(struct platform_device *pdev) 108static int corgibl_probe(struct platform_device *pdev)
@@ -116,30 +110,34 @@ static int corgibl_probe(struct platform_device *pdev)
116 struct corgibl_machinfo *machinfo = pdev->dev.platform_data; 110 struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
117 111
118 bl_machinfo = machinfo; 112 bl_machinfo = machinfo;
119 corgibl_data.max_brightness = machinfo->max_intensity;
120 if (!machinfo->limit_mask) 113 if (!machinfo->limit_mask)
121 machinfo->limit_mask = -1; 114 machinfo->limit_mask = -1;
122 115
123 corgi_backlight_device = backlight_device_register ("corgi-bl", 116 corgi_backlight_device = backlight_device_register ("corgi-bl",
124 &pdev->dev, NULL, &corgibl_data); 117 &pdev->dev, NULL, &corgibl_ops);
125 if (IS_ERR (corgi_backlight_device)) 118 if (IS_ERR (corgi_backlight_device))
126 return PTR_ERR (corgi_backlight_device); 119 return PTR_ERR (corgi_backlight_device);
127 120
128 corgibl_data.power = FB_BLANK_UNBLANK; 121 platform_set_drvdata(pdev, corgi_backlight_device);
129 corgibl_data.brightness = machinfo->default_intensity; 122
130 corgibl_send_intensity(corgi_backlight_device); 123 corgi_backlight_device->props.max_brightness = machinfo->max_intensity;
124 corgi_backlight_device->props.power = FB_BLANK_UNBLANK;
125 corgi_backlight_device->props.brightness = machinfo->default_intensity;
126 backlight_update_status(corgi_backlight_device);
131 127
132 printk("Corgi Backlight Driver Initialized.\n"); 128 printk("Corgi Backlight Driver Initialized.\n");
133 return 0; 129 return 0;
134} 130}
135 131
136static int corgibl_remove(struct platform_device *dev) 132static int corgibl_remove(struct platform_device *pdev)
137{ 133{
134 struct backlight_device *bd = platform_get_drvdata(pdev);
135
138 corgibl_data.power = 0; 136 corgibl_data.power = 0;
139 corgibl_data.brightness = 0; 137 corgibl_data.brightness = 0;
140 corgibl_send_intensity(corgi_backlight_device); 138 backlight_update_status(bd);
141 139
142 backlight_device_unregister(corgi_backlight_device); 140 backlight_device_unregister(bd);
143 141
144 printk("Corgi Backlight Driver Unloaded\n"); 142 printk("Corgi Backlight Driver Unloaded\n");
145 return 0; 143 return 0;
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index c07d8207fb54..0899fccbd570 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -28,17 +28,16 @@
28static int hp680bl_suspended; 28static int hp680bl_suspended;
29static int current_intensity = 0; 29static int current_intensity = 0;
30static DEFINE_SPINLOCK(bl_lock); 30static DEFINE_SPINLOCK(bl_lock);
31static struct backlight_device *hp680_backlight_device;
32 31
33static void hp680bl_send_intensity(struct backlight_device *bd) 32static void hp680bl_send_intensity(struct backlight_device *bd)
34{ 33{
35 unsigned long flags; 34 unsigned long flags;
36 u16 v; 35 u16 v;
37 int intensity = bd->props->brightness; 36 int intensity = bd->props.brightness;
38 37
39 if (bd->props->power != FB_BLANK_UNBLANK) 38 if (bd->props.power != FB_BLANK_UNBLANK)
40 intensity = 0; 39 intensity = 0;
41 if (bd->props->fb_blank != FB_BLANK_UNBLANK) 40 if (bd->props.fb_blank != FB_BLANK_UNBLANK)
42 intensity = 0; 41 intensity = 0;
43 if (hp680bl_suspended) 42 if (hp680bl_suspended)
44 intensity = 0; 43 intensity = 0;
@@ -66,17 +65,21 @@ static void hp680bl_send_intensity(struct backlight_device *bd)
66 65
67 66
68#ifdef CONFIG_PM 67#ifdef CONFIG_PM
69static int hp680bl_suspend(struct platform_device *dev, pm_message_t state) 68static int hp680bl_suspend(struct platform_device *pdev, pm_message_t state)
70{ 69{
70 struct backlight_device *bd = platform_get_drvdata(pdev);
71
71 hp680bl_suspended = 1; 72 hp680bl_suspended = 1;
72 hp680bl_send_intensity(hp680_backlight_device); 73 hp680bl_send_intensity(bd);
73 return 0; 74 return 0;
74} 75}
75 76
76static int hp680bl_resume(struct platform_device *dev) 77static int hp680bl_resume(struct platform_device *pdev)
77{ 78{
79 struct backlight_device *bd = platform_get_drvdata(pdev);
80
78 hp680bl_suspended = 0; 81 hp680bl_suspended = 0;
79 hp680bl_send_intensity(hp680_backlight_device); 82 hp680bl_send_intensity(bd);
80 return 0; 83 return 0;
81} 84}
82#else 85#else
@@ -95,33 +98,38 @@ static int hp680bl_get_intensity(struct backlight_device *bd)
95 return current_intensity; 98 return current_intensity;
96} 99}
97 100
98static struct backlight_properties hp680bl_data = { 101static struct backlight_ops hp680bl_ops = {
99 .owner = THIS_MODULE,
100 .max_brightness = HP680_MAX_INTENSITY,
101 .get_brightness = hp680bl_get_intensity, 102 .get_brightness = hp680bl_get_intensity,
102 .update_status = hp680bl_set_intensity, 103 .update_status = hp680bl_set_intensity,
103}; 104};
104 105
105static int __init hp680bl_probe(struct platform_device *dev) 106static int __init hp680bl_probe(struct platform_device *pdev)
106{ 107{
107 hp680_backlight_device = backlight_device_register ("hp680-bl", 108 struct backlight_device *bd;
108 &dev->dev, NULL, &hp680bl_data); 109
109 if (IS_ERR (hp680_backlight_device)) 110 bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL,
110 return PTR_ERR (hp680_backlight_device); 111 &hp680bl_ops);
112 if (IS_ERR(bd))
113 return PTR_ERR(bd);
111 114
112 hp680_backlight_device->props->brightness = HP680_DEFAULT_INTENSITY; 115 platform_set_drvdata(pdev, bd);
113 hp680bl_send_intensity(hp680_backlight_device); 116
117 bd->props.max_brightness = HP680_MAX_INTENSITY;
118 bd->props.brightness = HP680_DEFAULT_INTENSITY;
119 hp680bl_send_intensity(bd);
114 120
115 return 0; 121 return 0;
116} 122}
117 123
118static int hp680bl_remove(struct platform_device *dev) 124static int hp680bl_remove(struct platform_device *pdev)
119{ 125{
126 struct backlight_device *bd = platform_get_drvdata(pdev);
127
120 hp680bl_data.brightness = 0; 128 hp680bl_data.brightness = 0;
121 hp680bl_data.power = 0; 129 hp680bl_data.power = 0;
122 hp680bl_send_intensity(hp680_backlight_device); 130 hp680bl_send_intensity(bd);
123 131
124 backlight_device_unregister(hp680_backlight_device); 132 backlight_device_unregister(bd);
125 133
126 return 0; 134 return 0;
127} 135}
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index f6e041627edb..6ef8f0a7a137 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -31,11 +31,11 @@ static int fb_notifier_callback(struct notifier_block *self,
31 return 0; 31 return 0;
32 32
33 ld = container_of(self, struct lcd_device, fb_notif); 33 ld = container_of(self, struct lcd_device, fb_notif);
34 down(&ld->sem); 34 mutex_lock(&ld->ops_lock);
35 if (ld->props) 35 if (ld->ops)
36 if (!ld->props->check_fb || ld->props->check_fb(evdata->info)) 36 if (!ld->ops->check_fb || ld->ops->check_fb(evdata->info))
37 ld->props->set_power(ld, *(int *)evdata->data); 37 ld->ops->set_power(ld, *(int *)evdata->data);
38 up(&ld->sem); 38 mutex_unlock(&ld->ops_lock);
39 return 0; 39 return 0;
40} 40}
41 41
@@ -66,12 +66,12 @@ static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
66 int rc; 66 int rc;
67 struct lcd_device *ld = to_lcd_device(cdev); 67 struct lcd_device *ld = to_lcd_device(cdev);
68 68
69 down(&ld->sem); 69 mutex_lock(&ld->ops_lock);
70 if (likely(ld->props && ld->props->get_power)) 70 if (ld->ops && ld->ops->get_power)
71 rc = sprintf(buf, "%d\n", ld->props->get_power(ld)); 71 rc = sprintf(buf, "%d\n", ld->ops->get_power(ld));
72 else 72 else
73 rc = -ENXIO; 73 rc = -ENXIO;
74 up(&ld->sem); 74 mutex_unlock(&ld->ops_lock);
75 75
76 return rc; 76 return rc;
77} 77}
@@ -89,13 +89,13 @@ static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_
89 if (size != count) 89 if (size != count)
90 return -EINVAL; 90 return -EINVAL;
91 91
92 down(&ld->sem); 92 mutex_lock(&ld->ops_lock);
93 if (likely(ld->props && ld->props->set_power)) { 93 if (ld->ops && ld->ops->set_power) {
94 pr_debug("lcd: set power to %d\n", power); 94 pr_debug("lcd: set power to %d\n", power);
95 ld->props->set_power(ld, power); 95 ld->ops->set_power(ld, power);
96 rc = count; 96 rc = count;
97 } 97 }
98 up(&ld->sem); 98 mutex_unlock(&ld->ops_lock);
99 99
100 return rc; 100 return rc;
101} 101}
@@ -105,10 +105,10 @@ static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf)
105 int rc = -ENXIO; 105 int rc = -ENXIO;
106 struct lcd_device *ld = to_lcd_device(cdev); 106 struct lcd_device *ld = to_lcd_device(cdev);
107 107
108 down(&ld->sem); 108 mutex_lock(&ld->ops_lock);
109 if (likely(ld->props && ld->props->get_contrast)) 109 if (ld->ops && ld->ops->get_contrast)
110 rc = sprintf(buf, "%d\n", ld->props->get_contrast(ld)); 110 rc = sprintf(buf, "%d\n", ld->ops->get_contrast(ld));
111 up(&ld->sem); 111 mutex_unlock(&ld->ops_lock);
112 112
113 return rc; 113 return rc;
114} 114}
@@ -126,28 +126,22 @@ static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, si
126 if (size != count) 126 if (size != count)
127 return -EINVAL; 127 return -EINVAL;
128 128
129 down(&ld->sem); 129 mutex_lock(&ld->ops_lock);
130 if (likely(ld->props && ld->props->set_contrast)) { 130 if (ld->ops && ld->ops->set_contrast) {
131 pr_debug("lcd: set contrast to %d\n", contrast); 131 pr_debug("lcd: set contrast to %d\n", contrast);
132 ld->props->set_contrast(ld, contrast); 132 ld->ops->set_contrast(ld, contrast);
133 rc = count; 133 rc = count;
134 } 134 }
135 up(&ld->sem); 135 mutex_unlock(&ld->ops_lock);
136 136
137 return rc; 137 return rc;
138} 138}
139 139
140static ssize_t lcd_show_max_contrast(struct class_device *cdev, char *buf) 140static ssize_t lcd_show_max_contrast(struct class_device *cdev, char *buf)
141{ 141{
142 int rc = -ENXIO;
143 struct lcd_device *ld = to_lcd_device(cdev); 142 struct lcd_device *ld = to_lcd_device(cdev);
144 143
145 down(&ld->sem); 144 return sprintf(buf, "%d\n", ld->props.max_contrast);
146 if (likely(ld->props))
147 rc = sprintf(buf, "%d\n", ld->props->max_contrast);
148 up(&ld->sem);
149
150 return rc;
151} 145}
152 146
153static void lcd_class_release(struct class_device *dev) 147static void lcd_class_release(struct class_device *dev)
@@ -180,45 +174,46 @@ static const struct class_device_attribute lcd_class_device_attributes[] = {
180 * respective framebuffer device). 174 * respective framebuffer device).
181 * @devdata: an optional pointer to be stored in the class_device. The 175 * @devdata: an optional pointer to be stored in the class_device. The
182 * methods may retrieve it by using class_get_devdata(ld->class_dev). 176 * methods may retrieve it by using class_get_devdata(ld->class_dev).
183 * @lp: the lcd properties structure. 177 * @ops: the lcd operations structure.
184 * 178 *
185 * Creates and registers a new lcd class_device. Returns either an ERR_PTR() 179 * Creates and registers a new lcd class_device. Returns either an ERR_PTR()
186 * or a pointer to the newly allocated device. 180 * or a pointer to the newly allocated device.
187 */ 181 */
188struct lcd_device *lcd_device_register(const char *name, void *devdata, 182struct lcd_device *lcd_device_register(const char *name, void *devdata,
189 struct lcd_properties *lp) 183 struct lcd_ops *ops)
190{ 184{
191 int i, rc; 185 int i, rc;
192 struct lcd_device *new_ld; 186 struct lcd_device *new_ld;
193 187
194 pr_debug("lcd_device_register: name=%s\n", name); 188 pr_debug("lcd_device_register: name=%s\n", name);
195 189
196 new_ld = kmalloc(sizeof(struct lcd_device), GFP_KERNEL); 190 new_ld = kzalloc(sizeof(struct lcd_device), GFP_KERNEL);
197 if (unlikely(!new_ld)) 191 if (!new_ld)
198 return ERR_PTR(-ENOMEM); 192 return ERR_PTR(-ENOMEM);
199 193
200 init_MUTEX(&new_ld->sem); 194 mutex_init(&new_ld->ops_lock);
201 new_ld->props = lp; 195 mutex_init(&new_ld->update_lock);
202 memset(&new_ld->class_dev, 0, sizeof(new_ld->class_dev)); 196 new_ld->ops = ops;
203 new_ld->class_dev.class = &lcd_class; 197 new_ld->class_dev.class = &lcd_class;
204 strlcpy(new_ld->class_dev.class_id, name, KOBJ_NAME_LEN); 198 strlcpy(new_ld->class_dev.class_id, name, KOBJ_NAME_LEN);
205 class_set_devdata(&new_ld->class_dev, devdata); 199 class_set_devdata(&new_ld->class_dev, devdata);
206 200
207 rc = class_device_register(&new_ld->class_dev); 201 rc = class_device_register(&new_ld->class_dev);
208 if (unlikely(rc)) { 202 if (rc) {
209error: kfree(new_ld); 203 kfree(new_ld);
210 return ERR_PTR(rc); 204 return ERR_PTR(rc);
211 } 205 }
212 206
213 rc = lcd_register_fb(new_ld); 207 rc = lcd_register_fb(new_ld);
214 208 if (rc) {
215 if (unlikely(rc)) 209 class_device_unregister(&new_ld->class_dev);
216 goto error; 210 return ERR_PTR(rc);
211 }
217 212
218 for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++) { 213 for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++) {
219 rc = class_device_create_file(&new_ld->class_dev, 214 rc = class_device_create_file(&new_ld->class_dev,
220 &lcd_class_device_attributes[i]); 215 &lcd_class_device_attributes[i]);
221 if (unlikely(rc)) { 216 if (rc) {
222 while (--i >= 0) 217 while (--i >= 0)
223 class_device_remove_file(&new_ld->class_dev, 218 class_device_remove_file(&new_ld->class_dev,
224 &lcd_class_device_attributes[i]); 219 &lcd_class_device_attributes[i]);
@@ -251,9 +246,9 @@ void lcd_device_unregister(struct lcd_device *ld)
251 class_device_remove_file(&ld->class_dev, 246 class_device_remove_file(&ld->class_dev,
252 &lcd_class_device_attributes[i]); 247 &lcd_class_device_attributes[i]);
253 248
254 down(&ld->sem); 249 mutex_lock(&ld->ops_lock);
255 ld->props = NULL; 250 ld->ops = NULL;
256 up(&ld->sem); 251 mutex_unlock(&ld->ops_lock);
257 lcd_unregister_fb(ld); 252 lcd_unregister_fb(ld);
258 class_device_unregister(&ld->class_dev); 253 class_device_unregister(&ld->class_dev);
259} 254}
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index fc812d96c31d..d1312477813e 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -112,11 +112,11 @@ static int current_intensity;
112 112
113static int locomolcd_set_intensity(struct backlight_device *bd) 113static int locomolcd_set_intensity(struct backlight_device *bd)
114{ 114{
115 int intensity = bd->props->brightness; 115 int intensity = bd->props.brightness;
116 116
117 if (bd->props->power != FB_BLANK_UNBLANK) 117 if (bd->props.power != FB_BLANK_UNBLANK)
118 intensity = 0; 118 intensity = 0;
119 if (bd->props->fb_blank != FB_BLANK_UNBLANK) 119 if (bd->props.fb_blank != FB_BLANK_UNBLANK)
120 intensity = 0; 120 intensity = 0;
121 if (locomolcd_flags & LOCOMOLCD_SUSPENDED) 121 if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
122 intensity = 0; 122 intensity = 0;
@@ -141,11 +141,9 @@ static int locomolcd_get_intensity(struct backlight_device *bd)
141 return current_intensity; 141 return current_intensity;
142} 142}
143 143
144static struct backlight_properties locomobl_data = { 144static struct backlight_ops locomobl_data = {
145 .owner = THIS_MODULE,
146 .get_brightness = locomolcd_get_intensity, 145 .get_brightness = locomolcd_get_intensity,
147 .update_status = locomolcd_set_intensity, 146 .update_status = locomolcd_set_intensity,
148 .max_brightness = 4,
149}; 147};
150 148
151#ifdef CONFIG_PM 149#ifdef CONFIG_PM
@@ -190,7 +188,8 @@ static int locomolcd_probe(struct locomo_dev *ldev)
190 return PTR_ERR (locomolcd_bl_device); 188 return PTR_ERR (locomolcd_bl_device);
191 189
192 /* Set up frontlight so that screen is readable */ 190 /* Set up frontlight so that screen is readable */
193 locomobl_data.brightness = 2; 191 locomolcd_bl_device->props.max_brightness = 4,
192 locomolcd_bl_device->props.brightness = 2;
194 locomolcd_set_intensity(locomolcd_bl_device); 193 locomolcd_set_intensity(locomolcd_bl_device);
195 194
196 return 0; 195 return 0;
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
new file mode 100644
index 000000000000..702269357861
--- /dev/null
+++ b/drivers/video/backlight/progear_bl.c
@@ -0,0 +1,153 @@
1/*
2 * Backlight Driver for Frontpath ProGear HX1050+
3 *
4 * Copyright (c) 2006 Marcin Juszkiewicz
5 *
6 * Based on Progear LCD driver by M Schacht
7 * <mschacht at alumni dot washington dot edu>
8 *
9 * Based on Sharp's Corgi Backlight Driver
10 * Based on Backlight Driver for HP Jornada 680
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/mutex.h>
23#include <linux/fb.h>
24#include <linux/backlight.h>
25#include <linux/pci.h>
26#include <asm/uaccess.h>
27
28#define PMU_LPCR 0xB0
29#define SB_MPS1 0x61
30#define HW_LEVEL_MAX 0x77
31#define HW_LEVEL_MIN 0x4f
32
33static struct pci_dev *pmu_dev = NULL;
34static struct pci_dev *sb_dev = NULL;
35
36static int progearbl_set_intensity(struct backlight_device *bd)
37{
38 int intensity = bd->props.brightness;
39
40 if (bd->props.power != FB_BLANK_UNBLANK)
41 intensity = 0;
42 if (bd->props.fb_blank != FB_BLANK_UNBLANK)
43 intensity = 0;
44
45 pci_write_config_byte(pmu_dev, PMU_LPCR, intensity + HW_LEVEL_MIN);
46
47 return 0;
48}
49
50static int progearbl_get_intensity(struct backlight_device *bd)
51{
52 u8 intensity;
53 pci_read_config_byte(pmu_dev, PMU_LPCR, &intensity);
54
55 return intensity - HW_LEVEL_MIN;
56}
57
58static struct backlight_ops progearbl_ops = {
59 .get_brightness = progearbl_get_intensity,
60 .update_status = progearbl_set_intensity,
61};
62
63static int progearbl_probe(struct platform_device *pdev)
64{
65 u8 temp;
66 struct backlight_device *progear_backlight_device;
67
68 pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, 0);
69 if (!pmu_dev) {
70 printk("ALI M7101 PMU not found.\n");
71 return -ENODEV;
72 }
73
74 sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, 0);
75 if (!sb_dev) {
76 printk("ALI 1533 SB not found.\n");
77 pci_dev_put(pmu_dev);
78 return -ENODEV;
79 }
80
81 /* Set SB_MPS1 to enable brightness control. */
82 pci_read_config_byte(sb_dev, SB_MPS1, &temp);
83 pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
84
85 progear_backlight_device = backlight_device_register("progear-bl",
86 &pdev->dev, NULL,
87 &progearbl_ops);
88 if (IS_ERR(progear_backlight_device))
89 return PTR_ERR(progear_backlight_device);
90
91 platform_set_drvdata(pdev, progear_backlight_device);
92
93 progear_backlight_device->props.power = FB_BLANK_UNBLANK;
94 progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
95 progear_backlight_device->props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
96 progearbl_set_intensity(progear_backlight_device);
97
98 return 0;
99}
100
101static int progearbl_remove(struct platform_device *pdev)
102{
103 struct backlight_device *bd = platform_get_drvdata(pdev);
104 backlight_device_unregister(bd);
105
106 return 0;
107}
108
109static struct platform_driver progearbl_driver = {
110 .probe = progearbl_probe,
111 .remove = progearbl_remove,
112 .driver = {
113 .name = "progear-bl",
114 },
115};
116
117static struct platform_device *progearbl_device;
118
119static int __init progearbl_init(void)
120{
121 int ret = platform_driver_register(&progearbl_driver);
122
123 if (!ret) {
124 progearbl_device = platform_device_alloc("progear-bl", -1);
125 if (!progearbl_device)
126 return -ENOMEM;
127
128 ret = platform_device_add(progearbl_device);
129
130 if (ret) {
131 platform_device_put(progearbl_device);
132 platform_driver_unregister(&progearbl_driver);
133 }
134 }
135
136 return ret;
137}
138
139static void __exit progearbl_exit(void)
140{
141 pci_dev_put(pmu_dev);
142 pci_dev_put(sb_dev);
143
144 platform_device_unregister(progearbl_device);
145 platform_driver_unregister(&progearbl_driver);
146}
147
148module_init(progearbl_init);
149module_exit(progearbl_exit);
150
151MODULE_AUTHOR("Marcin Juszkiewicz <linux@hrw.one.pl>");
152MODULE_DESCRIPTION("ProGear Backlight Driver");
153MODULE_LICENSE("GPL");
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 73cb426bf2d7..af313bf1a2da 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -145,26 +145,6 @@ static int chipsfb_set_par(struct fb_info *info)
145 145
146static int chipsfb_blank(int blank, struct fb_info *info) 146static int chipsfb_blank(int blank, struct fb_info *info)
147{ 147{
148#ifdef CONFIG_PMAC_BACKLIGHT
149 mutex_lock(&pmac_backlight_mutex);
150
151 if (pmac_backlight) {
152 /* used to disable backlight only for blank > 1, but it seems
153 * useful at blank = 1 too (saves battery, extends backlight
154 * life)
155 */
156 down(&pmac_backlight->sem);
157 if (blank)
158 pmac_backlight->props->power = FB_BLANK_POWERDOWN;
159 else
160 pmac_backlight->props->power = FB_BLANK_UNBLANK;
161 pmac_backlight->props->update_status(pmac_backlight);
162 up(&pmac_backlight->sem);
163 }
164
165 mutex_unlock(&pmac_backlight_mutex);
166#endif /* CONFIG_PMAC_BACKLIGHT */
167
168 return 1; /* get fb_blank to set the colormap to all black */ 148 return 1; /* get fb_blank to set the colormap to all black */
169} 149}
170 150
@@ -415,10 +395,8 @@ chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
415 /* turn on the backlight */ 395 /* turn on the backlight */
416 mutex_lock(&pmac_backlight_mutex); 396 mutex_lock(&pmac_backlight_mutex);
417 if (pmac_backlight) { 397 if (pmac_backlight) {
418 down(&pmac_backlight->sem); 398 pmac_backlight->props.power = FB_BLANK_UNBLANK;
419 pmac_backlight->props->power = FB_BLANK_UNBLANK; 399 backlight_update_status(pmac_backlight);
420 pmac_backlight->props->update_status(pmac_backlight);
421 up(&pmac_backlight->sem);
422 } 400 }
423 mutex_unlock(&pmac_backlight_mutex); 401 mutex_unlock(&pmac_backlight_mutex);
424#endif /* CONFIG_PMAC_BACKLIGHT */ 402#endif /* CONFIG_PMAC_BACKLIGHT */
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index be3f2c3f132c..0429fd2cece0 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2233,6 +2233,8 @@ static int fbcon_switch(struct vc_data *vc)
2233static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, 2233static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
2234 int blank) 2234 int blank)
2235{ 2235{
2236 struct fb_event event;
2237
2236 if (blank) { 2238 if (blank) {
2237 unsigned short charmask = vc->vc_hi_font_mask ? 2239 unsigned short charmask = vc->vc_hi_font_mask ?
2238 0x1ff : 0xff; 2240 0x1ff : 0xff;
@@ -2243,6 +2245,11 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
2243 fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols); 2245 fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
2244 vc->vc_video_erase_char = oldc; 2246 vc->vc_video_erase_char = oldc;
2245 } 2247 }
2248
2249
2250 event.info = info;
2251 event.data = &blank;
2252 fb_notifier_call_chain(FB_EVENT_CONBLANK, &event);
2246} 2253}
2247 2254
2248static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) 2255static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 818fb09105f9..40c80c8190e2 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -59,7 +59,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
59 info->device = dev; 59 info->device = dev;
60 60
61#ifdef CONFIG_FB_BACKLIGHT 61#ifdef CONFIG_FB_BACKLIGHT
62 mutex_init(&info->bl_mutex); 62 mutex_init(&info->bl_curve_mutex);
63#endif 63#endif
64 64
65 return info; 65 return info;
@@ -445,10 +445,10 @@ static ssize_t store_bl_curve(struct device *device,
445 /* If there has been an error in the input data, we won't 445 /* If there has been an error in the input data, we won't
446 * reach this loop. 446 * reach this loop.
447 */ 447 */
448 mutex_lock(&fb_info->bl_mutex); 448 mutex_lock(&fb_info->bl_curve_mutex);
449 for (i = 0; i < FB_BACKLIGHT_LEVELS; ++i) 449 for (i = 0; i < FB_BACKLIGHT_LEVELS; ++i)
450 fb_info->bl_curve[i] = tmp_curve[i]; 450 fb_info->bl_curve[i] = tmp_curve[i];
451 mutex_unlock(&fb_info->bl_mutex); 451 mutex_unlock(&fb_info->bl_curve_mutex);
452 452
453 return count; 453 return count;
454} 454}
@@ -466,7 +466,7 @@ static ssize_t show_bl_curve(struct device *device,
466 if (!fb_info || !fb_info->bl_dev) 466 if (!fb_info || !fb_info->bl_dev)
467 return -ENODEV; 467 return -ENODEV;
468 468
469 mutex_lock(&fb_info->bl_mutex); 469 mutex_lock(&fb_info->bl_curve_mutex);
470 for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8) 470 for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8)
471 len += snprintf(&buf[len], PAGE_SIZE, 471 len += snprintf(&buf[len], PAGE_SIZE,
472 "%02x %02x %02x %02x %02x %02x %02x %02x\n", 472 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
@@ -478,7 +478,7 @@ static ssize_t show_bl_curve(struct device *device,
478 fb_info->bl_curve[i + 5], 478 fb_info->bl_curve[i + 5],
479 fb_info->bl_curve[i + 6], 479 fb_info->bl_curve[i + 6],
480 fb_info->bl_curve[i + 7]); 480 fb_info->bl_curve[i + 7]);
481 mutex_unlock(&fb_info->bl_mutex); 481 mutex_unlock(&fb_info->bl_curve_mutex);
482 482
483 return len; 483 return len;
484} 484}
@@ -552,6 +552,8 @@ void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max)
552{ 552{
553 unsigned int i, flat, count, range = (max - min); 553 unsigned int i, flat, count, range = (max - min);
554 554
555 mutex_lock(&fb_info->bl_curve_mutex);
556
555 fb_info->bl_curve[0] = off; 557 fb_info->bl_curve[0] = off;
556 558
557 for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat) 559 for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat)
@@ -560,6 +562,8 @@ void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max)
560 count = FB_BACKLIGHT_LEVELS * 15 / 16; 562 count = FB_BACKLIGHT_LEVELS * 15 / 16;
561 for (i = 0; i < count; ++i) 563 for (i = 0; i < count; ++i)
562 fb_info->bl_curve[flat + i] = min + (range * (i + 1) / count); 564 fb_info->bl_curve[flat + i] = min + (range * (i + 1) / count);
565
566 mutex_unlock(&fb_info->bl_curve_mutex);
563} 567}
564EXPORT_SYMBOL_GPL(fb_bl_default_curve); 568EXPORT_SYMBOL_GPL(fb_bl_default_curve);
565#endif 569#endif
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index df934bd21899..b7016e9b9e13 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -16,11 +16,6 @@
16#include "nv_type.h" 16#include "nv_type.h"
17#include "nv_proto.h" 17#include "nv_proto.h"
18 18
19#ifdef CONFIG_PMAC_BACKLIGHT
20#include <asm/backlight.h>
21#include <asm/machdep.h>
22#endif
23
24/* We do not have any information about which values are allowed, thus 19/* We do not have any information about which values are allowed, thus
25 * we used safe values. 20 * we used safe values.
26 */ 21 */
@@ -30,7 +25,6 @@
30 25
31static struct backlight_properties nvidia_bl_data; 26static struct backlight_properties nvidia_bl_data;
32 27
33/* Call with fb_info->bl_mutex held */
34static int nvidia_bl_get_level_brightness(struct nvidia_par *par, 28static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
35 int level) 29 int level)
36{ 30{
@@ -38,6 +32,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
38 int nlevel; 32 int nlevel;
39 33
40 /* Get and convert the value */ 34 /* Get and convert the value */
35 /* No locking of bl_curve since we read a single value */
41 nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; 36 nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
42 37
43 if (nlevel < 0) 38 if (nlevel < 0)
@@ -50,8 +45,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
50 return nlevel; 45 return nlevel;
51} 46}
52 47
53/* Call with fb_info->bl_mutex held */ 48static int nvidia_bl_update_status(struct backlight_device *bd)
54static int __nvidia_bl_update_status(struct backlight_device *bd)
55{ 49{
56 struct nvidia_par *par = class_get_devdata(&bd->class_dev); 50 struct nvidia_par *par = class_get_devdata(&bd->class_dev);
57 u32 tmp_pcrt, tmp_pmc, fpcontrol; 51 u32 tmp_pcrt, tmp_pmc, fpcontrol;
@@ -60,11 +54,11 @@ static int __nvidia_bl_update_status(struct backlight_device *bd)
60 if (!par->FlatPanel) 54 if (!par->FlatPanel)
61 return 0; 55 return 0;
62 56
63 if (bd->props->power != FB_BLANK_UNBLANK || 57 if (bd->props.power != FB_BLANK_UNBLANK ||
64 bd->props->fb_blank != FB_BLANK_UNBLANK) 58 bd->props.fb_blank != FB_BLANK_UNBLANK)
65 level = 0; 59 level = 0;
66 else 60 else
67 level = bd->props->brightness; 61 level = bd->props.brightness;
68 62
69 tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF; 63 tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF;
70 tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC; 64 tmp_pcrt = NV_RD32(par->PCRTC0, 0x081C) & 0xFFFFFFFC;
@@ -85,45 +79,16 @@ static int __nvidia_bl_update_status(struct backlight_device *bd)
85 return 0; 79 return 0;
86} 80}
87 81
88static int nvidia_bl_update_status(struct backlight_device *bd)
89{
90 struct nvidia_par *par = class_get_devdata(&bd->class_dev);
91 struct fb_info *info = pci_get_drvdata(par->pci_dev);
92 int ret;
93
94 mutex_lock(&info->bl_mutex);
95 ret = __nvidia_bl_update_status(bd);
96 mutex_unlock(&info->bl_mutex);
97
98 return ret;
99}
100
101static int nvidia_bl_get_brightness(struct backlight_device *bd) 82static int nvidia_bl_get_brightness(struct backlight_device *bd)
102{ 83{
103 return bd->props->brightness; 84 return bd->props.brightness;
104} 85}
105 86
106static struct backlight_properties nvidia_bl_data = { 87static struct backlight_ops nvidia_bl_ops = {
107 .owner = THIS_MODULE,
108 .get_brightness = nvidia_bl_get_brightness, 88 .get_brightness = nvidia_bl_get_brightness,
109 .update_status = nvidia_bl_update_status, 89 .update_status = nvidia_bl_update_status,
110 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
111}; 90};
112 91
113void nvidia_bl_set_power(struct fb_info *info, int power)
114{
115 mutex_lock(&info->bl_mutex);
116
117 if (info->bl_dev) {
118 down(&info->bl_dev->sem);
119 info->bl_dev->props->power = power;
120 __nvidia_bl_update_status(info->bl_dev);
121 up(&info->bl_dev->sem);
122 }
123
124 mutex_unlock(&info->bl_mutex);
125}
126
127void nvidia_bl_init(struct nvidia_par *par) 92void nvidia_bl_init(struct nvidia_par *par)
128{ 93{
129 struct fb_info *info = pci_get_drvdata(par->pci_dev); 94 struct fb_info *info = pci_get_drvdata(par->pci_dev);
@@ -141,32 +106,22 @@ void nvidia_bl_init(struct nvidia_par *par)
141 106
142 snprintf(name, sizeof(name), "nvidiabl%d", info->node); 107 snprintf(name, sizeof(name), "nvidiabl%d", info->node);
143 108
144 bd = backlight_device_register(name, info->dev, par, &nvidia_bl_data); 109 bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops);
145 if (IS_ERR(bd)) { 110 if (IS_ERR(bd)) {
146 info->bl_dev = NULL; 111 info->bl_dev = NULL;
147 printk(KERN_WARNING "nvidia: Backlight registration failed\n"); 112 printk(KERN_WARNING "nvidia: Backlight registration failed\n");
148 goto error; 113 goto error;
149 } 114 }
150 115
151 mutex_lock(&info->bl_mutex);
152 info->bl_dev = bd; 116 info->bl_dev = bd;
153 fb_bl_default_curve(info, 0, 117 fb_bl_default_curve(info, 0,
154 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, 118 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
155 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); 119 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
156 mutex_unlock(&info->bl_mutex);
157 120
158 down(&bd->sem); 121 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
159 bd->props->brightness = nvidia_bl_data.max_brightness; 122 bd->props.brightness = nvidia_bl_data.max_brightness;
160 bd->props->power = FB_BLANK_UNBLANK; 123 bd->props.power = FB_BLANK_UNBLANK;
161 bd->props->update_status(bd); 124 backlight_update_status(bd);
162 up(&bd->sem);
163
164#ifdef CONFIG_PMAC_BACKLIGHT
165 mutex_lock(&pmac_backlight_mutex);
166 if (!pmac_backlight)
167 pmac_backlight = bd;
168 mutex_unlock(&pmac_backlight_mutex);
169#endif
170 125
171 printk("nvidia: Backlight initialized (%s)\n", name); 126 printk("nvidia: Backlight initialized (%s)\n", name);
172 127
@@ -179,25 +134,8 @@ error:
179void nvidia_bl_exit(struct nvidia_par *par) 134void nvidia_bl_exit(struct nvidia_par *par)
180{ 135{
181 struct fb_info *info = pci_get_drvdata(par->pci_dev); 136 struct fb_info *info = pci_get_drvdata(par->pci_dev);
137 struct backlight_device *bd = info->bl_dev;
182 138
183#ifdef CONFIG_PMAC_BACKLIGHT 139 backlight_device_unregister(bd);
184 mutex_lock(&pmac_backlight_mutex); 140 printk("nvidia: Backlight unloaded\n");
185#endif
186
187 mutex_lock(&info->bl_mutex);
188 if (info->bl_dev) {
189#ifdef CONFIG_PMAC_BACKLIGHT
190 if (pmac_backlight == info->bl_dev)
191 pmac_backlight = NULL;
192#endif
193
194 backlight_device_unregister(info->bl_dev);
195
196 printk("nvidia: Backlight unloaded\n");
197 }
198 mutex_unlock(&info->bl_mutex);
199
200#ifdef CONFIG_PMAC_BACKLIGHT
201 mutex_unlock(&pmac_backlight_mutex);
202#endif
203} 141}
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index 43058d0cf5b7..ff5c410355ea 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -67,11 +67,9 @@ extern int nvidiafb_sync(struct fb_info *info);
67#ifdef CONFIG_FB_NVIDIA_BACKLIGHT 67#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
68extern void nvidia_bl_init(struct nvidia_par *par); 68extern void nvidia_bl_init(struct nvidia_par *par);
69extern void nvidia_bl_exit(struct nvidia_par *par); 69extern void nvidia_bl_exit(struct nvidia_par *par);
70extern void nvidia_bl_set_power(struct fb_info *info, int power);
71#else 70#else
72static inline void nvidia_bl_init(struct nvidia_par *par) {} 71static inline void nvidia_bl_init(struct nvidia_par *par) {}
73static inline void nvidia_bl_exit(struct nvidia_par *par) {} 72static inline void nvidia_bl_exit(struct nvidia_par *par) {}
74static inline void nvidia_bl_set_power(struct fb_info *info, int power) {}
75#endif 73#endif
76 74
77#endif /* __NV_PROTO_H__ */ 75#endif /* __NV_PROTO_H__ */
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 8e5b484db649..c18e9557ca30 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -938,8 +938,6 @@ static int nvidiafb_blank(int blank, struct fb_info *info)
938 NVWriteSeq(par, 0x01, tmp); 938 NVWriteSeq(par, 0x01, tmp);
939 NVWriteCrtc(par, 0x1a, vesa); 939 NVWriteCrtc(par, 0x1a, vesa);
940 940
941 nvidia_bl_set_power(info, blank);
942
943 NVTRACE_LEAVE(); 941 NVTRACE_LEAVE();
944 942
945 return 0; 943 return 0;
@@ -1352,9 +1350,10 @@ static void __devexit nvidiafb_remove(struct pci_dev *pd)
1352 1350
1353 NVTRACE_ENTER(); 1351 NVTRACE_ENTER();
1354 1352
1353 unregister_framebuffer(info);
1354
1355 nvidia_bl_exit(par); 1355 nvidia_bl_exit(par);
1356 1356
1357 unregister_framebuffer(info);
1358#ifdef CONFIG_MTRR 1357#ifdef CONFIG_MTRR
1359 if (par->mtrr.vram_valid) 1358 if (par->mtrr.vram_valid)
1360 mtrr_del(par->mtrr.vram, info->fix.smem_start, 1359 mtrr_del(par->mtrr.vram, info->fix.smem_start,
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index f2e9b742c92f..f8a3d608b208 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -282,7 +282,6 @@ static const struct riva_regs reg_template = {
282 282
283static struct backlight_properties riva_bl_data; 283static struct backlight_properties riva_bl_data;
284 284
285/* Call with fb_info->bl_mutex held */
286static int riva_bl_get_level_brightness(struct riva_par *par, 285static int riva_bl_get_level_brightness(struct riva_par *par,
287 int level) 286 int level)
288{ 287{
@@ -290,6 +289,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par,
290 int nlevel; 289 int nlevel;
291 290
292 /* Get and convert the value */ 291 /* Get and convert the value */
292 /* No locking on bl_curve since accessing a single value */
293 nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; 293 nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
294 294
295 if (nlevel < 0) 295 if (nlevel < 0)
@@ -302,18 +302,17 @@ static int riva_bl_get_level_brightness(struct riva_par *par,
302 return nlevel; 302 return nlevel;
303} 303}
304 304
305/* Call with fb_info->bl_mutex held */ 305static int riva_bl_update_status(struct backlight_device *bd)
306static int __riva_bl_update_status(struct backlight_device *bd)
307{ 306{
308 struct riva_par *par = class_get_devdata(&bd->class_dev); 307 struct riva_par *par = class_get_devdata(&bd->class_dev);
309 U032 tmp_pcrt, tmp_pmc; 308 U032 tmp_pcrt, tmp_pmc;
310 int level; 309 int level;
311 310
312 if (bd->props->power != FB_BLANK_UNBLANK || 311 if (bd->props.power != FB_BLANK_UNBLANK ||
313 bd->props->fb_blank != FB_BLANK_UNBLANK) 312 bd->props.fb_blank != FB_BLANK_UNBLANK)
314 level = 0; 313 level = 0;
315 else 314 else
316 level = bd->props->brightness; 315 level = bd->props.brightness;
317 316
318 tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF; 317 tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF;
319 tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC; 318 tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC;
@@ -328,45 +327,16 @@ static int __riva_bl_update_status(struct backlight_device *bd)
328 return 0; 327 return 0;
329} 328}
330 329
331static int riva_bl_update_status(struct backlight_device *bd)
332{
333 struct riva_par *par = class_get_devdata(&bd->class_dev);
334 struct fb_info *info = pci_get_drvdata(par->pdev);
335 int ret;
336
337 mutex_lock(&info->bl_mutex);
338 ret = __riva_bl_update_status(bd);
339 mutex_unlock(&info->bl_mutex);
340
341 return ret;
342}
343
344static int riva_bl_get_brightness(struct backlight_device *bd) 330static int riva_bl_get_brightness(struct backlight_device *bd)
345{ 331{
346 return bd->props->brightness; 332 return bd->props.brightness;
347} 333}
348 334
349static struct backlight_properties riva_bl_data = { 335static struct backlight_ops riva_bl_ops = {
350 .owner = THIS_MODULE,
351 .get_brightness = riva_bl_get_brightness, 336 .get_brightness = riva_bl_get_brightness,
352 .update_status = riva_bl_update_status, 337 .update_status = riva_bl_update_status,
353 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
354}; 338};
355 339
356static void riva_bl_set_power(struct fb_info *info, int power)
357{
358 mutex_lock(&info->bl_mutex);
359
360 if (info->bl_dev) {
361 down(&info->bl_dev->sem);
362 info->bl_dev->props->power = power;
363 __riva_bl_update_status(info->bl_dev);
364 up(&info->bl_dev->sem);
365 }
366
367 mutex_unlock(&info->bl_mutex);
368}
369
370static void riva_bl_init(struct riva_par *par) 340static void riva_bl_init(struct riva_par *par)
371{ 341{
372 struct fb_info *info = pci_get_drvdata(par->pdev); 342 struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -384,32 +354,22 @@ static void riva_bl_init(struct riva_par *par)
384 354
385 snprintf(name, sizeof(name), "rivabl%d", info->node); 355 snprintf(name, sizeof(name), "rivabl%d", info->node);
386 356
387 bd = backlight_device_register(name, info->dev, par, &riva_bl_data); 357 bd = backlight_device_register(name, info->dev, par, &riva_bl_ops);
388 if (IS_ERR(bd)) { 358 if (IS_ERR(bd)) {
389 info->bl_dev = NULL; 359 info->bl_dev = NULL;
390 printk(KERN_WARNING "riva: Backlight registration failed\n"); 360 printk(KERN_WARNING "riva: Backlight registration failed\n");
391 goto error; 361 goto error;
392 } 362 }
393 363
394 mutex_lock(&info->bl_mutex);
395 info->bl_dev = bd; 364 info->bl_dev = bd;
396 fb_bl_default_curve(info, 0, 365 fb_bl_default_curve(info, 0,
397 MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, 366 MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
398 FB_BACKLIGHT_MAX); 367 FB_BACKLIGHT_MAX);
399 mutex_unlock(&info->bl_mutex);
400
401 down(&bd->sem);
402 bd->props->brightness = riva_bl_data.max_brightness;
403 bd->props->power = FB_BLANK_UNBLANK;
404 bd->props->update_status(bd);
405 up(&bd->sem);
406 368
407#ifdef CONFIG_PMAC_BACKLIGHT 369 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
408 mutex_lock(&pmac_backlight_mutex); 370 bd->props.brightness = riva_bl_data.max_brightness;
409 if (!pmac_backlight) 371 bd->props.power = FB_BLANK_UNBLANK;
410 pmac_backlight = bd; 372 backlight_update_status(bd);
411 mutex_unlock(&pmac_backlight_mutex);
412#endif
413 373
414 printk("riva: Backlight initialized (%s)\n", name); 374 printk("riva: Backlight initialized (%s)\n", name);
415 375
@@ -419,35 +379,16 @@ error:
419 return; 379 return;
420} 380}
421 381
422static void riva_bl_exit(struct riva_par *par) 382static void riva_bl_exit(struct fb_info *info)
423{ 383{
424 struct fb_info *info = pci_get_drvdata(par->pdev); 384 struct backlight_device *bd = info->bl_dev;
425
426#ifdef CONFIG_PMAC_BACKLIGHT
427 mutex_lock(&pmac_backlight_mutex);
428#endif
429
430 mutex_lock(&info->bl_mutex);
431 if (info->bl_dev) {
432#ifdef CONFIG_PMAC_BACKLIGHT
433 if (pmac_backlight == info->bl_dev)
434 pmac_backlight = NULL;
435#endif
436 385
437 backlight_device_unregister(info->bl_dev); 386 backlight_device_unregister(bd);
438 387 printk("riva: Backlight unloaded\n");
439 printk("riva: Backlight unloaded\n");
440 }
441 mutex_unlock(&info->bl_mutex);
442
443#ifdef CONFIG_PMAC_BACKLIGHT
444 mutex_unlock(&pmac_backlight_mutex);
445#endif
446} 388}
447#else 389#else
448static inline void riva_bl_init(struct riva_par *par) {} 390static inline void riva_bl_init(struct riva_par *par) {}
449static inline void riva_bl_exit(struct riva_par *par) {} 391static inline void riva_bl_exit(struct fb_info *info) {}
450static inline void riva_bl_set_power(struct fb_info *info, int power) {}
451#endif /* CONFIG_FB_RIVA_BACKLIGHT */ 392#endif /* CONFIG_FB_RIVA_BACKLIGHT */
452 393
453/* ------------------------------------------------------------------------- * 394/* ------------------------------------------------------------------------- *
@@ -1348,8 +1289,6 @@ static int rivafb_blank(int blank, struct fb_info *info)
1348 SEQout(par, 0x01, tmp); 1289 SEQout(par, 0x01, tmp);
1349 CRTCout(par, 0x1a, vesa); 1290 CRTCout(par, 0x1a, vesa);
1350 1291
1351 riva_bl_set_power(info, blank);
1352
1353 NVTRACE_LEAVE(); 1292 NVTRACE_LEAVE();
1354 1293
1355 return 0; 1294 return 0;
@@ -2166,14 +2105,15 @@ static void __exit rivafb_remove(struct pci_dev *pd)
2166 2105
2167 NVTRACE_ENTER(); 2106 NVTRACE_ENTER();
2168 2107
2169 riva_bl_exit(par);
2170
2171#ifdef CONFIG_FB_RIVA_I2C 2108#ifdef CONFIG_FB_RIVA_I2C
2172 riva_delete_i2c_busses(par); 2109 riva_delete_i2c_busses(par);
2173 kfree(par->EDID); 2110 kfree(par->EDID);
2174#endif 2111#endif
2175 2112
2176 unregister_framebuffer(info); 2113 unregister_framebuffer(info);
2114
2115 riva_bl_exit(info);
2116
2177#ifdef CONFIG_MTRR 2117#ifdef CONFIG_MTRR
2178 if (par->mtrr.vram_valid) 2118 if (par->mtrr.vram_valid)
2179 mtrr_del(par->mtrr.vram, info->fix.smem_start, 2119 mtrr_del(par->mtrr.vram, info->fix.smem_start,