aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS5
-rw-r--r--arch/mips/cobalt/Makefile1
-rw-r--r--arch/mips/cobalt/mtd.c61
-rw-r--r--arch/mips/configs/cobalt_defconfig86
-rw-r--r--arch/mips/emma2rh/common/irq.c1
-rw-r--r--arch/mips/emma2rh/markeins/irq.c1
-rw-r--r--arch/mips/kernel/i8259.c13
-rw-r--r--arch/mips/kernel/signal32.c9
-rw-r--r--arch/mips/kernel/traps.c2
-rw-r--r--arch/mips/momentum/jaguar_atx/platform.c21
-rw-r--r--arch/mips/momentum/ocelot_3/platform.c21
-rw-r--r--arch/mips/momentum/ocelot_c/platform.c14
-rw-r--r--arch/mips/oprofile/Kconfig2
-rw-r--r--arch/powerpc/kernel/traps.c6
-rw-r--r--arch/powerpc/platforms/powermac/backlight.c27
-rw-r--r--arch/ppc/Kconfig15
-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/char/lcd.c168
-rw-r--r--drivers/char/lcd.h32
-rw-r--r--drivers/char/tty_io.c5
-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/net/8139too.c40
-rw-r--r--drivers/net/Kconfig21
-rw-r--r--drivers/net/hamradio/baycom_epp.c13
-rw-r--r--drivers/net/hamradio/hdlcdrv.c13
-rw-r--r--drivers/net/hamradio/yam.c11
-rw-r--r--drivers/net/natsemi.c43
-rw-r--r--drivers/net/r8169.c25
-rw-r--r--drivers/net/s2io.c21
-rw-r--r--drivers/net/sis190.c7
-rw-r--r--drivers/net/skge.c9
-rw-r--r--drivers/net/wireless/airo.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h8
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ilt.c15
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ilt.h1
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c20
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c195
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.c13
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.h10
-rw-r--r--drivers/net/wireless/hostap/hostap.h3
-rw-r--r--drivers/net/wireless/ipw2100.c14
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c8
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c4
-rw-r--r--drivers/net/wireless/wavelan.c14
-rw-r--r--drivers/net/wireless/wavelan.p.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c2
-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
-rw-r--r--include/linux/backlight.h50
-rw-r--r--include/linux/fb.h13
-rw-r--r--include/linux/lcd.h45
-rw-r--r--include/linux/wireless.h4
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c13
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c11
80 files changed, 1068 insertions, 1324 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 6261597a1bce..6fc033f22751 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -679,6 +679,11 @@ L: linux-hams@vger.kernel.org
679W: http://www.linux-ax25.org/ 679W: http://www.linux-ax25.org/
680S: Maintained 680S: Maintained
681 681
682BACKLIGHT CLASS/SUBSYSTEM
683P: Richard Purdie
684M: rpurdie@rpsys.net
685S: Maintained
686
682BAYCOM/HDLCDRV DRIVERS FOR AX.25 687BAYCOM/HDLCDRV DRIVERS FOR AX.25
683P: Thomas Sailer 688P: Thomas Sailer
684M: t.sailer@alumni.ethz.ch 689M: t.sailer@alumni.ethz.ch
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index 225ac8f34ccd..12589a1ff048 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -5,5 +5,6 @@
5obj-y := irq.o reset.o setup.o 5obj-y := irq.o reset.o setup.o
6 6
7obj-$(CONFIG_EARLY_PRINTK) += console.o 7obj-$(CONFIG_EARLY_PRINTK) += console.o
8obj-$(CONFIG_MTD_PHYSMAP) += mtd.o
8 9
9EXTRA_AFLAGS := $(CFLAGS) 10EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/cobalt/mtd.c b/arch/mips/cobalt/mtd.c
new file mode 100644
index 000000000000..01d8ec77fe9c
--- /dev/null
+++ b/arch/mips/cobalt/mtd.c
@@ -0,0 +1,61 @@
1/*
2 * Registration of Cobalt MTD device.
3 *
4 * Copyright (C) 2006 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/mtd/partitions.h>
23#include <linux/mtd/physmap.h>
24
25static struct mtd_partition cobalt_mtd_partitions[] = {
26 {
27 .name = "Colo",
28 .offset = 0x0,
29 .size = 0x80000,
30 },
31};
32
33static struct physmap_flash_data cobalt_flash_data = {
34 .width = 1,
35 .nr_parts = 1,
36 .parts = cobalt_mtd_partitions,
37};
38
39static struct resource cobalt_mtd_resource = {
40 .start = 0x1fc00000,
41 .end = 0x1fc7ffff,
42 .flags = IORESOURCE_MEM,
43};
44
45static struct platform_device cobalt_mtd = {
46 .name = "physmap-flash",
47 .dev = {
48 .platform_data = &cobalt_flash_data,
49 },
50 .num_resources = 1,
51 .resource = &cobalt_mtd_resource,
52};
53
54static int __init cobalt_mtd_init(void)
55{
56 platform_device_register(&cobalt_mtd);
57
58 return 0;
59}
60
61module_init(cobalt_mtd_init);
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 1a3d776ad1e4..f88c40fc9948 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20 3# Linux kernel version: 2.6.20
4# Sun Feb 18 21:27:37 2007 4# Mon Feb 19 14:51:58 2007
5# 5#
6CONFIG_MIPS=y 6CONFIG_MIPS=y
7 7
@@ -373,7 +373,88 @@ CONFIG_PROC_EVENTS=y
373# 373#
374# Memory Technology Devices (MTD) 374# Memory Technology Devices (MTD)
375# 375#
376# CONFIG_MTD is not set 376CONFIG_MTD=y
377# CONFIG_MTD_DEBUG is not set
378# CONFIG_MTD_CONCAT is not set
379CONFIG_MTD_PARTITIONS=y
380# CONFIG_MTD_REDBOOT_PARTS is not set
381# CONFIG_MTD_CMDLINE_PARTS is not set
382
383#
384# User Modules And Translation Layers
385#
386CONFIG_MTD_CHAR=y
387CONFIG_MTD_BLKDEVS=y
388# CONFIG_MTD_BLOCK is not set
389# CONFIG_MTD_BLOCK_RO is not set
390# CONFIG_FTL is not set
391# CONFIG_NFTL is not set
392# CONFIG_INFTL is not set
393# CONFIG_RFD_FTL is not set
394# CONFIG_SSFDC is not set
395
396#
397# RAM/ROM/Flash chip drivers
398#
399# CONFIG_MTD_CFI is not set
400CONFIG_MTD_JEDECPROBE=y
401CONFIG_MTD_GEN_PROBE=y
402# CONFIG_MTD_CFI_ADV_OPTIONS is not set
403CONFIG_MTD_MAP_BANK_WIDTH_1=y
404CONFIG_MTD_MAP_BANK_WIDTH_2=y
405CONFIG_MTD_MAP_BANK_WIDTH_4=y
406# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
407# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
408# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
409CONFIG_MTD_CFI_I1=y
410CONFIG_MTD_CFI_I2=y
411# CONFIG_MTD_CFI_I4 is not set
412# CONFIG_MTD_CFI_I8 is not set
413# CONFIG_MTD_CFI_INTELEXT is not set
414CONFIG_MTD_CFI_AMDSTD=y
415# CONFIG_MTD_CFI_STAA is not set
416CONFIG_MTD_CFI_UTIL=y
417# CONFIG_MTD_RAM is not set
418# CONFIG_MTD_ROM is not set
419# CONFIG_MTD_ABSENT is not set
420# CONFIG_MTD_OBSOLETE_CHIPS is not set
421
422#
423# Mapping drivers for chip access
424#
425# CONFIG_MTD_COMPLEX_MAPPINGS is not set
426CONFIG_MTD_PHYSMAP=y
427CONFIG_MTD_PHYSMAP_START=0x0
428CONFIG_MTD_PHYSMAP_LEN=0
429CONFIG_MTD_PHYSMAP_BANKWIDTH=0
430# CONFIG_MTD_PLATRAM is not set
431
432#
433# Self-contained MTD device drivers
434#
435# CONFIG_MTD_PMC551 is not set
436# CONFIG_MTD_SLRAM is not set
437# CONFIG_MTD_PHRAM is not set
438# CONFIG_MTD_MTDRAM is not set
439# CONFIG_MTD_BLOCK2MTD is not set
440
441#
442# Disk-On-Chip Device Drivers
443#
444# CONFIG_MTD_DOC2000 is not set
445# CONFIG_MTD_DOC2001 is not set
446# CONFIG_MTD_DOC2001PLUS is not set
447
448#
449# NAND Flash Device Drivers
450#
451# CONFIG_MTD_NAND is not set
452# CONFIG_MTD_NAND_CAFE is not set
453
454#
455# OneNAND Flash Device Drivers
456#
457# CONFIG_MTD_ONENAND is not set
377 458
378# 459#
379# Parallel port support 460# Parallel port support
@@ -901,6 +982,7 @@ CONFIG_CONFIGFS_FS=y
901# CONFIG_BEFS_FS is not set 982# CONFIG_BEFS_FS is not set
902# CONFIG_BFS_FS is not set 983# CONFIG_BFS_FS is not set
903# CONFIG_EFS_FS is not set 984# CONFIG_EFS_FS is not set
985# CONFIG_JFFS2_FS is not set
904# CONFIG_CRAMFS is not set 986# CONFIG_CRAMFS is not set
905# CONFIG_VXFS_FS is not set 987# CONFIG_VXFS_FS is not set
906# CONFIG_HPFS_FS is not set 988# CONFIG_HPFS_FS is not set
diff --git a/arch/mips/emma2rh/common/irq.c b/arch/mips/emma2rh/common/irq.c
index c191b3e9d9d9..d95604773667 100644
--- a/arch/mips/emma2rh/common/irq.c
+++ b/arch/mips/emma2rh/common/irq.c
@@ -27,7 +27,6 @@
27#include <linux/irq.h> 27#include <linux/irq.h>
28#include <linux/types.h> 28#include <linux/types.h>
29 29
30#include <asm/i8259.h>
31#include <asm/system.h> 30#include <asm/system.h>
32#include <asm/mipsregs.h> 31#include <asm/mipsregs.h>
33#include <asm/debug.h> 32#include <asm/debug.h>
diff --git a/arch/mips/emma2rh/markeins/irq.c b/arch/mips/emma2rh/markeins/irq.c
index 3299b6dfe764..e26630026375 100644
--- a/arch/mips/emma2rh/markeins/irq.c
+++ b/arch/mips/emma2rh/markeins/irq.c
@@ -29,7 +29,6 @@
29#include <linux/ptrace.h> 29#include <linux/ptrace.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31 31
32#include <asm/i8259.h>
33#include <asm/irq_cpu.h> 32#include <asm/irq_cpu.h>
34#include <asm/system.h> 33#include <asm/system.h>
35#include <asm/mipsregs.h> 34#include <asm/mipsregs.h>
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index b33ba6cd7f5b..9c79703979b2 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -28,7 +28,7 @@
28 * moves to arch independent land 28 * moves to arch independent land
29 */ 29 */
30 30
31static int i8259A_auto_eoi; 31static int i8259A_auto_eoi = -1;
32DEFINE_SPINLOCK(i8259A_lock); 32DEFINE_SPINLOCK(i8259A_lock);
33/* some platforms call this... */ 33/* some platforms call this... */
34void mask_and_ack_8259A(unsigned int); 34void mask_and_ack_8259A(unsigned int);
@@ -216,7 +216,8 @@ spurious_8259A_irq:
216 216
217static int i8259A_resume(struct sys_device *dev) 217static int i8259A_resume(struct sys_device *dev)
218{ 218{
219 init_8259A(i8259A_auto_eoi); 219 if (i8259A_auto_eoi >= 0)
220 init_8259A(i8259A_auto_eoi);
220 return 0; 221 return 0;
221} 222}
222 223
@@ -226,8 +227,10 @@ static int i8259A_shutdown(struct sys_device *dev)
226 * the kernel initialization code can get it 227 * the kernel initialization code can get it
227 * out of. 228 * out of.
228 */ 229 */
229 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ 230 if (i8259A_auto_eoi >= 0) {
230 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ 231 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
232 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */
233 }
231 return 0; 234 return 0;
232} 235}
233 236
@@ -252,7 +255,7 @@ static int __init i8259A_init_sysfs(void)
252 255
253device_initcall(i8259A_init_sysfs); 256device_initcall(i8259A_init_sysfs);
254 257
255void __init init_8259A(int auto_eoi) 258void init_8259A(int auto_eoi)
256{ 259{
257 unsigned long flags; 260 unsigned long flags;
258 261
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 02062fc59f77..19bbef001959 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -108,13 +108,6 @@ typedef struct compat_siginfo {
108 108
109/* 32-bit compatibility types */ 109/* 32-bit compatibility types */
110 110
111#define _NSIG_BPW32 32
112#define _NSIG_WORDS32 (_NSIG / _NSIG_BPW32)
113
114typedef struct {
115 unsigned int sig[_NSIG_WORDS32];
116} sigset_t32;
117
118typedef unsigned int __sighandler32_t; 111typedef unsigned int __sighandler32_t;
119typedef void (*vfptr_t)(void); 112typedef void (*vfptr_t)(void);
120 113
@@ -136,7 +129,7 @@ struct ucontext32 {
136 s32 uc_link; 129 s32 uc_link;
137 stack32_t uc_stack; 130 stack32_t uc_stack;
138 struct sigcontext32 uc_mcontext; 131 struct sigcontext32 uc_mcontext;
139 sigset_t32 uc_sigmask; /* mask last for extensibility */ 132 compat_sigset_t uc_sigmask; /* mask last for extensibility */
140}; 133};
141 134
142/* 135/*
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index f663c63d5dd3..2aa208b99da8 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -704,6 +704,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
704 die_if_kernel("Break instruction in kernel code", regs); 704 die_if_kernel("Break instruction in kernel code", regs);
705 force_sig(SIGTRAP, current); 705 force_sig(SIGTRAP, current);
706 } 706 }
707 return;
707 708
708out_sigsegv: 709out_sigsegv:
709 force_sig(SIGSEGV, current); 710 force_sig(SIGSEGV, current);
@@ -747,6 +748,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
747 die_if_kernel("Trap instruction in kernel code", regs); 748 die_if_kernel("Trap instruction in kernel code", regs);
748 force_sig(SIGTRAP, current); 749 force_sig(SIGTRAP, current);
749 } 750 }
751 return;
750 752
751out_sigsegv: 753out_sigsegv:
752 force_sig(SIGSEGV, current); 754 force_sig(SIGSEGV, current);
diff --git a/arch/mips/momentum/jaguar_atx/platform.c b/arch/mips/momentum/jaguar_atx/platform.c
index 81037709ba0d..c78ba3025af4 100644
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ b/arch/mips/momentum/jaguar_atx/platform.c
@@ -38,8 +38,6 @@ static struct platform_device mv643xx_eth_shared_device = {
38#define MV64x60_IRQ_ETH_1 49 38#define MV64x60_IRQ_ETH_1 49
39#define MV64x60_IRQ_ETH_2 50 39#define MV64x60_IRQ_ETH_2 50
40 40
41#ifdef CONFIG_MV643XX_ETH_0
42
43static struct resource mv64x60_eth0_resources[] = { 41static struct resource mv64x60_eth0_resources[] = {
44 [0] = { 42 [0] = {
45 .name = "eth0 irq", 43 .name = "eth0 irq",
@@ -72,9 +70,6 @@ static struct platform_device eth0_device = {
72 .platform_data = &eth0_pd, 70 .platform_data = &eth0_pd,
73 }, 71 },
74}; 72};
75#endif /* CONFIG_MV643XX_ETH_0 */
76
77#ifdef CONFIG_MV643XX_ETH_1
78 73
79static struct resource mv64x60_eth1_resources[] = { 74static struct resource mv64x60_eth1_resources[] = {
80 [0] = { 75 [0] = {
@@ -108,9 +103,6 @@ static struct platform_device eth1_device = {
108 .platform_data = &eth1_pd, 103 .platform_data = &eth1_pd,
109 }, 104 },
110}; 105};
111#endif /* CONFIG_MV643XX_ETH_1 */
112
113#ifdef CONFIG_MV643XX_ETH_2
114 106
115static struct resource mv64x60_eth2_resources[] = { 107static struct resource mv64x60_eth2_resources[] = {
116 [0] = { 108 [0] = {
@@ -136,19 +128,12 @@ static struct platform_device eth2_device = {
136 .platform_data = &eth2_pd, 128 .platform_data = &eth2_pd,
137 }, 129 },
138}; 130};
139#endif /* CONFIG_MV643XX_ETH_2 */
140 131
141static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { 132static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
142 &mv643xx_eth_shared_device, 133 &mv643xx_eth_shared_device,
143#ifdef CONFIG_MV643XX_ETH_0
144 &eth0_device, 134 &eth0_device,
145#endif
146#ifdef CONFIG_MV643XX_ETH_1
147 &eth1_device, 135 &eth1_device,
148#endif
149#ifdef CONFIG_MV643XX_ETH_2
150 &eth2_device, 136 &eth2_device,
151#endif
152}; 137};
153 138
154static u8 __init exchange_bit(u8 val, u8 cs) 139static u8 __init exchange_bit(u8 val, u8 cs)
@@ -215,15 +200,9 @@ static int __init mv643xx_eth_add_pds(void)
215 int ret; 200 int ret;
216 201
217 get_mac(mac); 202 get_mac(mac);
218#ifdef CONFIG_MV643XX_ETH_0
219 eth_mac_add(eth1_mac_addr, mac, 0); 203 eth_mac_add(eth1_mac_addr, mac, 0);
220#endif
221#ifdef CONFIG_MV643XX_ETH_1
222 eth_mac_add(eth1_mac_addr, mac, 1); 204 eth_mac_add(eth1_mac_addr, mac, 1);
223#endif
224#ifdef CONFIG_MV643XX_ETH_2
225 eth_mac_add(eth2_mac_addr, mac, 2); 205 eth_mac_add(eth2_mac_addr, mac, 2);
226#endif
227 ret = platform_add_devices(mv643xx_eth_pd_devs, 206 ret = platform_add_devices(mv643xx_eth_pd_devs,
228 ARRAY_SIZE(mv643xx_eth_pd_devs)); 207 ARRAY_SIZE(mv643xx_eth_pd_devs));
229 208
diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c
index 57cfe5c6e4a8..0ab8d231cf7d 100644
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -38,8 +38,6 @@ static struct platform_device mv643xx_eth_shared_device = {
38#define MV64x60_IRQ_ETH_1 49 38#define MV64x60_IRQ_ETH_1 49
39#define MV64x60_IRQ_ETH_2 50 39#define MV64x60_IRQ_ETH_2 50
40 40
41#ifdef CONFIG_MV643XX_ETH_0
42
43static struct resource mv64x60_eth0_resources[] = { 41static struct resource mv64x60_eth0_resources[] = {
44 [0] = { 42 [0] = {
45 .name = "eth0 irq", 43 .name = "eth0 irq",
@@ -72,9 +70,6 @@ static struct platform_device eth0_device = {
72 .platform_data = &eth0_pd, 70 .platform_data = &eth0_pd,
73 }, 71 },
74}; 72};
75#endif /* CONFIG_MV643XX_ETH_0 */
76
77#ifdef CONFIG_MV643XX_ETH_1
78 73
79static struct resource mv64x60_eth1_resources[] = { 74static struct resource mv64x60_eth1_resources[] = {
80 [0] = { 75 [0] = {
@@ -108,9 +103,6 @@ static struct platform_device eth1_device = {
108 .platform_data = &eth1_pd, 103 .platform_data = &eth1_pd,
109 }, 104 },
110}; 105};
111#endif /* CONFIG_MV643XX_ETH_1 */
112
113#ifdef CONFIG_MV643XX_ETH_2
114 106
115static struct resource mv64x60_eth2_resources[] = { 107static struct resource mv64x60_eth2_resources[] = {
116 [0] = { 108 [0] = {
@@ -136,19 +128,12 @@ static struct platform_device eth2_device = {
136 .platform_data = &eth2_pd, 128 .platform_data = &eth2_pd,
137 }, 129 },
138}; 130};
139#endif /* CONFIG_MV643XX_ETH_2 */
140 131
141static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { 132static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
142 &mv643xx_eth_shared_device, 133 &mv643xx_eth_shared_device,
143#ifdef CONFIG_MV643XX_ETH_0
144 &eth0_device, 134 &eth0_device,
145#endif
146#ifdef CONFIG_MV643XX_ETH_1
147 &eth1_device, 135 &eth1_device,
148#endif
149#ifdef CONFIG_MV643XX_ETH_2
150 &eth2_device, 136 &eth2_device,
151#endif
152}; 137};
153 138
154static u8 __init exchange_bit(u8 val, u8 cs) 139static u8 __init exchange_bit(u8 val, u8 cs)
@@ -215,15 +200,9 @@ static int __init mv643xx_eth_add_pds(void)
215 int ret; 200 int ret;
216 201
217 get_mac(mac); 202 get_mac(mac);
218#ifdef CONFIG_MV643XX_ETH_0
219 eth_mac_add(eth1_mac_addr, mac, 0); 203 eth_mac_add(eth1_mac_addr, mac, 0);
220#endif
221#ifdef CONFIG_MV643XX_ETH_1
222 eth_mac_add(eth1_mac_addr, mac, 1); 204 eth_mac_add(eth1_mac_addr, mac, 1);
223#endif
224#ifdef CONFIG_MV643XX_ETH_2
225 eth_mac_add(eth2_mac_addr, mac, 2); 205 eth_mac_add(eth2_mac_addr, mac, 2);
226#endif
227 ret = platform_add_devices(mv643xx_eth_pd_devs, 206 ret = platform_add_devices(mv643xx_eth_pd_devs,
228 ARRAY_SIZE(mv643xx_eth_pd_devs)); 207 ARRAY_SIZE(mv643xx_eth_pd_devs));
229 208
diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c
index 6c495b2f1560..8e381d447573 100644
--- a/arch/mips/momentum/ocelot_c/platform.c
+++ b/arch/mips/momentum/ocelot_c/platform.c
@@ -37,8 +37,6 @@ static struct platform_device mv643xx_eth_shared_device = {
37#define MV64x60_IRQ_ETH_0 48 37#define MV64x60_IRQ_ETH_0 48
38#define MV64x60_IRQ_ETH_1 49 38#define MV64x60_IRQ_ETH_1 49
39 39
40#ifdef CONFIG_MV643XX_ETH_0
41
42static struct resource mv64x60_eth0_resources[] = { 40static struct resource mv64x60_eth0_resources[] = {
43 [0] = { 41 [0] = {
44 .name = "eth0 irq", 42 .name = "eth0 irq",
@@ -71,9 +69,6 @@ static struct platform_device eth0_device = {
71 .platform_data = &eth0_pd, 69 .platform_data = &eth0_pd,
72 }, 70 },
73}; 71};
74#endif /* CONFIG_MV643XX_ETH_0 */
75
76#ifdef CONFIG_MV643XX_ETH_1
77 72
78static struct resource mv64x60_eth1_resources[] = { 73static struct resource mv64x60_eth1_resources[] = {
79 [0] = { 74 [0] = {
@@ -107,16 +102,11 @@ static struct platform_device eth1_device = {
107 .platform_data = &eth1_pd, 102 .platform_data = &eth1_pd,
108 }, 103 },
109}; 104};
110#endif /* CONFIG_MV643XX_ETH_1 */
111 105
112static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { 106static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
113 &mv643xx_eth_shared_device, 107 &mv643xx_eth_shared_device,
114#ifdef CONFIG_MV643XX_ETH_0
115 &eth0_device, 108 &eth0_device,
116#endif
117#ifdef CONFIG_MV643XX_ETH_1
118 &eth1_device, 109 &eth1_device,
119#endif
120 /* The third port is not wired up on the Ocelot C */ 110 /* The third port is not wired up on the Ocelot C */
121}; 111};
122 112
@@ -184,12 +174,8 @@ static int __init mv643xx_eth_add_pds(void)
184 int ret; 174 int ret;
185 175
186 get_mac(mac); 176 get_mac(mac);
187#ifdef CONFIG_MV643XX_ETH_0
188 eth_mac_add(eth1_mac_addr, mac, 0); 177 eth_mac_add(eth1_mac_addr, mac, 0);
189#endif
190#ifdef CONFIG_MV643XX_ETH_1
191 eth_mac_add(eth1_mac_addr, mac, 1); 178 eth_mac_add(eth1_mac_addr, mac, 1);
192#endif
193 ret = platform_add_devices(mv643xx_eth_pd_devs, 179 ret = platform_add_devices(mv643xx_eth_pd_devs,
194 ARRAY_SIZE(mv643xx_eth_pd_devs)); 180 ARRAY_SIZE(mv643xx_eth_pd_devs));
195 181
diff --git a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
index ca395ef06d4e..fb6f235348b0 100644
--- a/arch/mips/oprofile/Kconfig
+++ b/arch/mips/oprofile/Kconfig
@@ -11,7 +11,7 @@ config PROFILING
11 11
12config OPROFILE 12config OPROFILE
13 tristate "OProfile system profiling (EXPERIMENTAL)" 13 tristate "OProfile system profiling (EXPERIMENTAL)"
14 depends on PROFILING && !!MIPS_MT_SMTC && EXPERIMENTAL 14 depends on PROFILING && !MIPS_MT_SMTC && EXPERIMENTAL
15 help 15 help
16 OProfile is a profiling system capable of profiling the 16 OProfile is a profiling system capable of profiling the
17 whole system, include the kernel, kernel modules, libraries, 17 whole system, include the kernel, kernel modules, libraries,
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index dcc6f159fd94..17724fb2067f 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -107,12 +107,10 @@ int die(const char *str, struct pt_regs *regs, long err)
107 if (machine_is(powermac) && pmac_backlight) { 107 if (machine_is(powermac) && pmac_backlight) {
108 struct backlight_properties *props; 108 struct backlight_properties *props;
109 109
110 down(&pmac_backlight->sem); 110 props = &pmac_backlight->props;
111 props = pmac_backlight->props;
112 props->brightness = props->max_brightness; 111 props->brightness = props->max_brightness;
113 props->power = FB_BLANK_UNBLANK; 112 props->power = FB_BLANK_UNBLANK;
114 props->update_status(pmac_backlight); 113 backlight_update_status(pmac_backlight);
115 up(&pmac_backlight->sem);
116 } 114 }
117 mutex_unlock(&pmac_backlight_mutex); 115 mutex_unlock(&pmac_backlight_mutex);
118#endif 116#endif
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
index c3a89414ddc0..de7440e62cc4 100644
--- a/arch/powerpc/platforms/powermac/backlight.c
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -37,21 +37,20 @@ static int pmac_backlight_set_legacy_queued;
37 */ 37 */
38static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0); 38static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0);
39 39
40/* Protect the pmac_backlight variable */ 40/* Protect the pmac_backlight variable below.
41 You should hold this lock when using the pmac_backlight pointer to
42 prevent its potential removal. */
41DEFINE_MUTEX(pmac_backlight_mutex); 43DEFINE_MUTEX(pmac_backlight_mutex);
42 44
43/* Main backlight storage 45/* Main backlight storage
44 * 46 *
45 * Backlight drivers in this variable are required to have the "props" 47 * Backlight drivers in this variable are required to have the "ops"
46 * attribute set and to have an update_status function. 48 * attribute set and to have an update_status function.
47 * 49 *
48 * We can only store one backlight here, but since Apple laptops have only one 50 * We can only store one backlight here, but since Apple laptops have only one
49 * internal display, it doesn't matter. Other backlight drivers can be used 51 * internal display, it doesn't matter. Other backlight drivers can be used
50 * independently. 52 * independently.
51 * 53 *
52 * Lock ordering:
53 * pmac_backlight_mutex (global, main backlight)
54 * pmac_backlight->sem (backlight class)
55 */ 54 */
56struct backlight_device *pmac_backlight; 55struct backlight_device *pmac_backlight;
57 56
@@ -104,8 +103,7 @@ static void pmac_backlight_key_worker(struct work_struct *work)
104 struct backlight_properties *props; 103 struct backlight_properties *props;
105 int brightness; 104 int brightness;
106 105
107 down(&pmac_backlight->sem); 106 props = &pmac_backlight->props;
108 props = pmac_backlight->props;
109 107
110 brightness = props->brightness + 108 brightness = props->brightness +
111 ((pmac_backlight_key_queued?-1:1) * 109 ((pmac_backlight_key_queued?-1:1) *
@@ -117,9 +115,7 @@ static void pmac_backlight_key_worker(struct work_struct *work)
117 brightness = props->max_brightness; 115 brightness = props->max_brightness;
118 116
119 props->brightness = brightness; 117 props->brightness = brightness;
120 props->update_status(pmac_backlight); 118 backlight_update_status(pmac_backlight);
121
122 up(&pmac_backlight->sem);
123 } 119 }
124 mutex_unlock(&pmac_backlight_mutex); 120 mutex_unlock(&pmac_backlight_mutex);
125} 121}
@@ -145,8 +141,7 @@ static int __pmac_backlight_set_legacy_brightness(int brightness)
145 if (pmac_backlight) { 141 if (pmac_backlight) {
146 struct backlight_properties *props; 142 struct backlight_properties *props;
147 143
148 down(&pmac_backlight->sem); 144 props = &pmac_backlight->props;
149 props = pmac_backlight->props;
150 props->brightness = brightness * 145 props->brightness = brightness *
151 (props->max_brightness + 1) / 146 (props->max_brightness + 1) /
152 (OLD_BACKLIGHT_MAX + 1); 147 (OLD_BACKLIGHT_MAX + 1);
@@ -156,8 +151,7 @@ static int __pmac_backlight_set_legacy_brightness(int brightness)
156 else if (props->brightness < 0) 151 else if (props->brightness < 0)
157 props->brightness = 0; 152 props->brightness = 0;
158 153
159 props->update_status(pmac_backlight); 154 backlight_update_status(pmac_backlight);
160 up(&pmac_backlight->sem);
161 155
162 error = 0; 156 error = 0;
163 } 157 }
@@ -196,14 +190,11 @@ int pmac_backlight_get_legacy_brightness()
196 if (pmac_backlight) { 190 if (pmac_backlight) {
197 struct backlight_properties *props; 191 struct backlight_properties *props;
198 192
199 down(&pmac_backlight->sem); 193 props = &pmac_backlight->props;
200 props = pmac_backlight->props;
201 194
202 result = props->brightness * 195 result = props->brightness *
203 (OLD_BACKLIGHT_MAX + 1) / 196 (OLD_BACKLIGHT_MAX + 1) /
204 (props->max_brightness + 1); 197 (props->max_brightness + 1);
205
206 up(&pmac_backlight->sem);
207 } 198 }
208 mutex_unlock(&pmac_backlight_mutex); 199 mutex_unlock(&pmac_backlight_mutex);
209 200
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 0df9c33629fd..ccce2a4a1522 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -845,6 +845,21 @@ config MV64X60
845 select PPC_INDIRECT_PCI 845 select PPC_INDIRECT_PCI
846 default y 846 default y
847 847
848config MV643XX_ETH_0
849 bool
850 depends on MV643XX_ETH && (KATANA || RADSTONE_PPC7D || EV64360 || HDPU)
851 default y
852
853config MV643XX_ETH_1
854 bool
855 depends on MV643XX_ETH && (KATANA || RADSTONE_PPC7D || EV64360)
856 default y
857
858config MV643XX_ETH_2
859 bool
860 depends on MV643XX_ETH && (KATANA || RADSTONE_PPC7D || EV64360)
861 default y
862
848menu "Set bridge options" 863menu "Set bridge options"
849 depends on MV64X60 864 depends on MV64X60
850 865
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/char/lcd.c b/drivers/char/lcd.c
index d649abbf0857..5f4fdcf7c96e 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -409,138 +409,6 @@ static int lcd_ioctl(struct inode *inode, struct file *file,
409 break; 409 break;
410 } 410 }
411 411
412// Erase the flash
413
414 case FLASH_Erase:{
415
416 int ctr = 0;
417
418 if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
419
420 pr_info(LCD "Erasing Flash\n");
421
422 // Chip Erase Sequence
423 WRITE_FLASH(kFlash_Addr1, kFlash_Data1);
424 WRITE_FLASH(kFlash_Addr2, kFlash_Data2);
425 WRITE_FLASH(kFlash_Addr1, kFlash_Erase3);
426 WRITE_FLASH(kFlash_Addr1, kFlash_Data1);
427 WRITE_FLASH(kFlash_Addr2, kFlash_Data2);
428 WRITE_FLASH(kFlash_Addr1, kFlash_Erase6);
429
430 while ((!dqpoll(0x00000000, 0xFF))
431 && (!timeout(0x00000000))) {
432 ctr++;
433 }
434
435 if (READ_FLASH(0x07FFF0) == 0xFF) {
436 pr_info(LCD "Erase Successful\n");
437 } else if (timeout) {
438 pr_info(LCD "Erase Timed Out\n");
439 }
440
441 break;
442 }
443
444// burn the flash
445
446 case FLASH_Burn:{
447
448 volatile unsigned long burn_addr;
449 unsigned long flags;
450 unsigned int i, index;
451 unsigned char *rom;
452
453
454 struct lcd_display display;
455
456 if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;
457
458 if (copy_from_user
459 (&display, (struct lcd_display *) arg,
460 sizeof(struct lcd_display)))
461 return -EFAULT;
462 rom = kmalloc((128), GFP_ATOMIC);
463 if (rom == NULL) {
464 printk(KERN_ERR LCD "kmalloc() failed in %s\n",
465 __FUNCTION__);
466 return -ENOMEM;
467 }
468
469 pr_info(LCD "Starting Flash burn\n");
470 for (i = 0; i < FLASH_SIZE; i = i + 128) {
471
472 if (copy_from_user
473 (rom, display.RomImage + i, 128)) {
474 kfree(rom);
475 return -EFAULT;
476 }
477 burn_addr = kFlashBase + i;
478 spin_lock_irqsave(&lcd_lock, flags);
479 for (index = 0; index < (128); index++) {
480
481 WRITE_FLASH(kFlash_Addr1,
482 kFlash_Data1);
483 WRITE_FLASH(kFlash_Addr2,
484 kFlash_Data2);
485 WRITE_FLASH(kFlash_Addr1,
486 kFlash_Prog);
487 *((volatile unsigned char *)burn_addr) =
488 (volatile unsigned char) rom[index];
489
490 while ((!dqpoll (burn_addr,
491 (volatile unsigned char)
492 rom[index])) &&
493 (!timeout(burn_addr))) { }
494 burn_addr++;
495 }
496 spin_unlock_irqrestore(&lcd_lock, flags);
497 if (* ((volatile unsigned char *)
498 (burn_addr - 1)) ==
499 (volatile unsigned char)
500 rom[index - 1]) {
501 } else if (timeout) {
502 pr_info(LCD "Flash burn timed out\n");
503 }
504
505
506 }
507 kfree(rom);
508
509 pr_info(LCD "Flash successfully burned\n");
510
511 break;
512 }
513
514// read the flash all at once
515
516 case FLASH_Read:{
517
518 unsigned char *user_bytes;
519 volatile unsigned long read_addr;
520 unsigned int i;
521
522 user_bytes =
523 &(((struct lcd_display *) arg)->RomImage[0]);
524
525 if (!access_ok
526 (VERIFY_WRITE, user_bytes, FLASH_SIZE))
527 return -EFAULT;
528
529 pr_info(LCD "Reading Flash");
530 for (i = 0; i < FLASH_SIZE; i++) {
531 unsigned char tmp_byte;
532 read_addr = kFlashBase + i;
533 tmp_byte =
534 *((volatile unsigned char *)
535 read_addr);
536 if (__put_user(tmp_byte, &user_bytes[i]))
537 return -EFAULT;
538 }
539
540
541 break;
542 }
543
544 default: 412 default:
545 return -EINVAL; 413 return -EINVAL;
546 414
@@ -644,42 +512,6 @@ static void __exit lcd_exit(void)
644 misc_deregister(&lcd_dev); 512 misc_deregister(&lcd_dev);
645} 513}
646 514
647//
648// Function: dqpoll
649//
650// Description: Polls the data lines to see if the flash is busy
651//
652// In: address, byte data
653//
654// Out: 0 = busy, 1 = write or erase complete
655//
656//
657
658static int dqpoll(volatile unsigned long address, volatile unsigned char data)
659{
660 volatile unsigned char dq7;
661
662 dq7 = data & 0x80;
663
664 return ((READ_FLASH(address) & 0x80) == dq7);
665}
666
667//
668// Function: timeout
669//
670// Description: Checks to see if erase or write has timed out
671// By polling dq5
672//
673// In: address
674//
675//
676// Out: 0 = not timed out, 1 = timed out
677
678static int timeout(volatile unsigned long address)
679{
680 return (READ_FLASH(address) & 0x20) == 0x20;
681}
682
683module_init(lcd_init); 515module_init(lcd_init);
684module_exit(lcd_exit); 516module_exit(lcd_exit);
685 517
diff --git a/drivers/char/lcd.h b/drivers/char/lcd.h
index a8d4ae737158..290b3ff23b03 100644
--- a/drivers/char/lcd.h
+++ b/drivers/char/lcd.h
@@ -14,11 +14,7 @@
14 14
15// function headers 15// function headers
16 16
17static int dqpoll(volatile unsigned long, volatile unsigned char );
18static int timeout(volatile unsigned long);
19
20#define LCD_CHARS_PER_LINE 40 17#define LCD_CHARS_PER_LINE 40
21#define FLASH_SIZE 524288
22#define MAX_IDLE_TIME 120 18#define MAX_IDLE_TIME 120
23 19
24struct lcd_display { 20struct lcd_display {
@@ -54,26 +50,6 @@ struct lcd_display {
54#define LCDTimeoutValue 0xfff 50#define LCDTimeoutValue 0xfff
55 51
56 52
57// Flash definitions AMD 29F040
58#define kFlashBase 0x0FC00000
59
60#define kFlash_Addr1 0x5555
61#define kFlash_Addr2 0x2AAA
62#define kFlash_Data1 0xAA
63#define kFlash_Data2 0x55
64#define kFlash_Prog 0xA0
65#define kFlash_Erase3 0x80
66#define kFlash_Erase6 0x10
67#define kFlash_Read 0xF0
68
69#define kFlash_ID 0x90
70#define kFlash_VenAddr 0x00
71#define kFlash_DevAddr 0x01
72#define kFlash_VenID 0x01
73#define kFlash_DevID 0xA4 // 29F040
74//#define kFlash_DevID 0xAD // 29F016
75
76
77// Macros 53// Macros
78 54
79#define LCDWriteData(x) outl((x << 24), kLCD_DR) 55#define LCDWriteData(x) outl((x << 24), kLCD_DR)
@@ -89,9 +65,6 @@ struct lcd_display {
89#define WRITE_GAL(x,y) outl(y, 0x04000000 | (x)) 65#define WRITE_GAL(x,y) outl(y, 0x04000000 | (x))
90#define BusyCheck() while ((LCDReadInst & 0x80) == 0x80) 66#define BusyCheck() while ((LCDReadInst & 0x80) == 0x80)
91 67
92#define WRITE_FLASH(x,y) outb((char)y, kFlashBase | (x))
93#define READ_FLASH(x) (inb(kFlashBase | (x)))
94
95 68
96 69
97/* 70/*
@@ -124,11 +97,6 @@ struct lcd_display {
124// Button defs 97// Button defs
125#define BUTTON_Read 50 98#define BUTTON_Read 50
126 99
127// Flash command codes
128#define FLASH_Erase 60
129#define FLASH_Burn 61
130#define FLASH_Read 62
131
132 100
133// Ethernet LINK check hackaroo 101// Ethernet LINK check hackaroo
134#define LINK_Check 90 102#define LINK_Check 90
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 5289254e7ab3..df467284ff4e 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -3713,15 +3713,14 @@ int tty_register_driver(struct tty_driver *driver)
3713 3713
3714 if (!driver->major) { 3714 if (!driver->major) {
3715 error = alloc_chrdev_region(&dev, driver->minor_start, driver->num, 3715 error = alloc_chrdev_region(&dev, driver->minor_start, driver->num,
3716 (char*)driver->name); 3716 driver->name);
3717 if (!error) { 3717 if (!error) {
3718 driver->major = MAJOR(dev); 3718 driver->major = MAJOR(dev);
3719 driver->minor_start = MINOR(dev); 3719 driver->minor_start = MINOR(dev);
3720 } 3720 }
3721 } else { 3721 } else {
3722 dev = MKDEV(driver->major, driver->minor_start); 3722 dev = MKDEV(driver->major, driver->minor_start);
3723 error = register_chrdev_region(dev, driver->num, 3723 error = register_chrdev_region(dev, driver->num, driver->name);
3724 (char*)driver->name);
3725 } 3724 }
3726 if (error < 0) { 3725 if (error < 0) {
3727 kfree(p); 3726 kfree(p);
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/net/8139too.c b/drivers/net/8139too.c
index 35ad5cff18e6..99304b2aa86e 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -1109,6 +1109,8 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
1109 1109
1110 assert (dev != NULL); 1110 assert (dev != NULL);
1111 1111
1112 flush_scheduled_work();
1113
1112 unregister_netdev (dev); 1114 unregister_netdev (dev);
1113 1115
1114 __rtl8139_cleanup_dev (dev); 1116 __rtl8139_cleanup_dev (dev);
@@ -1603,18 +1605,21 @@ static void rtl8139_thread (struct work_struct *work)
1603 struct net_device *dev = tp->mii.dev; 1605 struct net_device *dev = tp->mii.dev;
1604 unsigned long thr_delay = next_tick; 1606 unsigned long thr_delay = next_tick;
1605 1607
1608 rtnl_lock();
1609
1610 if (!netif_running(dev))
1611 goto out_unlock;
1612
1606 if (tp->watchdog_fired) { 1613 if (tp->watchdog_fired) {
1607 tp->watchdog_fired = 0; 1614 tp->watchdog_fired = 0;
1608 rtl8139_tx_timeout_task(work); 1615 rtl8139_tx_timeout_task(work);
1609 } else if (rtnl_trylock()) { 1616 } else
1610 rtl8139_thread_iter (dev, tp, tp->mmio_addr); 1617 rtl8139_thread_iter(dev, tp, tp->mmio_addr);
1611 rtnl_unlock ();
1612 } else {
1613 /* unlikely race. mitigate with fast poll. */
1614 thr_delay = HZ / 2;
1615 }
1616 1618
1617 schedule_delayed_work(&tp->thread, thr_delay); 1619 if (tp->have_thread)
1620 schedule_delayed_work(&tp->thread, thr_delay);
1621out_unlock:
1622 rtnl_unlock ();
1618} 1623}
1619 1624
1620static void rtl8139_start_thread(struct rtl8139_private *tp) 1625static void rtl8139_start_thread(struct rtl8139_private *tp)
@@ -1626,19 +1631,11 @@ static void rtl8139_start_thread(struct rtl8139_private *tp)
1626 return; 1631 return;
1627 1632
1628 tp->have_thread = 1; 1633 tp->have_thread = 1;
1634 tp->watchdog_fired = 0;
1629 1635
1630 schedule_delayed_work(&tp->thread, next_tick); 1636 schedule_delayed_work(&tp->thread, next_tick);
1631} 1637}
1632 1638
1633static void rtl8139_stop_thread(struct rtl8139_private *tp)
1634{
1635 if (tp->have_thread) {
1636 cancel_rearming_delayed_work(&tp->thread);
1637 tp->have_thread = 0;
1638 } else
1639 flush_scheduled_work();
1640}
1641
1642static inline void rtl8139_tx_clear (struct rtl8139_private *tp) 1639static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
1643{ 1640{
1644 tp->cur_tx = 0; 1641 tp->cur_tx = 0;
@@ -1696,12 +1693,11 @@ static void rtl8139_tx_timeout (struct net_device *dev)
1696{ 1693{
1697 struct rtl8139_private *tp = netdev_priv(dev); 1694 struct rtl8139_private *tp = netdev_priv(dev);
1698 1695
1696 tp->watchdog_fired = 1;
1699 if (!tp->have_thread) { 1697 if (!tp->have_thread) {
1700 INIT_DELAYED_WORK(&tp->thread, rtl8139_tx_timeout_task); 1698 INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
1701 schedule_delayed_work(&tp->thread, next_tick); 1699 schedule_delayed_work(&tp->thread, next_tick);
1702 } else 1700 }
1703 tp->watchdog_fired = 1;
1704
1705} 1701}
1706 1702
1707static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) 1703static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
@@ -2233,8 +2229,6 @@ static int rtl8139_close (struct net_device *dev)
2233 2229
2234 netif_stop_queue (dev); 2230 netif_stop_queue (dev);
2235 2231
2236 rtl8139_stop_thread(tp);
2237
2238 if (netif_msg_ifdown(tp)) 2232 if (netif_msg_ifdown(tp))
2239 printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", 2233 printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
2240 dev->name, RTL_R16 (IntrStatus)); 2234 dev->name, RTL_R16 (IntrStatus));
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index d9400ef87195..9d5c083f3339 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2307,27 +2307,6 @@ config MV643XX_ETH
2307 chipset which is used in the Momenco Ocelot C and Jaguar ATX and 2307 chipset which is used in the Momenco Ocelot C and Jaguar ATX and
2308 Pegasos II, amongst other PPC and MIPS boards. 2308 Pegasos II, amongst other PPC and MIPS boards.
2309 2309
2310config MV643XX_ETH_0
2311 bool "MV-643XX Port 0"
2312 depends on MV643XX_ETH
2313 help
2314 This enables support for Port 0 of the Marvell MV643XX Gigabit
2315 Ethernet.
2316
2317config MV643XX_ETH_1
2318 bool "MV-643XX Port 1"
2319 depends on MV643XX_ETH
2320 help
2321 This enables support for Port 1 of the Marvell MV643XX Gigabit
2322 Ethernet.
2323
2324config MV643XX_ETH_2
2325 bool "MV-643XX Port 2"
2326 depends on MV643XX_ETH
2327 help
2328 This enables support for Port 2 of the Marvell MV643XX Gigabit
2329 Ethernet.
2330
2331config QLA3XXX 2310config QLA3XXX
2332 tristate "QLogic QLA3XXX Network Driver Support" 2311 tristate "QLogic QLA3XXX Network Driver Support"
2333 depends on PCI 2312 depends on PCI
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 153b6dc80af4..84aa2117c0ee 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -52,6 +52,7 @@
52#include <linux/hdlcdrv.h> 52#include <linux/hdlcdrv.h>
53#include <linux/baycom.h> 53#include <linux/baycom.h>
54#include <linux/jiffies.h> 54#include <linux/jiffies.h>
55#include <linux/random.h>
55#include <net/ax25.h> 56#include <net/ax25.h>
56#include <asm/uaccess.h> 57#include <asm/uaccess.h>
57 58
@@ -433,16 +434,6 @@ static void encode_hdlc(struct baycom_state *bc)
433 434
434/* ---------------------------------------------------------------------- */ 435/* ---------------------------------------------------------------------- */
435 436
436static unsigned short random_seed;
437
438static inline unsigned short random_num(void)
439{
440 random_seed = 28629 * random_seed + 157;
441 return random_seed;
442}
443
444/* ---------------------------------------------------------------------- */
445
446static int transmit(struct baycom_state *bc, int cnt, unsigned char stat) 437static int transmit(struct baycom_state *bc, int cnt, unsigned char stat)
447{ 438{
448 struct parport *pp = bc->pdev->port; 439 struct parport *pp = bc->pdev->port;
@@ -464,7 +455,7 @@ static int transmit(struct baycom_state *bc, int cnt, unsigned char stat)
464 if ((--bc->hdlctx.slotcnt) > 0) 455 if ((--bc->hdlctx.slotcnt) > 0)
465 return 0; 456 return 0;
466 bc->hdlctx.slotcnt = bc->ch_params.slottime; 457 bc->hdlctx.slotcnt = bc->ch_params.slottime;
467 if ((random_num() % 256) > bc->ch_params.ppersist) 458 if ((random32() % 256) > bc->ch_params.ppersist)
468 return 0; 459 return 0;
469 } 460 }
470 } 461 }
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 452873e7c68f..f5a17ad9d3d6 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -56,6 +56,7 @@
56#include <linux/if_arp.h> 56#include <linux/if_arp.h>
57#include <linux/skbuff.h> 57#include <linux/skbuff.h>
58#include <linux/hdlcdrv.h> 58#include <linux/hdlcdrv.h>
59#include <linux/random.h>
59#include <net/ax25.h> 60#include <net/ax25.h>
60#include <asm/uaccess.h> 61#include <asm/uaccess.h>
61 62
@@ -371,16 +372,6 @@ static void start_tx(struct net_device *dev, struct hdlcdrv_state *s)
371 372
372/* ---------------------------------------------------------------------- */ 373/* ---------------------------------------------------------------------- */
373 374
374static unsigned short random_seed;
375
376static inline unsigned short random_num(void)
377{
378 random_seed = 28629 * random_seed + 157;
379 return random_seed;
380}
381
382/* ---------------------------------------------------------------------- */
383
384void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s) 375void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
385{ 376{
386 if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || !s->skb) 377 if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || !s->skb)
@@ -396,7 +387,7 @@ void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
396 if ((--s->hdlctx.slotcnt) > 0) 387 if ((--s->hdlctx.slotcnt) > 0)
397 return; 388 return;
398 s->hdlctx.slotcnt = s->ch_params.slottime; 389 s->hdlctx.slotcnt = s->ch_params.slottime;
399 if ((random_num() % 256) > s->ch_params.ppersist) 390 if ((random32() % 256) > s->ch_params.ppersist)
400 return; 391 return;
401 start_tx(dev, s); 392 start_tx(dev, s);
402} 393}
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 08f27119a807..ee3ea4fa729f 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -50,6 +50,7 @@
50#include <linux/slab.h> 50#include <linux/slab.h>
51#include <linux/errno.h> 51#include <linux/errno.h>
52#include <linux/bitops.h> 52#include <linux/bitops.h>
53#include <linux/random.h>
53#include <asm/io.h> 54#include <asm/io.h>
54#include <asm/system.h> 55#include <asm/system.h>
55#include <linux/interrupt.h> 56#include <linux/interrupt.h>
@@ -566,14 +567,6 @@ static void yam_start_tx(struct net_device *dev, struct yam_port *yp)
566 ptt_on(dev); 567 ptt_on(dev);
567} 568}
568 569
569static unsigned short random_seed;
570
571static inline unsigned short random_num(void)
572{
573 random_seed = 28629 * random_seed + 157;
574 return random_seed;
575}
576
577static void yam_arbitrate(struct net_device *dev) 570static void yam_arbitrate(struct net_device *dev)
578{ 571{
579 struct yam_port *yp = netdev_priv(dev); 572 struct yam_port *yp = netdev_priv(dev);
@@ -600,7 +593,7 @@ static void yam_arbitrate(struct net_device *dev)
600 yp->slotcnt = yp->slot / 10; 593 yp->slotcnt = yp->slot / 10;
601 594
602 /* is random > persist ? */ 595 /* is random > persist ? */
603 if ((random_num() % 256) > yp->pers) 596 if ((random32() % 256) > yp->pers)
604 return; 597 return;
605 598
606 yam_start_tx(dev, yp); 599 yam_start_tx(dev, yp);
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index ffa0afd2eddc..adf29dd66798 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -244,6 +244,9 @@ enum {
244 MII_EN_SCRM = 0x0004, /* enable scrambler (tp) */ 244 MII_EN_SCRM = 0x0004, /* enable scrambler (tp) */
245}; 245};
246 246
247enum {
248 NATSEMI_FLAG_IGNORE_PHY = 0x1,
249};
247 250
248/* array of board data directly indexed by pci_tbl[x].driver_data */ 251/* array of board data directly indexed by pci_tbl[x].driver_data */
249static const struct { 252static const struct {
@@ -251,10 +254,12 @@ static const struct {
251 unsigned long flags; 254 unsigned long flags;
252 unsigned int eeprom_size; 255 unsigned int eeprom_size;
253} natsemi_pci_info[] __devinitdata = { 256} natsemi_pci_info[] __devinitdata = {
257 { "Aculab E1/T1 PMXc cPCI carrier card", NATSEMI_FLAG_IGNORE_PHY, 128 },
254 { "NatSemi DP8381[56]", 0, 24 }, 258 { "NatSemi DP8381[56]", 0, 24 },
255}; 259};
256 260
257static const struct pci_device_id natsemi_pci_tbl[] __devinitdata = { 261static const struct pci_device_id natsemi_pci_tbl[] __devinitdata = {
262 { PCI_VENDOR_ID_NS, 0x0020, 0x12d9, 0x000c, 0, 0, 0 },
258 { PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 263 { PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
259 { } /* terminate list */ 264 { } /* terminate list */
260}; 265};
@@ -568,6 +573,8 @@ struct netdev_private {
568 u32 intr_status; 573 u32 intr_status;
569 /* Do not touch the nic registers */ 574 /* Do not touch the nic registers */
570 int hands_off; 575 int hands_off;
576 /* Don't pay attention to the reported link state. */
577 int ignore_phy;
571 /* external phy that is used: only valid if dev->if_port != PORT_TP */ 578 /* external phy that is used: only valid if dev->if_port != PORT_TP */
572 int mii; 579 int mii;
573 int phy_addr_external; 580 int phy_addr_external;
@@ -696,7 +703,10 @@ static void __devinit natsemi_init_media (struct net_device *dev)
696 struct netdev_private *np = netdev_priv(dev); 703 struct netdev_private *np = netdev_priv(dev);
697 u32 tmp; 704 u32 tmp;
698 705
699 netif_carrier_off(dev); 706 if (np->ignore_phy)
707 netif_carrier_on(dev);
708 else
709 netif_carrier_off(dev);
700 710
701 /* get the initial settings from hardware */ 711 /* get the initial settings from hardware */
702 tmp = mdio_read(dev, MII_BMCR); 712 tmp = mdio_read(dev, MII_BMCR);
@@ -806,8 +816,13 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
806 np->hands_off = 0; 816 np->hands_off = 0;
807 np->intr_status = 0; 817 np->intr_status = 0;
808 np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size; 818 np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size;
819 if (natsemi_pci_info[chip_idx].flags & NATSEMI_FLAG_IGNORE_PHY)
820 np->ignore_phy = 1;
821 else
822 np->ignore_phy = 0;
809 823
810 /* Initial port: 824 /* Initial port:
825 * - If configured to ignore the PHY set up for external.
811 * - If the nic was configured to use an external phy and if find_mii 826 * - If the nic was configured to use an external phy and if find_mii
812 * finds a phy: use external port, first phy that replies. 827 * finds a phy: use external port, first phy that replies.
813 * - Otherwise: internal port. 828 * - Otherwise: internal port.
@@ -815,7 +830,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
815 * The address would be used to access a phy over the mii bus, but 830 * The address would be used to access a phy over the mii bus, but
816 * the internal phy is accessed through mapped registers. 831 * the internal phy is accessed through mapped registers.
817 */ 832 */
818 if (readl(ioaddr + ChipConfig) & CfgExtPhy) 833 if (np->ignore_phy || readl(ioaddr + ChipConfig) & CfgExtPhy)
819 dev->if_port = PORT_MII; 834 dev->if_port = PORT_MII;
820 else 835 else
821 dev->if_port = PORT_TP; 836 dev->if_port = PORT_TP;
@@ -825,7 +840,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
825 840
826 if (dev->if_port != PORT_TP) { 841 if (dev->if_port != PORT_TP) {
827 np->phy_addr_external = find_mii(dev); 842 np->phy_addr_external = find_mii(dev);
828 if (np->phy_addr_external == PHY_ADDR_NONE) { 843 /* If we're ignoring the PHY it doesn't matter if we can't
844 * find one. */
845 if (!np->ignore_phy && np->phy_addr_external == PHY_ADDR_NONE) {
829 dev->if_port = PORT_TP; 846 dev->if_port = PORT_TP;
830 np->phy_addr_external = PHY_ADDR_INTERNAL; 847 np->phy_addr_external = PHY_ADDR_INTERNAL;
831 } 848 }
@@ -891,6 +908,8 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
891 printk("%02x, IRQ %d", dev->dev_addr[i], irq); 908 printk("%02x, IRQ %d", dev->dev_addr[i], irq);
892 if (dev->if_port == PORT_TP) 909 if (dev->if_port == PORT_TP)
893 printk(", port TP.\n"); 910 printk(", port TP.\n");
911 else if (np->ignore_phy)
912 printk(", port MII, ignoring PHY\n");
894 else 913 else
895 printk(", port MII, phy ad %d.\n", np->phy_addr_external); 914 printk(", port MII, phy ad %d.\n", np->phy_addr_external);
896 } 915 }
@@ -1571,9 +1590,13 @@ static void check_link(struct net_device *dev)
1571{ 1590{
1572 struct netdev_private *np = netdev_priv(dev); 1591 struct netdev_private *np = netdev_priv(dev);
1573 void __iomem * ioaddr = ns_ioaddr(dev); 1592 void __iomem * ioaddr = ns_ioaddr(dev);
1574 int duplex; 1593 int duplex = np->duplex;
1575 u16 bmsr; 1594 u16 bmsr;
1576 1595
1596 /* If we are ignoring the PHY then don't try reading it. */
1597 if (np->ignore_phy)
1598 goto propagate_state;
1599
1577 /* The link status field is latched: it remains low after a temporary 1600 /* The link status field is latched: it remains low after a temporary
1578 * link failure until it's read. We need the current link status, 1601 * link failure until it's read. We need the current link status,
1579 * thus read twice. 1602 * thus read twice.
@@ -1585,7 +1608,7 @@ static void check_link(struct net_device *dev)
1585 if (netif_carrier_ok(dev)) { 1608 if (netif_carrier_ok(dev)) {
1586 if (netif_msg_link(np)) 1609 if (netif_msg_link(np))
1587 printk(KERN_NOTICE "%s: link down.\n", 1610 printk(KERN_NOTICE "%s: link down.\n",
1588 dev->name); 1611 dev->name);
1589 netif_carrier_off(dev); 1612 netif_carrier_off(dev);
1590 undo_cable_magic(dev); 1613 undo_cable_magic(dev);
1591 } 1614 }
@@ -1609,6 +1632,7 @@ static void check_link(struct net_device *dev)
1609 duplex = 1; 1632 duplex = 1;
1610 } 1633 }
1611 1634
1635propagate_state:
1612 /* if duplex is set then bit 28 must be set, too */ 1636 /* if duplex is set then bit 28 must be set, too */
1613 if (duplex ^ !!(np->rx_config & RxAcceptTx)) { 1637 if (duplex ^ !!(np->rx_config & RxAcceptTx)) {
1614 if (netif_msg_link(np)) 1638 if (netif_msg_link(np))
@@ -2819,6 +2843,15 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
2819 } 2843 }
2820 2844
2821 /* 2845 /*
2846 * If we're ignoring the PHY then autoneg and the internal
2847 * transciever are really not going to work so don't let the
2848 * user select them.
2849 */
2850 if (np->ignore_phy && (ecmd->autoneg == AUTONEG_ENABLE ||
2851 ecmd->port == PORT_TP))
2852 return -EINVAL;
2853
2854 /*
2822 * maxtxpkt, maxrxpkt: ignored for now. 2855 * maxtxpkt, maxrxpkt: ignored for now.
2823 * 2856 *
2824 * transceiver: 2857 * transceiver:
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 5598d86380b4..13cf06ee97f7 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1733,6 +1733,8 @@ rtl8169_remove_one(struct pci_dev *pdev)
1733 assert(dev != NULL); 1733 assert(dev != NULL);
1734 assert(tp != NULL); 1734 assert(tp != NULL);
1735 1735
1736 flush_scheduled_work();
1737
1736 unregister_netdev(dev); 1738 unregister_netdev(dev);
1737 rtl8169_release_board(pdev, dev, tp->mmio_addr); 1739 rtl8169_release_board(pdev, dev, tp->mmio_addr);
1738 pci_set_drvdata(pdev, NULL); 1740 pci_set_drvdata(pdev, NULL);
@@ -2161,10 +2163,13 @@ static void rtl8169_reinit_task(struct work_struct *work)
2161 struct net_device *dev = tp->dev; 2163 struct net_device *dev = tp->dev;
2162 int ret; 2164 int ret;
2163 2165
2164 if (netif_running(dev)) { 2166 rtnl_lock();
2165 rtl8169_wait_for_quiescence(dev); 2167
2166 rtl8169_close(dev); 2168 if (!netif_running(dev))
2167 } 2169 goto out_unlock;
2170
2171 rtl8169_wait_for_quiescence(dev);
2172 rtl8169_close(dev);
2168 2173
2169 ret = rtl8169_open(dev); 2174 ret = rtl8169_open(dev);
2170 if (unlikely(ret < 0)) { 2175 if (unlikely(ret < 0)) {
@@ -2179,6 +2184,9 @@ static void rtl8169_reinit_task(struct work_struct *work)
2179 } 2184 }
2180 rtl8169_schedule_work(dev, rtl8169_reinit_task); 2185 rtl8169_schedule_work(dev, rtl8169_reinit_task);
2181 } 2186 }
2187
2188out_unlock:
2189 rtnl_unlock();
2182} 2190}
2183 2191
2184static void rtl8169_reset_task(struct work_struct *work) 2192static void rtl8169_reset_task(struct work_struct *work)
@@ -2187,8 +2195,10 @@ static void rtl8169_reset_task(struct work_struct *work)
2187 container_of(work, struct rtl8169_private, task.work); 2195 container_of(work, struct rtl8169_private, task.work);
2188 struct net_device *dev = tp->dev; 2196 struct net_device *dev = tp->dev;
2189 2197
2198 rtnl_lock();
2199
2190 if (!netif_running(dev)) 2200 if (!netif_running(dev))
2191 return; 2201 goto out_unlock;
2192 2202
2193 rtl8169_wait_for_quiescence(dev); 2203 rtl8169_wait_for_quiescence(dev);
2194 2204
@@ -2210,6 +2220,9 @@ static void rtl8169_reset_task(struct work_struct *work)
2210 } 2220 }
2211 rtl8169_schedule_work(dev, rtl8169_reset_task); 2221 rtl8169_schedule_work(dev, rtl8169_reset_task);
2212 } 2222 }
2223
2224out_unlock:
2225 rtnl_unlock();
2213} 2226}
2214 2227
2215static void rtl8169_tx_timeout(struct net_device *dev) 2228static void rtl8169_tx_timeout(struct net_device *dev)
@@ -2722,8 +2735,6 @@ static void rtl8169_down(struct net_device *dev)
2722 2735
2723 netif_stop_queue(dev); 2736 netif_stop_queue(dev);
2724 2737
2725 flush_scheduled_work();
2726
2727core_down: 2738core_down:
2728 spin_lock_irq(&tp->lock); 2739 spin_lock_irq(&tp->lock);
2729 2740
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index e8e0d94e9bdd..fd85648d98d1 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3758,7 +3758,6 @@ static int s2io_close(struct net_device *dev)
3758{ 3758{
3759 struct s2io_nic *sp = dev->priv; 3759 struct s2io_nic *sp = dev->priv;
3760 3760
3761 flush_scheduled_work();
3762 netif_stop_queue(dev); 3761 netif_stop_queue(dev);
3763 /* Reset card, kill tasklet and free Tx and Rx buffers. */ 3762 /* Reset card, kill tasklet and free Tx and Rx buffers. */
3764 s2io_card_down(sp); 3763 s2io_card_down(sp);
@@ -5847,9 +5846,14 @@ static void s2io_set_link(struct work_struct *work)
5847 register u64 val64; 5846 register u64 val64;
5848 u16 subid; 5847 u16 subid;
5849 5848
5849 rtnl_lock();
5850
5851 if (!netif_running(dev))
5852 goto out_unlock;
5853
5850 if (test_and_set_bit(0, &(nic->link_state))) { 5854 if (test_and_set_bit(0, &(nic->link_state))) {
5851 /* The card is being reset, no point doing anything */ 5855 /* The card is being reset, no point doing anything */
5852 return; 5856 goto out_unlock;
5853 } 5857 }
5854 5858
5855 subid = nic->pdev->subsystem_device; 5859 subid = nic->pdev->subsystem_device;
@@ -5903,6 +5907,9 @@ static void s2io_set_link(struct work_struct *work)
5903 s2io_link(nic, LINK_DOWN); 5907 s2io_link(nic, LINK_DOWN);
5904 } 5908 }
5905 clear_bit(0, &(nic->link_state)); 5909 clear_bit(0, &(nic->link_state));
5910
5911out_unlock:
5912 rtnl_lock();
5906} 5913}
5907 5914
5908static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, 5915static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
@@ -6356,6 +6363,11 @@ static void s2io_restart_nic(struct work_struct *work)
6356 struct s2io_nic *sp = container_of(work, struct s2io_nic, rst_timer_task); 6363 struct s2io_nic *sp = container_of(work, struct s2io_nic, rst_timer_task);
6357 struct net_device *dev = sp->dev; 6364 struct net_device *dev = sp->dev;
6358 6365
6366 rtnl_lock();
6367
6368 if (!netif_running(dev))
6369 goto out_unlock;
6370
6359 s2io_card_down(sp); 6371 s2io_card_down(sp);
6360 if (s2io_card_up(sp)) { 6372 if (s2io_card_up(sp)) {
6361 DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", 6373 DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
@@ -6364,7 +6376,8 @@ static void s2io_restart_nic(struct work_struct *work)
6364 netif_wake_queue(dev); 6376 netif_wake_queue(dev);
6365 DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", 6377 DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n",
6366 dev->name); 6378 dev->name);
6367 6379out_unlock:
6380 rtnl_unlock();
6368} 6381}
6369 6382
6370/** 6383/**
@@ -7173,6 +7186,8 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
7173 return; 7186 return;
7174 } 7187 }
7175 7188
7189 flush_scheduled_work();
7190
7176 sp = dev->priv; 7191 sp = dev->priv;
7177 unregister_netdev(dev); 7192 unregister_netdev(dev);
7178 7193
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 45d91b159100..b08508b35833 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -909,6 +909,9 @@ static void sis190_phy_task(struct work_struct *work)
909 909
910 rtnl_lock(); 910 rtnl_lock();
911 911
912 if (!netif_running(dev))
913 goto out_unlock;
914
912 val = mdio_read(ioaddr, phy_id, MII_BMCR); 915 val = mdio_read(ioaddr, phy_id, MII_BMCR);
913 if (val & BMCR_RESET) { 916 if (val & BMCR_RESET) {
914 // FIXME: needlessly high ? -- FR 02/07/2005 917 // FIXME: needlessly high ? -- FR 02/07/2005
@@ -981,6 +984,7 @@ static void sis190_phy_task(struct work_struct *work)
981 netif_carrier_on(dev); 984 netif_carrier_on(dev);
982 } 985 }
983 986
987out_unlock:
984 rtnl_unlock(); 988 rtnl_unlock();
985} 989}
986 990
@@ -1102,8 +1106,6 @@ static void sis190_down(struct net_device *dev)
1102 1106
1103 netif_stop_queue(dev); 1107 netif_stop_queue(dev);
1104 1108
1105 flush_scheduled_work();
1106
1107 do { 1109 do {
1108 spin_lock_irq(&tp->lock); 1110 spin_lock_irq(&tp->lock);
1109 1111
@@ -1857,6 +1859,7 @@ static void __devexit sis190_remove_one(struct pci_dev *pdev)
1857 struct net_device *dev = pci_get_drvdata(pdev); 1859 struct net_device *dev = pci_get_drvdata(pdev);
1858 1860
1859 sis190_mii_remove(dev); 1861 sis190_mii_remove(dev);
1862 flush_scheduled_work();
1860 unregister_netdev(dev); 1863 unregister_netdev(dev);
1861 sis190_release_board(pdev); 1864 sis190_release_board(pdev);
1862 pci_set_drvdata(pdev, NULL); 1865 pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index e482e7fcbb2b..c3d2e0a2c4e6 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -1419,7 +1419,8 @@ static void xm_link_timer(struct work_struct *work)
1419 mutex_unlock(&hw->phy_mutex); 1419 mutex_unlock(&hw->phy_mutex);
1420 1420
1421nochange: 1421nochange:
1422 schedule_delayed_work(&skge->link_thread, LINK_HZ); 1422 if (netif_running(dev))
1423 schedule_delayed_work(&skge->link_thread, LINK_HZ);
1423} 1424}
1424 1425
1425static void genesis_mac_init(struct skge_hw *hw, int port) 1426static void genesis_mac_init(struct skge_hw *hw, int port)
@@ -2530,7 +2531,7 @@ static int skge_down(struct net_device *dev)
2530 2531
2531 netif_stop_queue(dev); 2532 netif_stop_queue(dev);
2532 if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC) 2533 if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
2533 cancel_rearming_delayed_work(&skge->link_thread); 2534 cancel_delayed_work(&skge->link_thread);
2534 2535
2535 skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); 2536 skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
2536 if (hw->chip_id == CHIP_ID_GENESIS) 2537 if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3690,6 +3691,8 @@ static void __devexit skge_remove(struct pci_dev *pdev)
3690 if (!hw) 3691 if (!hw)
3691 return; 3692 return;
3692 3693
3694 flush_scheduled_work();
3695
3693 if ((dev1 = hw->dev[1])) 3696 if ((dev1 = hw->dev[1]))
3694 unregister_netdev(dev1); 3697 unregister_netdev(dev1);
3695 dev0 = hw->dev[0]; 3698 dev0 = hw->dev[0];
@@ -3704,8 +3707,6 @@ static void __devexit skge_remove(struct pci_dev *pdev)
3704 skge_write16(hw, B0_LED, LED_STAT_OFF); 3707 skge_write16(hw, B0_LED, LED_STAT_OFF);
3705 skge_write8(hw, B0_CTST, CS_RST_SET); 3708 skge_write8(hw, B0_CTST, CS_RST_SET);
3706 3709
3707 flush_scheduled_work();
3708
3709 free_irq(pdev->irq, hw); 3710 free_irq(pdev->irq, hw);
3710 pci_release_regions(pdev); 3711 pci_release_regions(pdev);
3711 pci_disable_device(pdev); 3712 pci_disable_device(pdev);
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index b08055abe83a..a8c2bfe26c27 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -1623,7 +1623,7 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
1623 1623
1624 crypto_cipher_setkey(tfm, pkey, 16); 1624 crypto_cipher_setkey(tfm, pkey, 16);
1625 counter = 0; 1625 counter = 0;
1626 for (i = 0; i < (sizeof(context->coeff)/sizeof(context->coeff[0])); ) { 1626 for (i = 0; i < ARRAY_SIZE(context->coeff); ) {
1627 aes_counter[15] = (u8)(counter >> 0); 1627 aes_counter[15] = (u8)(counter >> 0);
1628 aes_counter[14] = (u8)(counter >> 8); 1628 aes_counter[14] = (u8)(counter >> 8);
1629 aes_counter[13] = (u8)(counter >> 16); 1629 aes_counter[13] = (u8)(counter >> 16);
@@ -1632,7 +1632,7 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
1632 memcpy (plain, aes_counter, 16); 1632 memcpy (plain, aes_counter, 16);
1633 crypto_cipher_encrypt_one(tfm, plain, plain); 1633 crypto_cipher_encrypt_one(tfm, plain, plain);
1634 cipher = plain; 1634 cipher = plain;
1635 for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) { 1635 for (j = 0; (j < 16) && (i < ARRAY_SIZE(context->coeff)); ) {
1636 context->coeff[i++] = ntohl(*(u32 *)&cipher[j]); 1636 context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
1637 j += 4; 1637 j += 4;
1638 } 1638 }
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 0e790efae683..95ff175d8f33 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -21,7 +21,7 @@
21#define PFX KBUILD_MODNAME ": " 21#define PFX KBUILD_MODNAME ": "
22 22
23#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50 23#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50
24#define BCM43xx_IRQWAIT_MAX_RETRIES 50 24#define BCM43xx_IRQWAIT_MAX_RETRIES 100
25 25
26#define BCM43xx_IO_SIZE 8192 26#define BCM43xx_IO_SIZE 8192
27 27
@@ -333,7 +333,7 @@
333#define BCM43xx_SBF_PS2 0x04000000 333#define BCM43xx_SBF_PS2 0x04000000
334#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000 334#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000
335#define BCM43xx_SBF_TIME_UPDATE 0x10000000 335#define BCM43xx_SBF_TIME_UPDATE 0x10000000
336#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/ 336#define BCM43xx_SBF_MODE_G 0x80000000
337 337
338/* Microcode */ 338/* Microcode */
339#define BCM43xx_UCODE_REVISION 0x0000 339#define BCM43xx_UCODE_REVISION 0x0000
@@ -507,8 +507,6 @@ struct bcm43xx_sprominfo {
507 u8 et1macaddr[6]; 507 u8 et1macaddr[6];
508 u8 et0phyaddr:5; 508 u8 et0phyaddr:5;
509 u8 et1phyaddr:5; 509 u8 et1phyaddr:5;
510 u8 et0mdcport:1;
511 u8 et1mdcport:1;
512 u8 boardrev; 510 u8 boardrev;
513 u8 locale:4; 511 u8 locale:4;
514 u8 antennas_aphy:2; 512 u8 antennas_aphy:2;
@@ -542,7 +540,7 @@ struct bcm43xx_lopair {
542 540
543struct bcm43xx_phyinfo { 541struct bcm43xx_phyinfo {
544 /* Hardware Data */ 542 /* Hardware Data */
545 u8 version; 543 u8 analog;
546 u8 type; 544 u8 type;
547 u8 rev; 545 u8 rev;
548 u16 antenna_diversity; 546 u16 antenna_diversity;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
index ad8e569d1faf..f2b8dbac55a4 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
@@ -325,6 +325,21 @@ void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
325 } 325 }
326} 326}
327 327
328void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val)
329{
330 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
331 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
332 mmiowb();
333 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA2, (val & 0xFFFF0000) >> 16);
334 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val & 0x0000FFFF);
335 } else {
336 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
337 mmiowb();
338 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA2, (val & 0xFFFF0000) >> 16);
339 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val & 0x0000FFFF);
340 }
341}
342
328u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset) 343u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset)
329{ 344{
330 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) { 345 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
index 464521abf73c..d7eaf5f25b7f 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
@@ -27,6 +27,7 @@ extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE];
27 27
28 28
29void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val); 29void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
30void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val);
30u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset); 31u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset);
31 32
32#endif /* BCM43xx_ILT_H_ */ 33#endif /* BCM43xx_ILT_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 2e400aacc436..73c831a3b747 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -851,8 +851,6 @@ static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
851 value = sprom[BCM43xx_SPROM_ETHPHY]; 851 value = sprom[BCM43xx_SPROM_ETHPHY];
852 bcm->sprom.et0phyaddr = (value & 0x001F); 852 bcm->sprom.et0phyaddr = (value & 0x001F);
853 bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5; 853 bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5;
854 bcm->sprom.et0mdcport = (value & (1 << 14)) >> 14;
855 bcm->sprom.et1mdcport = (value & (1 << 15)) >> 15;
856 854
857 /* boardrev, antennas, locale */ 855 /* boardrev, antennas, locale */
858 value = sprom[BCM43xx_SPROM_BOARDREV]; 856 value = sprom[BCM43xx_SPROM_BOARDREV];
@@ -1449,12 +1447,10 @@ static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
1449 1447
1450 bcm43xx_debugfs_log_txstat(bcm, &stat); 1448 bcm43xx_debugfs_log_txstat(bcm, &stat);
1451 1449
1452 if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE) 1450 if (stat.flags & BCM43xx_TXSTAT_FLAG_AMPDU)
1451 continue;
1452 if (stat.flags & BCM43xx_TXSTAT_FLAG_INTER)
1453 continue; 1453 continue;
1454 if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
1455 //TODO: packet was not acked (was lost)
1456 }
1457 //TODO: There are more (unknown) flags to test. see bcm43xx_main.h
1458 1454
1459 if (bcm43xx_using_pio(bcm)) 1455 if (bcm43xx_using_pio(bcm))
1460 bcm43xx_pio_handle_xmitstatus(bcm, &stat); 1456 bcm43xx_pio_handle_xmitstatus(bcm, &stat);
@@ -3696,7 +3692,7 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3696{ 3692{
3697 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 3693 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3698 u16 value; 3694 u16 value;
3699 u8 phy_version; 3695 u8 phy_analog;
3700 u8 phy_type; 3696 u8 phy_type;
3701 u8 phy_rev; 3697 u8 phy_rev;
3702 int phy_rev_ok = 1; 3698 int phy_rev_ok = 1;
@@ -3704,12 +3700,12 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3704 3700
3705 value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER); 3701 value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
3706 3702
3707 phy_version = (value & 0xF000) >> 12; 3703 phy_analog = (value & 0xF000) >> 12;
3708 phy_type = (value & 0x0F00) >> 8; 3704 phy_type = (value & 0x0F00) >> 8;
3709 phy_rev = (value & 0x000F); 3705 phy_rev = (value & 0x000F);
3710 3706
3711 dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n", 3707 dprintk(KERN_INFO PFX "Detected PHY: Analog: %x, Type %x, Revision %x\n",
3712 phy_version, phy_type, phy_rev); 3708 phy_analog, phy_type, phy_rev);
3713 3709
3714 switch (phy_type) { 3710 switch (phy_type) {
3715 case BCM43xx_PHYTYPE_A: 3711 case BCM43xx_PHYTYPE_A:
@@ -3752,7 +3748,7 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3752 phy_rev); 3748 phy_rev);
3753 } 3749 }
3754 3750
3755 phy->version = phy_version; 3751 phy->analog = phy_analog;
3756 phy->type = phy_type; 3752 phy->type = phy_type;
3757 phy->rev = phy_rev; 3753 phy->rev = phy_rev;
3758 if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) { 3754 if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index 52ce2a9334fb..3a5c9c2b2150 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -205,8 +205,8 @@ static void bcm43xx_phy_init_pctl(struct bcm43xx_private *bcm)
205 (bcm->board_type == 0x0416)) 205 (bcm->board_type == 0x0416))
206 return; 206 return;
207 207
208 bcm43xx_write16(bcm, 0x03E6, bcm43xx_read16(bcm, 0x03E6) & 0xFFDF);
209 bcm43xx_phy_write(bcm, 0x0028, 0x8018); 208 bcm43xx_phy_write(bcm, 0x0028, 0x8018);
209 bcm43xx_write16(bcm, 0x03E6, bcm43xx_read16(bcm, 0x03E6) & 0xFFDF);
210 210
211 if (phy->type == BCM43xx_PHYTYPE_G) { 211 if (phy->type == BCM43xx_PHYTYPE_G) {
212 if (!phy->connected) 212 if (!phy->connected)
@@ -317,6 +317,13 @@ static void bcm43xx_phy_agcsetup(struct bcm43xx_private *bcm)
317 bcm43xx_ilt_write(bcm, offset + 0x0801, 7); 317 bcm43xx_ilt_write(bcm, offset + 0x0801, 7);
318 bcm43xx_ilt_write(bcm, offset + 0x0802, 16); 318 bcm43xx_ilt_write(bcm, offset + 0x0802, 16);
319 bcm43xx_ilt_write(bcm, offset + 0x0803, 28); 319 bcm43xx_ilt_write(bcm, offset + 0x0803, 28);
320
321 if (phy->rev >= 6) {
322 bcm43xx_phy_write(bcm, 0x0426, (bcm43xx_phy_read(bcm, 0x0426)
323 & 0xFFFC));
324 bcm43xx_phy_write(bcm, 0x0426, (bcm43xx_phy_read(bcm, 0x0426)
325 & 0xEFFF));
326 }
320} 327}
321 328
322static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm) 329static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
@@ -337,7 +344,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
337 for (i = 0; i < BCM43xx_ILT_NOISEG1_SIZE; i++) 344 for (i = 0; i < BCM43xx_ILT_NOISEG1_SIZE; i++)
338 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg1[i]); 345 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg1[i]);
339 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++) 346 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
340 bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]); 347 bcm43xx_ilt_write32(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
341 } else { 348 } else {
342 /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */ 349 /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */
343 bcm43xx_nrssi_hw_write(bcm, 0xBA98, (s16)0x7654); 350 bcm43xx_nrssi_hw_write(bcm, 0xBA98, (s16)0x7654);
@@ -377,7 +384,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
377 384
378 if (phy->rev == 1) { 385 if (phy->rev == 1) {
379 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++) 386 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
380 bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]); 387 bcm43xx_ilt_write32(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
381 for (i = 0; i < 4; i++) { 388 for (i = 0; i < 4; i++) {
382 bcm43xx_ilt_write(bcm, 0x5404 + i, 0x0020); 389 bcm43xx_ilt_write(bcm, 0x5404 + i, 0x0020);
383 bcm43xx_ilt_write(bcm, 0x5408 + i, 0x0020); 390 bcm43xx_ilt_write(bcm, 0x5408 + i, 0x0020);
@@ -500,10 +507,10 @@ static void bcm43xx_phy_setupa(struct bcm43xx_private *bcm)
500 for (i = 0; i < BCM43xx_ILT_NOISEA2_SIZE; i++) 507 for (i = 0; i < BCM43xx_ILT_NOISEA2_SIZE; i++)
501 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea2[i]); 508 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea2[i]);
502 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++) 509 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
503 bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]); 510 bcm43xx_ilt_write32(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
504 bcm43xx_phy_init_noisescaletbl(bcm); 511 bcm43xx_phy_init_noisescaletbl(bcm);
505 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++) 512 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
506 bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]); 513 bcm43xx_ilt_write32(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
507 break; 514 break;
508 case 3: 515 case 3:
509 for (i = 0; i < 64; i++) 516 for (i = 0; i < 64; i++)
@@ -729,19 +736,19 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
729 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 736 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
730 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 737 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
731 u16 offset; 738 u16 offset;
739 u16 value;
740 u8 old_channel;
732 741
733 if (phy->version == 1 && 742 if (phy->analog == 1)
734 radio->version == 0x2050) {
735 bcm43xx_radio_write16(bcm, 0x007A, 743 bcm43xx_radio_write16(bcm, 0x007A,
736 bcm43xx_radio_read16(bcm, 0x007A) 744 bcm43xx_radio_read16(bcm, 0x007A)
737 | 0x0050); 745 | 0x0050);
738 }
739 if ((bcm->board_vendor != PCI_VENDOR_ID_BROADCOM) && 746 if ((bcm->board_vendor != PCI_VENDOR_ID_BROADCOM) &&
740 (bcm->board_type != 0x0416)) { 747 (bcm->board_type != 0x0416)) {
748 value = 0x2120;
741 for (offset = 0x00A8 ; offset < 0x00C7; offset++) { 749 for (offset = 0x00A8 ; offset < 0x00C7; offset++) {
742 bcm43xx_phy_write(bcm, offset, 750 bcm43xx_phy_write(bcm, offset, value);
743 (bcm43xx_phy_read(bcm, offset) + 0x2020) 751 value += 0x0202;
744 & 0x3F3F);
745 } 752 }
746 } 753 }
747 bcm43xx_phy_write(bcm, 0x0035, 754 bcm43xx_phy_write(bcm, 0x0035,
@@ -750,7 +757,7 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
750 if (radio->version == 0x2050) 757 if (radio->version == 0x2050)
751 bcm43xx_phy_write(bcm, 0x0038, 0x0667); 758 bcm43xx_phy_write(bcm, 0x0038, 0x0667);
752 759
753 if (phy->connected) { 760 if (phy->type == BCM43xx_PHYTYPE_G) {
754 if (radio->version == 0x2050) { 761 if (radio->version == 0x2050) {
755 bcm43xx_radio_write16(bcm, 0x007A, 762 bcm43xx_radio_write16(bcm, 0x007A,
756 bcm43xx_radio_read16(bcm, 0x007A) 763 bcm43xx_radio_read16(bcm, 0x007A)
@@ -776,7 +783,7 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
776 bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | (1 << 11)); 783 bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | (1 << 11));
777 } 784 }
778 785
779 if (phy->version == 1 && radio->version == 0x2050) { 786 if (phy->analog == 1) {
780 bcm43xx_phy_write(bcm, 0x0026, 0xCE00); 787 bcm43xx_phy_write(bcm, 0x0026, 0xCE00);
781 bcm43xx_phy_write(bcm, 0x0021, 0x3763); 788 bcm43xx_phy_write(bcm, 0x0021, 0x3763);
782 bcm43xx_phy_write(bcm, 0x0022, 0x1BC3); 789 bcm43xx_phy_write(bcm, 0x0022, 0x1BC3);
@@ -787,14 +794,15 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
787 bcm43xx_phy_write(bcm, 0x0030, 0x00C6); 794 bcm43xx_phy_write(bcm, 0x0030, 0x00C6);
788 bcm43xx_write16(bcm, 0x03EC, 0x3F22); 795 bcm43xx_write16(bcm, 0x03EC, 0x3F22);
789 796
790 if (phy->version == 1 && radio->version == 0x2050) 797 if (phy->analog == 1)
791 bcm43xx_phy_write(bcm, 0x0020, 0x3E1C); 798 bcm43xx_phy_write(bcm, 0x0020, 0x3E1C);
792 else 799 else
793 bcm43xx_phy_write(bcm, 0x0020, 0x301C); 800 bcm43xx_phy_write(bcm, 0x0020, 0x301C);
794 801
795 if (phy->version == 0) 802 if (phy->analog == 0)
796 bcm43xx_write16(bcm, 0x03E4, 0x3000); 803 bcm43xx_write16(bcm, 0x03E4, 0x3000);
797 804
805 old_channel = radio->channel;
798 /* Force to channel 7, even if not supported. */ 806 /* Force to channel 7, even if not supported. */
799 bcm43xx_radio_selectchannel(bcm, 7, 0); 807 bcm43xx_radio_selectchannel(bcm, 7, 0);
800 808
@@ -816,11 +824,11 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
816 824
817 bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0007); 825 bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0007);
818 826
819 bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); 827 bcm43xx_radio_selectchannel(bcm, old_channel, 0);
820 828
821 bcm43xx_phy_write(bcm, 0x0014, 0x0080); 829 bcm43xx_phy_write(bcm, 0x0014, 0x0080);
822 bcm43xx_phy_write(bcm, 0x0032, 0x00CA); 830 bcm43xx_phy_write(bcm, 0x0032, 0x00CA);
823 bcm43xx_phy_write(bcm, 0x88A3, 0x002A); 831 bcm43xx_phy_write(bcm, 0x002A, 0x88A3);
824 832
825 bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); 833 bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
826 834
@@ -835,61 +843,24 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
835 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 843 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
836 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 844 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
837 u16 offset, val; 845 u16 offset, val;
846 u8 old_channel;
838 847
839 bcm43xx_phy_write(bcm, 0x003E, 0x817A); 848 bcm43xx_phy_write(bcm, 0x003E, 0x817A);
840 bcm43xx_radio_write16(bcm, 0x007A, 849 bcm43xx_radio_write16(bcm, 0x007A,
841 (bcm43xx_radio_read16(bcm, 0x007A) | 0x0058)); 850 (bcm43xx_radio_read16(bcm, 0x007A) | 0x0058));
842 if ((radio->manufact == 0x17F) && 851 if (radio->revision == 4 ||
843 (radio->version == 0x2050) && 852 radio->revision == 5) {
844 (radio->revision == 3 || 853 bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
845 radio->revision == 4 || 854 bcm43xx_radio_write16(bcm, 0x0052, 0x0070);
846 radio->revision == 5)) { 855 bcm43xx_radio_write16(bcm, 0x0053, 0x00B3);
847 bcm43xx_radio_write16(bcm, 0x0051, 0x001F); 856 bcm43xx_radio_write16(bcm, 0x0054, 0x009B);
848 bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
849 bcm43xx_radio_write16(bcm, 0x0053, 0x005B);
850 bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
851 bcm43xx_radio_write16(bcm, 0x005A, 0x0088); 857 bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
852 bcm43xx_radio_write16(bcm, 0x005B, 0x0088); 858 bcm43xx_radio_write16(bcm, 0x005B, 0x0088);
853 bcm43xx_radio_write16(bcm, 0x005D, 0x0088); 859 bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
854 bcm43xx_radio_write16(bcm, 0x005E, 0x0088); 860 bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
855 bcm43xx_radio_write16(bcm, 0x007D, 0x0088); 861 bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
856 } 862 }
857 if ((radio->manufact == 0x17F) && 863 if (radio->revision == 8) {
858 (radio->version == 0x2050) &&
859 (radio->revision == 6)) {
860 bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
861 bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
862 bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
863 bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
864 bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
865 bcm43xx_radio_write16(bcm, 0x005B, 0x008B);
866 bcm43xx_radio_write16(bcm, 0x005C, 0x00B5);
867 bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
868 bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
869 bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
870 bcm43xx_radio_write16(bcm, 0x007C, 0x0001);
871 bcm43xx_radio_write16(bcm, 0x007E, 0x0008);
872 }
873 if ((radio->manufact == 0x17F) &&
874 (radio->version == 0x2050) &&
875 (radio->revision == 7)) {
876 bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
877 bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
878 bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
879 bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
880 bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
881 bcm43xx_radio_write16(bcm, 0x005B, 0x00A8);
882 bcm43xx_radio_write16(bcm, 0x005C, 0x0075);
883 bcm43xx_radio_write16(bcm, 0x005D, 0x00F5);
884 bcm43xx_radio_write16(bcm, 0x005E, 0x00B8);
885 bcm43xx_radio_write16(bcm, 0x007D, 0x00E8);
886 bcm43xx_radio_write16(bcm, 0x007C, 0x0001);
887 bcm43xx_radio_write16(bcm, 0x007E, 0x0008);
888 bcm43xx_radio_write16(bcm, 0x007B, 0x0000);
889 }
890 if ((radio->manufact == 0x17F) &&
891 (radio->version == 0x2050) &&
892 (radio->revision == 8)) {
893 bcm43xx_radio_write16(bcm, 0x0051, 0x0000); 864 bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
894 bcm43xx_radio_write16(bcm, 0x0052, 0x0040); 865 bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
895 bcm43xx_radio_write16(bcm, 0x0053, 0x00B7); 866 bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
@@ -933,20 +904,26 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
933 bcm43xx_phy_read(bcm, 0x0802) | 0x0100); 904 bcm43xx_phy_read(bcm, 0x0802) | 0x0100);
934 bcm43xx_phy_write(bcm, 0x042B, 905 bcm43xx_phy_write(bcm, 0x042B,
935 bcm43xx_phy_read(bcm, 0x042B) | 0x2000); 906 bcm43xx_phy_read(bcm, 0x042B) | 0x2000);
907 bcm43xx_phy_write(bcm, 0x5B, 0x0000);
908 bcm43xx_phy_write(bcm, 0x5C, 0x0000);
936 } 909 }
937 910
938 /* Force to channel 7, even if not supported. */ 911 old_channel = radio->channel;
939 bcm43xx_radio_selectchannel(bcm, 7, 0); 912 if (old_channel >= 8)
913 bcm43xx_radio_selectchannel(bcm, 1, 0);
914 else
915 bcm43xx_radio_selectchannel(bcm, 13, 0);
940 916
941 bcm43xx_radio_write16(bcm, 0x0050, 0x0020); 917 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
942 bcm43xx_radio_write16(bcm, 0x0050, 0x0023); 918 bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
943 udelay(40); 919 udelay(40);
944 bcm43xx_radio_write16(bcm, 0x007C, (bcm43xx_radio_read16(bcm, 0x007C) | 0x0002)); 920 if (radio->revision < 6 || radio-> revision == 8) {
945 bcm43xx_radio_write16(bcm, 0x0050, 0x0020); 921 bcm43xx_radio_write16(bcm, 0x007C, (bcm43xx_radio_read16(bcm, 0x007C)
946 if (radio->manufact == 0x17F && 922 | 0x0002));
947 radio->version == 0x2050 &&
948 radio->revision <= 2) {
949 bcm43xx_radio_write16(bcm, 0x0050, 0x0020); 923 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
924 }
925 if (radio->revision <= 2) {
926 bcm43xx_radio_write16(bcm, 0x007C, 0x0020);
950 bcm43xx_radio_write16(bcm, 0x005A, 0x0070); 927 bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
951 bcm43xx_radio_write16(bcm, 0x005B, 0x007B); 928 bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
952 bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); 929 bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
@@ -954,46 +931,41 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
954 bcm43xx_radio_write16(bcm, 0x007A, 931 bcm43xx_radio_write16(bcm, 0x007A,
955 (bcm43xx_radio_read16(bcm, 0x007A) & 0x00F8) | 0x0007); 932 (bcm43xx_radio_read16(bcm, 0x007A) & 0x00F8) | 0x0007);
956 933
957 bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); 934 bcm43xx_radio_selectchannel(bcm, old_channel, 0);
958 935
959 bcm43xx_phy_write(bcm, 0x0014, 0x0200); 936 bcm43xx_phy_write(bcm, 0x0014, 0x0200);
960 if (radio->version == 0x2050){ 937 if (radio->revision >= 6)
961 if (radio->revision == 3 || 938 bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
962 radio->revision == 4 || 939 else
963 radio->revision == 5) 940 bcm43xx_phy_write(bcm, 0x002A, 0x8AC0);
964 bcm43xx_phy_write(bcm, 0x002A, 0x8AC0);
965 else
966 bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
967 }
968 bcm43xx_phy_write(bcm, 0x0038, 0x0668); 941 bcm43xx_phy_write(bcm, 0x0038, 0x0668);
969 bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); 942 bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
970 if (radio->version == 0x2050) { 943 if (radio->revision <= 5)
971 if (radio->revision == 3 || 944 bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003);
972 radio->revision == 4 || 945 if (radio->revision <= 2)
973 radio->revision == 5) 946 bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
974 bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003);
975 else if (radio->revision <= 2)
976 bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
977 }
978 947
979 if (phy->rev == 4) 948 if (phy->analog == 4){
980 bcm43xx_phy_write(bcm, 0x0002, (bcm43xx_phy_read(bcm, 0x0002) & 0xFFC0) | 0x0004);
981 else
982 bcm43xx_write16(bcm, 0x03E4, 0x0009); 949 bcm43xx_write16(bcm, 0x03E4, 0x0009);
950 bcm43xx_phy_write(bcm, 0x61, bcm43xx_phy_read(bcm, 0x61) & 0xFFF);
951 } else {
952 bcm43xx_phy_write(bcm, 0x0002, (bcm43xx_phy_read(bcm, 0x0002) & 0xFFC0) | 0x0004);
953 }
954 if (phy->type == BCM43xx_PHYTYPE_G)
955 bcm43xx_write16(bcm, 0x03E6, 0x0);
983 if (phy->type == BCM43xx_PHYTYPE_B) { 956 if (phy->type == BCM43xx_PHYTYPE_B) {
984 bcm43xx_write16(bcm, 0x03E6, 0x8140); 957 bcm43xx_write16(bcm, 0x03E6, 0x8140);
985 bcm43xx_phy_write(bcm, 0x0016, 0x0410); 958 bcm43xx_phy_write(bcm, 0x0016, 0x0410);
986 bcm43xx_phy_write(bcm, 0x0017, 0x0820); 959 bcm43xx_phy_write(bcm, 0x0017, 0x0820);
987 bcm43xx_phy_write(bcm, 0x0062, 0x0007); 960 bcm43xx_phy_write(bcm, 0x0062, 0x0007);
988 (void) bcm43xx_radio_calibrationvalue(bcm); 961 (void) bcm43xx_radio_calibrationvalue(bcm);
989 bcm43xx_phy_lo_b_measure(bcm); 962 bcm43xx_phy_lo_g_measure(bcm);
990 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { 963 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
991 bcm43xx_calc_nrssi_slope(bcm); 964 bcm43xx_calc_nrssi_slope(bcm);
992 bcm43xx_calc_nrssi_threshold(bcm); 965 bcm43xx_calc_nrssi_threshold(bcm);
993 } 966 }
994 bcm43xx_phy_init_pctl(bcm); 967 bcm43xx_phy_init_pctl(bcm);
995 } else 968 }
996 bcm43xx_write16(bcm, 0x03E6, 0x0);
997} 969}
998 970
999static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm) 971static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
@@ -1063,7 +1035,7 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
1063 bcm43xx_phy_write(bcm, 0x005A, 0x0780); 1035 bcm43xx_phy_write(bcm, 0x005A, 0x0780);
1064 bcm43xx_phy_write(bcm, 0x0059, 0xC810); 1036 bcm43xx_phy_write(bcm, 0x0059, 0xC810);
1065 bcm43xx_phy_write(bcm, 0x0058, 0x000D); 1037 bcm43xx_phy_write(bcm, 0x0058, 0x000D);
1066 if (phy->version == 0) { 1038 if (phy->analog == 0) {
1067 bcm43xx_phy_write(bcm, 0x0003, 0x0122); 1039 bcm43xx_phy_write(bcm, 0x0003, 0x0122);
1068 } else { 1040 } else {
1069 bcm43xx_phy_write(bcm, 0x000A, 1041 bcm43xx_phy_write(bcm, 0x000A,
@@ -1205,27 +1177,30 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
1205 if (phy->rev >= 2) { 1177 if (phy->rev >= 2) {
1206 bcm43xx_phy_write(bcm, 0x0814, 0x0000); 1178 bcm43xx_phy_write(bcm, 0x0814, 0x0000);
1207 bcm43xx_phy_write(bcm, 0x0815, 0x0000); 1179 bcm43xx_phy_write(bcm, 0x0815, 0x0000);
1208 if (phy->rev == 2) 1180 }
1209 bcm43xx_phy_write(bcm, 0x0811, 0x0000); 1181 if (phy->rev == 2) {
1210 else if (phy->rev >= 3) 1182 bcm43xx_phy_write(bcm, 0x0811, 0x0000);
1211 bcm43xx_phy_write(bcm, 0x0811, 0x0400);
1212 bcm43xx_phy_write(bcm, 0x0015, 0x00C0); 1183 bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
1213 if (phy->connected) { 1184 }
1214 tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF; 1185 if (phy->rev >= 3) {
1215 if (tmp < 6) { 1186 bcm43xx_phy_write(bcm, 0x0811, 0x0400);
1216 bcm43xx_phy_write(bcm, 0x04C2, 0x1816); 1187 bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
1217 bcm43xx_phy_write(bcm, 0x04C3, 0x8006); 1188 }
1218 if (tmp != 3) { 1189 if (phy->connected) {
1219 bcm43xx_phy_write(bcm, 0x04CC, 1190 tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF;
1220 (bcm43xx_phy_read(bcm, 0x04CC) 1191 if (tmp < 6) {
1221 & 0x00FF) | 0x1F00); 1192 bcm43xx_phy_write(bcm, 0x04C2, 0x1816);
1222 } 1193 bcm43xx_phy_write(bcm, 0x04C3, 0x8006);
1194 if (tmp != 3) {
1195 bcm43xx_phy_write(bcm, 0x04CC,
1196 (bcm43xx_phy_read(bcm, 0x04CC)
1197 & 0x00FF) | 0x1F00);
1223 } 1198 }
1224 } 1199 }
1225 } 1200 }
1226 if (phy->rev < 3 && phy->connected) 1201 if (phy->rev < 3 && phy->connected)
1227 bcm43xx_phy_write(bcm, 0x047E, 0x0078); 1202 bcm43xx_phy_write(bcm, 0x047E, 0x0078);
1228 if (phy->rev >= 6 && phy->rev <= 8) { 1203 if (radio->revision == 8) {
1229 bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080); 1204 bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080);
1230 bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004); 1205 bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004);
1231 } 1206 }
@@ -1638,14 +1613,14 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
1638 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 1613 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1639 u16 value; 1614 u16 value;
1640 1615
1641 if (phy->version == 0) { 1616 if (phy->analog == 0) {
1642 value = (bcm43xx_read16(bcm, 0x03E6) & 0xFFF0); 1617 value = (bcm43xx_read16(bcm, 0x03E6) & 0xFFF0);
1643 value |= (baseband_attenuation & 0x000F); 1618 value |= (baseband_attenuation & 0x000F);
1644 bcm43xx_write16(bcm, 0x03E6, value); 1619 bcm43xx_write16(bcm, 0x03E6, value);
1645 return; 1620 return;
1646 } 1621 }
1647 1622
1648 if (phy->version > 1) { 1623 if (phy->analog > 1) {
1649 value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C; 1624 value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C;
1650 value |= (baseband_attenuation << 2) & 0x003C; 1625 value |= (baseband_attenuation << 2) & 0x003C;
1651 } else { 1626 } else {
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
index af19a07032a3..32beb91b7164 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -1393,11 +1393,12 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1393 backup[12] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT); 1393 backup[12] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
1394 1394
1395 // Initialization 1395 // Initialization
1396 if (phy->version == 0) { 1396 if (phy->analog == 0) {
1397 bcm43xx_write16(bcm, 0x03E6, 0x0122); 1397 bcm43xx_write16(bcm, 0x03E6, 0x0122);
1398 } else { 1398 } else {
1399 if (phy->version >= 2) 1399 if (phy->analog >= 2)
1400 bcm43xx_write16(bcm, 0x03E6, 0x0040); 1400 bcm43xx_phy_write(bcm, 0x0003, (bcm43xx_phy_read(bcm, 0x0003)
1401 & 0xFFBF) | 0x0040);
1401 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 1402 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
1402 (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) | 0x2000)); 1403 (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) | 0x2000));
1403 } 1404 }
@@ -1405,7 +1406,7 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1405 ret = bcm43xx_radio_calibrationvalue(bcm); 1406 ret = bcm43xx_radio_calibrationvalue(bcm);
1406 1407
1407 if (phy->type == BCM43xx_PHYTYPE_B) 1408 if (phy->type == BCM43xx_PHYTYPE_B)
1408 bcm43xx_radio_write16(bcm, 0x0078, 0x0003); 1409 bcm43xx_radio_write16(bcm, 0x0078, 0x0026);
1409 1410
1410 bcm43xx_phy_write(bcm, 0x0015, 0xBFAF); 1411 bcm43xx_phy_write(bcm, 0x0015, 0xBFAF);
1411 bcm43xx_phy_write(bcm, 0x002B, 0x1403); 1412 bcm43xx_phy_write(bcm, 0x002B, 0x1403);
@@ -1416,7 +1417,7 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1416 (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004)); 1417 (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004));
1417 bcm43xx_radio_write16(bcm, 0x0052, 0x0000); 1418 bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
1418 bcm43xx_radio_write16(bcm, 0x0043, 1419 bcm43xx_radio_write16(bcm, 0x0043,
1419 bcm43xx_radio_read16(bcm, 0x0043) | 0x0009); 1420 (bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0) | 0x0009);
1420 bcm43xx_phy_write(bcm, 0x0058, 0x0000); 1421 bcm43xx_phy_write(bcm, 0x0058, 0x0000);
1421 1422
1422 for (i = 0; i < 16; i++) { 1423 for (i = 0; i < 16; i++) {
@@ -1488,7 +1489,7 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1488 bcm43xx_phy_write(bcm, 0x0059, backup[17]); 1489 bcm43xx_phy_write(bcm, 0x0059, backup[17]);
1489 bcm43xx_phy_write(bcm, 0x0058, backup[18]); 1490 bcm43xx_phy_write(bcm, 0x0058, backup[18]);
1490 bcm43xx_write16(bcm, 0x03E6, backup[11]); 1491 bcm43xx_write16(bcm, 0x03E6, backup[11]);
1491 if (phy->version != 0) 1492 if (phy->analog != 0)
1492 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[12]); 1493 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[12]);
1493 bcm43xx_phy_write(bcm, 0x0035, backup[10]); 1494 bcm43xx_phy_write(bcm, 0x0035, backup[10]);
1494 bcm43xx_radio_selectchannel(bcm, radio->channel, 1); 1495 bcm43xx_radio_selectchannel(bcm, radio->channel, 1);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
index 2aed19e35c77..9ecf2bf0d25d 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
@@ -137,14 +137,8 @@ struct bcm43xx_xmitstatus {
137 u16 unknown; //FIXME 137 u16 unknown; //FIXME
138}; 138};
139 139
140#define BCM43xx_TXSTAT_FLAG_ACK 0x01 140#define BCM43xx_TXSTAT_FLAG_AMPDU 0x10
141//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x02 141#define BCM43xx_TXSTAT_FLAG_INTER 0x20
142//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x04
143//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x08
144//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x10
145#define BCM43xx_TXSTAT_FLAG_IGNORE 0x20
146//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x40
147//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x80
148 142
149u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate); 143u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate);
150u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate); 144u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate);
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index e89c890d16fd..ef37a75d550b 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -2,13 +2,14 @@
2#define HOSTAP_H 2#define HOSTAP_H
3 3
4#include <linux/ethtool.h> 4#include <linux/ethtool.h>
5#include <linux/kernel.h>
5 6
6#include "hostap_wlan.h" 7#include "hostap_wlan.h"
7#include "hostap_ap.h" 8#include "hostap_ap.h"
8 9
9static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 10static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
10 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; 11 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
11#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0])) 12#define FREQ_COUNT ARRAY_SIZE(freq_list)
12 13
13/* hostap.c */ 14/* hostap.c */
14 15
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index d0639a45cd2c..ad6e4a428355 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -2888,7 +2888,7 @@ static int __ipw2100_tx_process(struct ipw2100_priv *priv)
2888 2888
2889#ifdef CONFIG_IPW2100_DEBUG 2889#ifdef CONFIG_IPW2100_DEBUG
2890 if (packet->info.c_struct.cmd->host_command_reg < 2890 if (packet->info.c_struct.cmd->host_command_reg <
2891 sizeof(command_types) / sizeof(*command_types)) 2891 ARRAY_SIZE(command_types))
2892 IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n", 2892 IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
2893 command_types[packet->info.c_struct.cmd-> 2893 command_types[packet->info.c_struct.cmd->
2894 host_command_reg], 2894 host_command_reg],
@@ -3736,7 +3736,7 @@ static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3736 3736
3737 out += sprintf(out, "%30s [Address ] : Hex\n", "Register"); 3737 out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
3738 3738
3739 for (i = 0; i < (sizeof(hw_data) / sizeof(*hw_data)); i++) { 3739 for (i = 0; i < ARRAY_SIZE(hw_data); i++) {
3740 read_register(dev, hw_data[i].addr, &val); 3740 read_register(dev, hw_data[i].addr, &val);
3741 out += sprintf(out, "%30s [%08X] : %08X\n", 3741 out += sprintf(out, "%30s [%08X] : %08X\n",
3742 hw_data[i].name, hw_data[i].addr, val); 3742 hw_data[i].name, hw_data[i].addr, val);
@@ -3757,7 +3757,7 @@ static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3757 3757
3758 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry"); 3758 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
3759 3759
3760 for (i = 0; i < (sizeof(nic_data) / sizeof(*nic_data)); i++) { 3760 for (i = 0; i < ARRAY_SIZE(nic_data); i++) {
3761 u8 tmp8; 3761 u8 tmp8;
3762 u16 tmp16; 3762 u16 tmp16;
3763 u32 tmp32; 3763 u32 tmp32;
@@ -3894,13 +3894,11 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3894 if (priv->status & STATUS_RF_KILL_MASK) 3894 if (priv->status & STATUS_RF_KILL_MASK)
3895 return 0; 3895 return 0;
3896 3896
3897 if (loop >= sizeof(ord_data) / sizeof(*ord_data)) 3897 if (loop >= ARRAY_SIZE(ord_data))
3898 loop = 0; 3898 loop = 0;
3899 3899
3900 /* sysfs provides us PAGE_SIZE buffer */ 3900 /* sysfs provides us PAGE_SIZE buffer */
3901 while (len < PAGE_SIZE - 128 && 3901 while (len < PAGE_SIZE - 128 && loop < ARRAY_SIZE(ord_data)) {
3902 loop < (sizeof(ord_data) / sizeof(*ord_data))) {
3903
3904 val_len = sizeof(u32); 3902 val_len = sizeof(u32);
3905 3903
3906 if (ipw2100_get_ordinal(priv, ord_data[loop].index, &val, 3904 if (ipw2100_get_ordinal(priv, ord_data[loop].index, &val,
@@ -6589,7 +6587,7 @@ static const long ipw2100_rates_11b[] = {
6589 11000000 6587 11000000
6590}; 6588};
6591 6589
6592#define RATE_COUNT (sizeof(ipw2100_rates_11b) / sizeof(ipw2100_rates_11b[0])) 6590#define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b)
6593 6591
6594static int ipw2100_wx_get_name(struct net_device *dev, 6592static int ipw2100_wx_get_name(struct net_device *dev,
6595 struct iw_request_info *info, 6593 struct iw_request_info *info,
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 838d510213c6..841b3c136ad9 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -1395,11 +1395,16 @@ static int prism54_set_auth(struct net_device *ndev,
1395 break; 1395 break;
1396 1396
1397 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1397 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1398 dot1x = param->value ? 1 : 0; 1398 /* dot1x should be the opposite of RX_UNENCRYPTED_EAPOL;
1399 * turn off dot1x when allowing receipt of unencrypted EAPOL
1400 * frames, turn on dot1x when receipt should be disallowed
1401 */
1402 dot1x = param->value ? 0 : 0x01;
1399 break; 1403 break;
1400 1404
1401 case IW_AUTH_PRIVACY_INVOKED: 1405 case IW_AUTH_PRIVACY_INVOKED:
1402 privinvoked = param->value ? 1 : 0; 1406 privinvoked = param->value ? 1 : 0;
1407 break;
1403 1408
1404 case IW_AUTH_DROP_UNENCRYPTED: 1409 case IW_AUTH_DROP_UNENCRYPTED:
1405 exunencrypt = param->value ? 1 : 0; 1410 exunencrypt = param->value ? 1 : 0;
@@ -1589,6 +1594,7 @@ static int prism54_set_encodeext(struct net_device *ndev,
1589 } 1594 }
1590 key.type = DOT11_PRIV_TKIP; 1595 key.type = DOT11_PRIV_TKIP;
1591 key.length = KEY_SIZE_TKIP; 1596 key.length = KEY_SIZE_TKIP;
1597 break;
1592 default: 1598 default:
1593 return -EINVAL; 1599 return -EINVAL;
1594 } 1600 }
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index e6cf9df2c206..42780320cd5c 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -16,6 +16,8 @@
16 * 16 *
17 */ 17 */
18 18
19#include <linux/kernel.h>
20
19#include "prismcompat.h" 21#include "prismcompat.h"
20#include "islpci_dev.h" 22#include "islpci_dev.h"
21#include "islpci_mgt.h" 23#include "islpci_mgt.h"
@@ -692,7 +694,7 @@ mgt_update_addr(islpci_private *priv)
692 return ret; 694 return ret;
693} 695}
694 696
695#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0])) 697#define VEC_SIZE(a) ARRAY_SIZE(a)
696 698
697int 699int
698mgt_commit(islpci_private *priv) 700mgt_commit(islpci_private *priv)
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 24221e476cd3..2aa3c761dd83 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -28,7 +28,7 @@
28 */ 28 */
29static u8 wv_irq_to_psa(int irq) 29static u8 wv_irq_to_psa(int irq)
30{ 30{
31 if (irq < 0 || irq >= NELS(irqvals)) 31 if (irq < 0 || irq >= ARRAY_SIZE(irqvals))
32 return 0; 32 return 0;
33 33
34 return irqvals[irq]; 34 return irqvals[irq];
@@ -42,7 +42,7 @@ static int __init wv_psa_to_irq(u8 irqval)
42{ 42{
43 int irq; 43 int irq;
44 44
45 for (irq = 0; irq < NELS(irqvals); irq++) 45 for (irq = 0; irq < ARRAY_SIZE(irqvals); irq++)
46 if (irqvals[irq] == irqval) 46 if (irqvals[irq] == irqval)
47 return irq; 47 return irq;
48 48
@@ -1695,7 +1695,7 @@ static int wv_frequency_list(unsigned long ioaddr, /* I/O port of the card */
1695 /* Look in the table if the frequency is allowed */ 1695 /* Look in the table if the frequency is allowed */
1696 if (table[9 - (freq / 16)] & (1 << (freq % 16))) { 1696 if (table[9 - (freq / 16)] & (1 << (freq % 16))) {
1697 /* Compute approximate channel number */ 1697 /* Compute approximate channel number */
1698 while ((c < NELS(channel_bands)) && 1698 while ((c < ARRAY_SIZE(channel_bands)) &&
1699 (((channel_bands[c] >> 1) - 24) < freq)) 1699 (((channel_bands[c] >> 1) - 24) < freq))
1700 c++; 1700 c++;
1701 list[i].i = c; /* Set the list index */ 1701 list[i].i = c; /* Set the list index */
@@ -4269,7 +4269,7 @@ struct net_device * __init wavelan_probe(int unit)
4269 printk(KERN_DEBUG "%s: <-wavelan_probe()\n", dev->name); 4269 printk(KERN_DEBUG "%s: <-wavelan_probe()\n", dev->name);
4270#endif 4270#endif
4271 } else { /* Scan all possible addresses of the WaveLAN hardware. */ 4271 } else { /* Scan all possible addresses of the WaveLAN hardware. */
4272 for (i = 0; i < NELS(iobase); i++) { 4272 for (i = 0; i < ARRAY_SIZE(iobase); i++) {
4273 dev->irq = def_irq; 4273 dev->irq = def_irq;
4274 if (wavelan_config(dev, iobase[i]) == 0) { 4274 if (wavelan_config(dev, iobase[i]) == 0) {
4275#ifdef DEBUG_CALLBACK_TRACE 4275#ifdef DEBUG_CALLBACK_TRACE
@@ -4280,7 +4280,7 @@ struct net_device * __init wavelan_probe(int unit)
4280 break; 4280 break;
4281 } 4281 }
4282 } 4282 }
4283 if (i == NELS(iobase)) 4283 if (i == ARRAY_SIZE(iobase))
4284 r = -ENODEV; 4284 r = -ENODEV;
4285 } 4285 }
4286 if (r) 4286 if (r)
@@ -4327,14 +4327,14 @@ int __init init_module(void)
4327#endif 4327#endif
4328 4328
4329 /* Copy the basic set of address to be probed. */ 4329 /* Copy the basic set of address to be probed. */
4330 for (i = 0; i < NELS(iobase); i++) 4330 for (i = 0; i < ARRAY_SIZE(iobase); i++)
4331 io[i] = iobase[i]; 4331 io[i] = iobase[i];
4332 } 4332 }
4333 4333
4334 4334
4335 /* Loop on all possible base addresses. */ 4335 /* Loop on all possible base addresses. */
4336 i = -1; 4336 i = -1;
4337 while ((io[++i] != 0) && (i < NELS(io))) { 4337 while ((io[++i] != 0) && (i < ARRAY_SIZE(io))) {
4338 struct net_device *dev = alloc_etherdev(sizeof(net_local)); 4338 struct net_device *dev = alloc_etherdev(sizeof(net_local));
4339 if (!dev) 4339 if (!dev)
4340 break; 4340 break;
diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
index 72b646c77d5a..fe242812d858 100644
--- a/drivers/net/wireless/wavelan.p.h
+++ b/drivers/net/wireless/wavelan.p.h
@@ -449,9 +449,6 @@ static const char *version = "wavelan.c : v24 (SMP + wireless extensions) 11/12/
449/* Watchdog temporisation */ 449/* Watchdog temporisation */
450#define WATCHDOG_JIFFIES (512*HZ/100) 450#define WATCHDOG_JIFFIES (512*HZ/100)
451 451
452/* Macro to get the number of elements in an array */
453#define NELS(a) (sizeof(a) / sizeof(a[0]))
454
455/* ------------------------ PRIVATE IOCTL ------------------------ */ 452/* ------------------------ PRIVATE IOCTL ------------------------ */
456 453
457#define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */ 454#define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 12dfc0b6efe6..9c64f894b71b 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -113,7 +113,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
113 113
114 /* Allocate a single memory block for values and addresses. */ 114 /* Allocate a single memory block for values and addresses. */
115 count16 = 2*count; 115 count16 = 2*count;
116 a16 = kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)), 116 a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
117 GFP_NOFS); 117 GFP_NOFS);
118 if (!a16) { 118 if (!a16) {
119 dev_dbg_f(zd_chip_dev(chip), 119 dev_dbg_f(zd_chip_dev(chip),
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,
diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index a5cf1beacb44..1023ba0d6e55 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -9,17 +9,28 @@
9#define _LINUX_BACKLIGHT_H 9#define _LINUX_BACKLIGHT_H
10 10
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/mutex.h>
12#include <linux/notifier.h> 13#include <linux/notifier.h>
13 14
15/* Notes on locking:
16 *
17 * backlight_device->ops_lock is an internal backlight lock protecting the
18 * ops pointer and no code outside the core should need to touch it.
19 *
20 * Access to update_status() is serialised by the update_lock mutex since
21 * most drivers seem to need this and historically get it wrong.
22 *
23 * Most drivers don't need locking on their get_brightness() method.
24 * If yours does, you need to implement it in the driver. You can use the
25 * update_lock mutex if appropriate.
26 *
27 * Any other use of the locks below is probably wrong.
28 */
29
14struct backlight_device; 30struct backlight_device;
15struct fb_info; 31struct fb_info;
16 32
17/* This structure defines all the properties of a backlight 33struct backlight_ops {
18 (usually attached to a LCD). */
19struct backlight_properties {
20 /* Owner module */
21 struct module *owner;
22
23 /* Notify the backlight driver some property has changed */ 34 /* Notify the backlight driver some property has changed */
24 int (*update_status)(struct backlight_device *); 35 int (*update_status)(struct backlight_device *);
25 /* Return the current backlight brightness (accounting for power, 36 /* Return the current backlight brightness (accounting for power,
@@ -28,7 +39,10 @@ struct backlight_properties {
28 /* Check if given framebuffer device is the one bound to this backlight; 39 /* Check if given framebuffer device is the one bound to this backlight;
29 return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */ 40 return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */
30 int (*check_fb)(struct fb_info *); 41 int (*check_fb)(struct fb_info *);
42};
31 43
44/* This structure defines all the properties of a backlight */
45struct backlight_properties {
32 /* Current User requested brightness (0 - max_brightness) */ 46 /* Current User requested brightness (0 - max_brightness) */
33 int brightness; 47 int brightness;
34 /* Maximal value for brightness (read-only) */ 48 /* Maximal value for brightness (read-only) */
@@ -41,20 +55,34 @@ struct backlight_properties {
41}; 55};
42 56
43struct backlight_device { 57struct backlight_device {
44 /* This protects the 'props' field. If 'props' is NULL, the driver that 58 /* Backlight properties */
59 struct backlight_properties props;
60
61 /* Serialise access to update_status method */
62 struct mutex update_lock;
63
64 /* This protects the 'ops' field. If 'ops' is NULL, the driver that
45 registered this device has been unloaded, and if class_get_devdata() 65 registered this device has been unloaded, and if class_get_devdata()
46 points to something in the body of that driver, it is also invalid. */ 66 points to something in the body of that driver, it is also invalid. */
47 struct semaphore sem; 67 struct mutex ops_lock;
48 /* If this is NULL, the backing module is unloaded */ 68 struct backlight_ops *ops;
49 struct backlight_properties *props; 69
50 /* The framebuffer notifier block */ 70 /* The framebuffer notifier block */
51 struct notifier_block fb_notif; 71 struct notifier_block fb_notif;
52 /* The class device structure */ 72 /* The class device structure */
53 struct class_device class_dev; 73 struct class_device class_dev;
54}; 74};
55 75
76static inline void backlight_update_status(struct backlight_device *bd)
77{
78 mutex_lock(&bd->update_lock);
79 if (bd->ops && bd->ops->update_status)
80 bd->ops->update_status(bd);
81 mutex_unlock(&bd->update_lock);
82}
83
56extern struct backlight_device *backlight_device_register(const char *name, 84extern struct backlight_device *backlight_device_register(const char *name,
57 struct device *dev,void *devdata,struct backlight_properties *bp); 85 struct device *dev, void *devdata, struct backlight_ops *ops);
58extern void backlight_device_unregister(struct backlight_device *bd); 86extern void backlight_device_unregister(struct backlight_device *bd);
59 87
60#define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev) 88#define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev)
diff --git a/include/linux/fb.h b/include/linux/fb.h
index a78e25683f82..be913ec87169 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -516,13 +516,15 @@ struct fb_cursor_user {
516#define FB_EVENT_GET_CONSOLE_MAP 0x07 516#define FB_EVENT_GET_CONSOLE_MAP 0x07
517/* CONSOLE-SPECIFIC: set console to framebuffer mapping */ 517/* CONSOLE-SPECIFIC: set console to framebuffer mapping */
518#define FB_EVENT_SET_CONSOLE_MAP 0x08 518#define FB_EVENT_SET_CONSOLE_MAP 0x08
519/* A display blank is requested */ 519/* A hardware display blank change occured */
520#define FB_EVENT_BLANK 0x09 520#define FB_EVENT_BLANK 0x09
521/* Private modelist is to be replaced */ 521/* Private modelist is to be replaced */
522#define FB_EVENT_NEW_MODELIST 0x0A 522#define FB_EVENT_NEW_MODELIST 0x0A
523/* The resolution of the passed in fb_info about to change and 523/* The resolution of the passed in fb_info about to change and
524 all vc's should be changed */ 524 all vc's should be changed */
525#define FB_EVENT_MODE_CHANGE_ALL 0x0B 525#define FB_EVENT_MODE_CHANGE_ALL 0x0B
526/* A software display blank change occured */
527#define FB_EVENT_CONBLANK 0x0C
526 528
527struct fb_event { 529struct fb_event {
528 struct fb_info *info; 530 struct fb_info *info;
@@ -767,16 +769,13 @@ struct fb_info {
767 struct fb_videomode *mode; /* current mode */ 769 struct fb_videomode *mode; /* current mode */
768 770
769#ifdef CONFIG_FB_BACKLIGHT 771#ifdef CONFIG_FB_BACKLIGHT
770 /* Lock ordering:
771 * bl_mutex (protects bl_dev and bl_curve)
772 * bl_dev->sem (backlight class)
773 */
774 struct mutex bl_mutex;
775
776 /* assigned backlight device */ 772 /* assigned backlight device */
773 /* set before framebuffer registration,
774 remove after unregister */
777 struct backlight_device *bl_dev; 775 struct backlight_device *bl_dev;
778 776
779 /* Backlight level curve */ 777 /* Backlight level curve */
778 struct mutex bl_curve_mutex;
780 u8 bl_curve[FB_BACKLIGHT_LEVELS]; 779 u8 bl_curve[FB_BACKLIGHT_LEVELS];
781#endif 780#endif
782 781
diff --git a/include/linux/lcd.h b/include/linux/lcd.h
index d739b2e7eac2..598793c0745b 100644
--- a/include/linux/lcd.h
+++ b/include/linux/lcd.h
@@ -9,22 +9,38 @@
9#define _LINUX_LCD_H 9#define _LINUX_LCD_H
10 10
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/mutex.h>
12#include <linux/notifier.h> 13#include <linux/notifier.h>
13 14
15/* Notes on locking:
16 *
17 * lcd_device->ops_lock is an internal backlight lock protecting the ops
18 * field and no code outside the core should need to touch it.
19 *
20 * Access to set_power() is serialised by the update_lock mutex since
21 * most drivers seem to need this and historically get it wrong.
22 *
23 * Most drivers don't need locking on their get_power() method.
24 * If yours does, you need to implement it in the driver. You can use the
25 * update_lock mutex if appropriate.
26 *
27 * Any other use of the locks below is probably wrong.
28 */
29
14struct lcd_device; 30struct lcd_device;
15struct fb_info; 31struct fb_info;
16 32
17/* This structure defines all the properties of a LCD flat panel. */
18struct lcd_properties { 33struct lcd_properties {
19 /* Owner module */ 34 /* The maximum value for contrast (read-only) */
20 struct module *owner; 35 int max_contrast;
36};
37
38struct lcd_ops {
21 /* Get the LCD panel power status (0: full on, 1..3: controller 39 /* Get the LCD panel power status (0: full on, 1..3: controller
22 power on, flat panel power off, 4: full off), see FB_BLANK_XXX */ 40 power on, flat panel power off, 4: full off), see FB_BLANK_XXX */
23 int (*get_power)(struct lcd_device *); 41 int (*get_power)(struct lcd_device *);
24 /* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */ 42 /* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */
25 int (*set_power)(struct lcd_device *, int power); 43 int (*set_power)(struct lcd_device *, int power);
26 /* The maximum value for contrast (read-only) */
27 int max_contrast;
28 /* Get the current contrast setting (0-max_contrast) */ 44 /* Get the current contrast setting (0-max_contrast) */
29 int (*get_contrast)(struct lcd_device *); 45 int (*get_contrast)(struct lcd_device *);
30 /* Set LCD panel contrast */ 46 /* Set LCD panel contrast */
@@ -35,20 +51,31 @@ struct lcd_properties {
35}; 51};
36 52
37struct lcd_device { 53struct lcd_device {
38 /* This protects the 'props' field. If 'props' is NULL, the driver that 54 struct lcd_properties props;
55 /* This protects the 'ops' field. If 'ops' is NULL, the driver that
39 registered this device has been unloaded, and if class_get_devdata() 56 registered this device has been unloaded, and if class_get_devdata()
40 points to something in the body of that driver, it is also invalid. */ 57 points to something in the body of that driver, it is also invalid. */
41 struct semaphore sem; 58 struct mutex ops_lock;
42 /* If this is NULL, the backing module is unloaded */ 59 /* If this is NULL, the backing module is unloaded */
43 struct lcd_properties *props; 60 struct lcd_ops *ops;
61 /* Serialise access to set_power method */
62 struct mutex update_lock;
44 /* The framebuffer notifier block */ 63 /* The framebuffer notifier block */
45 struct notifier_block fb_notif; 64 struct notifier_block fb_notif;
46 /* The class device structure */ 65 /* The class device structure */
47 struct class_device class_dev; 66 struct class_device class_dev;
48}; 67};
49 68
69static inline void lcd_set_power(struct lcd_device *ld, int power)
70{
71 mutex_lock(&ld->update_lock);
72 if (ld->ops && ld->ops->set_power)
73 ld->ops->set_power(ld, power);
74 mutex_unlock(&ld->update_lock);
75}
76
50extern struct lcd_device *lcd_device_register(const char *name, 77extern struct lcd_device *lcd_device_register(const char *name,
51 void *devdata, struct lcd_properties *lp); 78 void *devdata, struct lcd_ops *ops);
52extern void lcd_device_unregister(struct lcd_device *ld); 79extern void lcd_device_unregister(struct lcd_device *ld);
53 80
54#define to_lcd_device(obj) container_of(obj, struct lcd_device, class_dev) 81#define to_lcd_device(obj) container_of(obj, struct lcd_device, class_dev)
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 7c269f4992eb..447c52beb691 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -334,7 +334,7 @@
334 * separate range because of collisions with other tools such as 334 * separate range because of collisions with other tools such as
335 * 'mii-tool'. 335 * 'mii-tool'.
336 * We now have 32 commands, so a bit more space ;-). 336 * We now have 32 commands, so a bit more space ;-).
337 * Also, all 'odd' commands are only usable by root and don't return the 337 * Also, all 'even' commands are only usable by root and don't return the
338 * content of ifr/iwr to user (but you are not obliged to use the set/get 338 * content of ifr/iwr to user (but you are not obliged to use the set/get
339 * convention, just use every other two command). More details in iwpriv.c. 339 * convention, just use every other two command). More details in iwpriv.c.
340 * And I repeat : you are not forced to use them with iwpriv, but you 340 * And I repeat : you are not forced to use them with iwpriv, but you
@@ -348,7 +348,7 @@
348#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */ 348#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */
349#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) 349#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST)
350 350
351/* Even : get (world access), odd : set (root access) */ 351/* Odd : get (world access), even : set (root access) */
352#define IW_IS_SET(cmd) (!((cmd) & 0x1)) 352#define IW_IS_SET(cmd) (!((cmd) & 0x1))
353#define IW_IS_GET(cmd) ((cmd) & 0x1) 353#define IW_IS_GET(cmd) ((cmd) & 0x1)
354 354
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index 4f8c3ef70819..e9cdc6615ddc 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -265,17 +265,10 @@ void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac)
265 /* Change the default txrate to the highest possible value. 265 /* Change the default txrate to the highest possible value.
266 * The txrate machine will lower it, if it is too high. 266 * The txrate machine will lower it, if it is too high.
267 */ 267 */
268 /* FIXME: We don't correctly handle backing down to lower 268 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
269 rates, so 801.11g devices start off at 11M for now. People 269 txrates->user_rate = IEEE80211_OFDM_RATE_24MB;
270 can manually change it if they really need to, but 11M is 270 else
271 more reliable. Note similar logic in
272 ieee80211softmac_wx_set_rate() */
273 if (ieee->modulation & IEEE80211_CCK_MODULATION) {
274 txrates->user_rate = IEEE80211_CCK_RATE_11MB; 271 txrates->user_rate = IEEE80211_CCK_RATE_11MB;
275 } else if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
276 txrates->user_rate = IEEE80211_OFDM_RATE_54MB;
277 } else
278 assert(0);
279 272
280 txrates->default_rate = IEEE80211_CCK_RATE_1MB; 273 txrates->default_rate = IEEE80211_CCK_RATE_1MB;
281 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; 274 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index c306d52566e0..f13937bf9e8c 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -177,15 +177,10 @@ ieee80211softmac_wx_set_rate(struct net_device *net_dev,
177 int err = -EINVAL; 177 int err = -EINVAL;
178 178
179 if (in_rate == -1) { 179 if (in_rate == -1) {
180 /* FIXME: We don't correctly handle backing down to lower 180 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
181 rates, so 801.11g devices start off at 11M for now. People 181 in_rate = 24000000;
182 can manually change it if they really need to, but 11M is
183 more reliable. Note similar logic in
184 ieee80211softmac_wx_set_rate() */
185 if (ieee->modulation & IEEE80211_CCK_MODULATION)
186 in_rate = 11000000;
187 else 182 else
188 in_rate = 54000000; 183 in_rate = 11000000;
189 } 184 }
190 185
191 switch (in_rate) { 186 switch (in_rate) {