Commit f398778aa336a2919ee04ba45d915007230c6957

Authored by Len Brown

Merge branch 'video' into release

Conflicts:
	Documentation/kernel-parameters.txt

Signed-off-by: Len Brown <len.brown@intel.com>

Showing 16 changed files Inline Diff

Documentation/kernel-parameters.txt
1 Kernel Parameters 1 Kernel Parameters
2 ~~~~~~~~~~~~~~~~~ 2 ~~~~~~~~~~~~~~~~~
3 3
4 The following is a consolidated list of the kernel parameters as implemented 4 The following is a consolidated list of the kernel parameters as implemented
5 (mostly) by the __setup() macro and sorted into English Dictionary order 5 (mostly) by the __setup() macro and sorted into English Dictionary order
6 (defined as ignoring all punctuation and sorting digits before letters in a 6 (defined as ignoring all punctuation and sorting digits before letters in a
7 case insensitive manner), and with descriptions where known. 7 case insensitive manner), and with descriptions where known.
8 8
9 Module parameters for loadable modules are specified only as the 9 Module parameters for loadable modules are specified only as the
10 parameter name with optional '=' and value as appropriate, such as: 10 parameter name with optional '=' and value as appropriate, such as:
11 11
12 modprobe usbcore blinkenlights=1 12 modprobe usbcore blinkenlights=1
13 13
14 Module parameters for modules that are built into the kernel image 14 Module parameters for modules that are built into the kernel image
15 are specified on the kernel command line with the module name plus 15 are specified on the kernel command line with the module name plus
16 '.' plus parameter name, with '=' and value if appropriate, such as: 16 '.' plus parameter name, with '=' and value if appropriate, such as:
17 17
18 usbcore.blinkenlights=1 18 usbcore.blinkenlights=1
19 19
20 This document may not be entirely up to date and comprehensive. The command 20 This document may not be entirely up to date and comprehensive. The command
21 "modinfo -p ${modulename}" shows a current list of all parameters of a loadable 21 "modinfo -p ${modulename}" shows a current list of all parameters of a loadable
22 module. Loadable modules, after being loaded into the running kernel, also 22 module. Loadable modules, after being loaded into the running kernel, also
23 reveal their parameters in /sys/module/${modulename}/parameters/. Some of these 23 reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
24 parameters may be changed at runtime by the command 24 parameters may be changed at runtime by the command
25 "echo -n ${value} > /sys/module/${modulename}/parameters/${parm}". 25 "echo -n ${value} > /sys/module/${modulename}/parameters/${parm}".
26 26
27 The parameters listed below are only valid if certain kernel build options were 27 The parameters listed below are only valid if certain kernel build options were
28 enabled and if respective hardware is present. The text in square brackets at 28 enabled and if respective hardware is present. The text in square brackets at
29 the beginning of each description states the restrictions within which a 29 the beginning of each description states the restrictions within which a
30 parameter is applicable: 30 parameter is applicable:
31 31
32 ACPI ACPI support is enabled. 32 ACPI ACPI support is enabled.
33 AGP AGP (Accelerated Graphics Port) is enabled. 33 AGP AGP (Accelerated Graphics Port) is enabled.
34 ALSA ALSA sound support is enabled. 34 ALSA ALSA sound support is enabled.
35 APIC APIC support is enabled. 35 APIC APIC support is enabled.
36 APM Advanced Power Management support is enabled. 36 APM Advanced Power Management support is enabled.
37 AVR32 AVR32 architecture is enabled. 37 AVR32 AVR32 architecture is enabled.
38 AX25 Appropriate AX.25 support is enabled. 38 AX25 Appropriate AX.25 support is enabled.
39 BLACKFIN Blackfin architecture is enabled. 39 BLACKFIN Blackfin architecture is enabled.
40 DRM Direct Rendering Management support is enabled. 40 DRM Direct Rendering Management support is enabled.
41 EDD BIOS Enhanced Disk Drive Services (EDD) is enabled 41 EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
42 EFI EFI Partitioning (GPT) is enabled 42 EFI EFI Partitioning (GPT) is enabled
43 EIDE EIDE/ATAPI support is enabled. 43 EIDE EIDE/ATAPI support is enabled.
44 FB The frame buffer device is enabled. 44 FB The frame buffer device is enabled.
45 HW Appropriate hardware is enabled. 45 HW Appropriate hardware is enabled.
46 IA-64 IA-64 architecture is enabled. 46 IA-64 IA-64 architecture is enabled.
47 IOSCHED More than one I/O scheduler is enabled. 47 IOSCHED More than one I/O scheduler is enabled.
48 IP_PNP IP DHCP, BOOTP, or RARP is enabled. 48 IP_PNP IP DHCP, BOOTP, or RARP is enabled.
49 ISAPNP ISA PnP code is enabled. 49 ISAPNP ISA PnP code is enabled.
50 ISDN Appropriate ISDN support is enabled. 50 ISDN Appropriate ISDN support is enabled.
51 JOY Appropriate joystick support is enabled. 51 JOY Appropriate joystick support is enabled.
52 LIBATA Libata driver is enabled 52 LIBATA Libata driver is enabled
53 LP Printer support is enabled. 53 LP Printer support is enabled.
54 LOOP Loopback device support is enabled. 54 LOOP Loopback device support is enabled.
55 M68k M68k architecture is enabled. 55 M68k M68k architecture is enabled.
56 These options have more detailed description inside of 56 These options have more detailed description inside of
57 Documentation/m68k/kernel-options.txt. 57 Documentation/m68k/kernel-options.txt.
58 MCA MCA bus support is enabled. 58 MCA MCA bus support is enabled.
59 MDA MDA console support is enabled. 59 MDA MDA console support is enabled.
60 MOUSE Appropriate mouse support is enabled. 60 MOUSE Appropriate mouse support is enabled.
61 MSI Message Signaled Interrupts (PCI). 61 MSI Message Signaled Interrupts (PCI).
62 MTD MTD (Memory Technology Device) support is enabled. 62 MTD MTD (Memory Technology Device) support is enabled.
63 NET Appropriate network support is enabled. 63 NET Appropriate network support is enabled.
64 NUMA NUMA support is enabled. 64 NUMA NUMA support is enabled.
65 GENERIC_TIME The generic timeofday code is enabled. 65 GENERIC_TIME The generic timeofday code is enabled.
66 NFS Appropriate NFS support is enabled. 66 NFS Appropriate NFS support is enabled.
67 OSS OSS sound support is enabled. 67 OSS OSS sound support is enabled.
68 PV_OPS A paravirtualized kernel is enabled. 68 PV_OPS A paravirtualized kernel is enabled.
69 PARIDE The ParIDE (parallel port IDE) subsystem is enabled. 69 PARIDE The ParIDE (parallel port IDE) subsystem is enabled.
70 PARISC The PA-RISC architecture is enabled. 70 PARISC The PA-RISC architecture is enabled.
71 PCI PCI bus support is enabled. 71 PCI PCI bus support is enabled.
72 PCIE PCI Express support is enabled. 72 PCIE PCI Express support is enabled.
73 PCMCIA The PCMCIA subsystem is enabled. 73 PCMCIA The PCMCIA subsystem is enabled.
74 PNP Plug & Play support is enabled. 74 PNP Plug & Play support is enabled.
75 PPC PowerPC architecture is enabled. 75 PPC PowerPC architecture is enabled.
76 PPT Parallel port support is enabled. 76 PPT Parallel port support is enabled.
77 PS2 Appropriate PS/2 support is enabled. 77 PS2 Appropriate PS/2 support is enabled.
78 RAM RAM disk support is enabled. 78 RAM RAM disk support is enabled.
79 ROOTPLUG The example Root Plug LSM is enabled. 79 ROOTPLUG The example Root Plug LSM is enabled.
80 S390 S390 architecture is enabled. 80 S390 S390 architecture is enabled.
81 SCSI Appropriate SCSI support is enabled. 81 SCSI Appropriate SCSI support is enabled.
82 A lot of drivers has their options described inside of 82 A lot of drivers has their options described inside of
83 Documentation/scsi/. 83 Documentation/scsi/.
84 SECURITY Different security models are enabled. 84 SECURITY Different security models are enabled.
85 SELINUX SELinux support is enabled. 85 SELINUX SELinux support is enabled.
86 SERIAL Serial support is enabled. 86 SERIAL Serial support is enabled.
87 SH SuperH architecture is enabled. 87 SH SuperH architecture is enabled.
88 SMP The kernel is an SMP kernel. 88 SMP The kernel is an SMP kernel.
89 SPARC Sparc architecture is enabled. 89 SPARC Sparc architecture is enabled.
90 SWSUSP Software suspend (hibernation) is enabled. 90 SWSUSP Software suspend (hibernation) is enabled.
91 SUSPEND System suspend states are enabled. 91 SUSPEND System suspend states are enabled.
92 TS Appropriate touchscreen support is enabled. 92 TS Appropriate touchscreen support is enabled.
93 USB USB support is enabled. 93 USB USB support is enabled.
94 USBHID USB Human Interface Device support is enabled. 94 USBHID USB Human Interface Device support is enabled.
95 V4L Video For Linux support is enabled. 95 V4L Video For Linux support is enabled.
96 VGA The VGA console has been enabled. 96 VGA The VGA console has been enabled.
97 VT Virtual terminal support is enabled. 97 VT Virtual terminal support is enabled.
98 WDT Watchdog support is enabled. 98 WDT Watchdog support is enabled.
99 XT IBM PC/XT MFM hard disk support is enabled. 99 XT IBM PC/XT MFM hard disk support is enabled.
100 X86-32 X86-32, aka i386 architecture is enabled. 100 X86-32 X86-32, aka i386 architecture is enabled.
101 X86-64 X86-64 architecture is enabled. 101 X86-64 X86-64 architecture is enabled.
102 More X86-64 boot options can be found in 102 More X86-64 boot options can be found in
103 Documentation/x86/x86_64/boot-options.txt . 103 Documentation/x86/x86_64/boot-options.txt .
104 X86 Either 32bit or 64bit x86 (same as X86-32+X86-64) 104 X86 Either 32bit or 64bit x86 (same as X86-32+X86-64)
105 105
106 In addition, the following text indicates that the option: 106 In addition, the following text indicates that the option:
107 107
108 BUGS= Relates to possible processor bugs on the said processor. 108 BUGS= Relates to possible processor bugs on the said processor.
109 KNL Is a kernel start-up parameter. 109 KNL Is a kernel start-up parameter.
110 BOOT Is a boot loader parameter. 110 BOOT Is a boot loader parameter.
111 111
112 Parameters denoted with BOOT are actually interpreted by the boot 112 Parameters denoted with BOOT are actually interpreted by the boot
113 loader, and have no meaning to the kernel directly. 113 loader, and have no meaning to the kernel directly.
114 Do not modify the syntax of boot loader parameters without extreme 114 Do not modify the syntax of boot loader parameters without extreme
115 need or coordination with <Documentation/x86/i386/boot.txt>. 115 need or coordination with <Documentation/x86/i386/boot.txt>.
116 116
117 There are also arch-specific kernel-parameters not documented here. 117 There are also arch-specific kernel-parameters not documented here.
118 See for example <Documentation/x86/x86_64/boot-options.txt>. 118 See for example <Documentation/x86/x86_64/boot-options.txt>.
119 119
120 Note that ALL kernel parameters listed below are CASE SENSITIVE, and that 120 Note that ALL kernel parameters listed below are CASE SENSITIVE, and that
121 a trailing = on the name of any parameter states that that parameter will 121 a trailing = on the name of any parameter states that that parameter will
122 be entered as an environment variable, whereas its absence indicates that 122 be entered as an environment variable, whereas its absence indicates that
123 it will appear as a kernel argument readable via /proc/cmdline by programs 123 it will appear as a kernel argument readable via /proc/cmdline by programs
124 running once the system is up. 124 running once the system is up.
125 125
126 The number of kernel parameters is not limited, but the length of the 126 The number of kernel parameters is not limited, but the length of the
127 complete command line (parameters including spaces etc.) is limited to 127 complete command line (parameters including spaces etc.) is limited to
128 a fixed number of characters. This limit depends on the architecture 128 a fixed number of characters. This limit depends on the architecture
129 and is between 256 and 4096 characters. It is defined in the file 129 and is between 256 and 4096 characters. It is defined in the file
130 ./include/asm/setup.h as COMMAND_LINE_SIZE. 130 ./include/asm/setup.h as COMMAND_LINE_SIZE.
131 131
132 132
133 acpi= [HW,ACPI,X86-64,i386] 133 acpi= [HW,ACPI,X86-64,i386]
134 Advanced Configuration and Power Interface 134 Advanced Configuration and Power Interface
135 Format: { force | off | ht | strict | noirq } 135 Format: { force | off | ht | strict | noirq }
136 force -- enable ACPI if default was off 136 force -- enable ACPI if default was off
137 off -- disable ACPI if default was on 137 off -- disable ACPI if default was on
138 noirq -- do not use ACPI for IRQ routing 138 noirq -- do not use ACPI for IRQ routing
139 ht -- run only enough ACPI to enable Hyper Threading 139 ht -- run only enough ACPI to enable Hyper Threading
140 strict -- Be less tolerant of platforms that are not 140 strict -- Be less tolerant of platforms that are not
141 strictly ACPI specification compliant. 141 strictly ACPI specification compliant.
142 142
143 See also Documentation/power/pm.txt, pci=noacpi 143 See also Documentation/power/pm.txt, pci=noacpi
144 144
145 acpi_apic_instance= [ACPI, IOAPIC] 145 acpi_apic_instance= [ACPI, IOAPIC]
146 Format: <int> 146 Format: <int>
147 2: use 2nd APIC table, if available 147 2: use 2nd APIC table, if available
148 1,0: use 1st APIC table 148 1,0: use 1st APIC table
149 default: 0 149 default: 0
150 150
151 acpi_sleep= [HW,ACPI] Sleep options 151 acpi_sleep= [HW,ACPI] Sleep options
152 Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, old_ordering } 152 Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, old_ordering }
153 See Documentation/power/video.txt for s3_bios and s3_mode. 153 See Documentation/power/video.txt for s3_bios and s3_mode.
154 s3_beep is for debugging; it makes the PC's speaker beep 154 s3_beep is for debugging; it makes the PC's speaker beep
155 as soon as the kernel's real-mode entry point is called. 155 as soon as the kernel's real-mode entry point is called.
156 s4_nohwsig prevents ACPI hardware signature from being 156 s4_nohwsig prevents ACPI hardware signature from being
157 used during resume from hibernation. 157 used during resume from hibernation.
158 old_ordering causes the ACPI 1.0 ordering of the _PTS 158 old_ordering causes the ACPI 1.0 ordering of the _PTS
159 control method, wrt putting devices into low power 159 control method, wrt putting devices into low power
160 states, to be enforced (the ACPI 2.0 ordering of _PTS is 160 states, to be enforced (the ACPI 2.0 ordering of _PTS is
161 used by default). 161 used by default).
162 162
163 acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode 163 acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode
164 Format: { level | edge | high | low } 164 Format: { level | edge | high | low }
165 165
166 acpi_irq_balance [HW,ACPI] 166 acpi_irq_balance [HW,ACPI]
167 ACPI will balance active IRQs 167 ACPI will balance active IRQs
168 default in APIC mode 168 default in APIC mode
169 169
170 acpi_irq_nobalance [HW,ACPI] 170 acpi_irq_nobalance [HW,ACPI]
171 ACPI will not move active IRQs (default) 171 ACPI will not move active IRQs (default)
172 default in PIC mode 172 default in PIC mode
173 173
174 acpi_irq_pci= [HW,ACPI] If irq_balance, clear listed IRQs for 174 acpi_irq_pci= [HW,ACPI] If irq_balance, clear listed IRQs for
175 use by PCI 175 use by PCI
176 Format: <irq>,<irq>... 176 Format: <irq>,<irq>...
177 177
178 acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA 178 acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
179 Format: <irq>,<irq>... 179 Format: <irq>,<irq>...
180 180
181 acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT 181 acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
182 182
183 acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS 183 acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
184 Format: To spoof as Windows 98: ="Microsoft Windows" 184 Format: To spoof as Windows 98: ="Microsoft Windows"
185 185
186 acpi_osi= [HW,ACPI] Modify list of supported OS interface strings 186 acpi_osi= [HW,ACPI] Modify list of supported OS interface strings
187 acpi_osi="string1" # add string1 -- only one string 187 acpi_osi="string1" # add string1 -- only one string
188 acpi_osi="!string2" # remove built-in string2 188 acpi_osi="!string2" # remove built-in string2
189 acpi_osi= # disable all strings 189 acpi_osi= # disable all strings
190 190
191 acpi_serialize [HW,ACPI] force serialization of AML methods 191 acpi_serialize [HW,ACPI] force serialization of AML methods
192 192
193 acpi_skip_timer_override [HW,ACPI] 193 acpi_skip_timer_override [HW,ACPI]
194 Recognize and ignore IRQ0/pin2 Interrupt Override. 194 Recognize and ignore IRQ0/pin2 Interrupt Override.
195 For broken nForce2 BIOS resulting in XT-PIC timer. 195 For broken nForce2 BIOS resulting in XT-PIC timer.
196 acpi_use_timer_override [HW,ACPI} 196 acpi_use_timer_override [HW,ACPI}
197 Use timer override. For some broken Nvidia NF5 boards 197 Use timer override. For some broken Nvidia NF5 boards
198 that require a timer override, but don't have 198 that require a timer override, but don't have
199 HPET 199 HPET
200 200
201 acpi_backlight= [HW,ACPI]
202 acpi_backlight=vendor
203 acpi_backlight=video
204 If set to vendor, prefer vendor specific driver
205 (e.g. thinkpad_acpi, sony_acpi, etc.) instead
206 of the ACPI video.ko driver.
207
208 acpi_display_output= [HW,ACPI]
209 acpi_display_output=vendor
210 acpi_display_output=video
211 See above.
212
201 acpi.debug_layer= [HW,ACPI,ACPI_DEBUG] 213 acpi.debug_layer= [HW,ACPI,ACPI_DEBUG]
202 acpi.debug_level= [HW,ACPI,ACPI_DEBUG] 214 acpi.debug_level= [HW,ACPI,ACPI_DEBUG]
203 Format: <int> 215 Format: <int>
204 CONFIG_ACPI_DEBUG must be enabled to produce any ACPI 216 CONFIG_ACPI_DEBUG must be enabled to produce any ACPI
205 debug output. Bits in debug_layer correspond to a 217 debug output. Bits in debug_layer correspond to a
206 _COMPONENT in an ACPI source file, e.g., 218 _COMPONENT in an ACPI source file, e.g.,
207 #define _COMPONENT ACPI_PCI_COMPONENT 219 #define _COMPONENT ACPI_PCI_COMPONENT
208 Bits in debug_level correspond to a level in 220 Bits in debug_level correspond to a level in
209 ACPI_DEBUG_PRINT statements, e.g., 221 ACPI_DEBUG_PRINT statements, e.g.,
210 ACPI_DEBUG_PRINT((ACPI_DB_INFO, ... 222 ACPI_DEBUG_PRINT((ACPI_DB_INFO, ...
211 See Documentation/acpi/debug.txt for more information 223 See Documentation/acpi/debug.txt for more information
212 about debug layers and levels. 224 about debug layers and levels.
213 225
214 Enable AML "Debug" output, i.e., stores to the Debug 226 Enable AML "Debug" output, i.e., stores to the Debug
215 object while interpreting AML: 227 object while interpreting AML:
216 acpi.debug_layer=0xffffffff acpi.debug_level=0x2 228 acpi.debug_layer=0xffffffff acpi.debug_level=0x2
217 Enable PCI/PCI interrupt routing info messages: 229 Enable PCI/PCI interrupt routing info messages:
218 acpi.debug_layer=0x400000 acpi.debug_level=0x4 230 acpi.debug_layer=0x400000 acpi.debug_level=0x4
219 Enable all messages related to ACPI hardware: 231 Enable all messages related to ACPI hardware:
220 acpi.debug_layer=0x2 acpi.debug_level=0xffffffff 232 acpi.debug_layer=0x2 acpi.debug_level=0xffffffff
221 233
222 Some values produce so much output that the system is 234 Some values produce so much output that the system is
223 unusable. The "log_buf_len" parameter may be useful 235 unusable. The "log_buf_len" parameter may be useful
224 if you need to capture more output. 236 if you need to capture more output.
225 237
226 acpi.power_nocheck= [HW,ACPI] 238 acpi.power_nocheck= [HW,ACPI]
227 Format: 1/0 enable/disable the check of power state. 239 Format: 1/0 enable/disable the check of power state.
228 On some bogus BIOS the _PSC object/_STA object of 240 On some bogus BIOS the _PSC object/_STA object of
229 power resource can't return the correct device power 241 power resource can't return the correct device power
230 state. In such case it is unneccessary to check its 242 state. In such case it is unneccessary to check its
231 power state again in power transition. 243 power state again in power transition.
232 1 : disable the power state check 244 1 : disable the power state check
233 245
234 acpi_pm_good [X86-32,X86-64] 246 acpi_pm_good [X86-32,X86-64]
235 Override the pmtimer bug detection: force the kernel 247 Override the pmtimer bug detection: force the kernel
236 to assume that this machine's pmtimer latches its value 248 to assume that this machine's pmtimer latches its value
237 and always returns good values. 249 and always returns good values.
238 250
239 agp= [AGP] 251 agp= [AGP]
240 { off | try_unsupported } 252 { off | try_unsupported }
241 off: disable AGP support 253 off: disable AGP support
242 try_unsupported: try to drive unsupported chipsets 254 try_unsupported: try to drive unsupported chipsets
243 (may crash computer or cause data corruption) 255 (may crash computer or cause data corruption)
244 256
245 enable_timer_pin_1 [i386,x86-64] 257 enable_timer_pin_1 [i386,x86-64]
246 Enable PIN 1 of APIC timer 258 Enable PIN 1 of APIC timer
247 Can be useful to work around chipset bugs 259 Can be useful to work around chipset bugs
248 (in particular on some ATI chipsets). 260 (in particular on some ATI chipsets).
249 The kernel tries to set a reasonable default. 261 The kernel tries to set a reasonable default.
250 262
251 disable_timer_pin_1 [i386,x86-64] 263 disable_timer_pin_1 [i386,x86-64]
252 Disable PIN 1 of APIC timer 264 Disable PIN 1 of APIC timer
253 Can be useful to work around chipset bugs. 265 Can be useful to work around chipset bugs.
254 266
255 ad1848= [HW,OSS] 267 ad1848= [HW,OSS]
256 Format: <io>,<irq>,<dma>,<dma2>,<type> 268 Format: <io>,<irq>,<dma>,<dma2>,<type>
257 269
258 advansys= [HW,SCSI] 270 advansys= [HW,SCSI]
259 See header of drivers/scsi/advansys.c. 271 See header of drivers/scsi/advansys.c.
260 272
261 advwdt= [HW,WDT] Advantech WDT 273 advwdt= [HW,WDT] Advantech WDT
262 Format: <iostart>,<iostop> 274 Format: <iostart>,<iostop>
263 275
264 aedsp16= [HW,OSS] Audio Excel DSP 16 276 aedsp16= [HW,OSS] Audio Excel DSP 16
265 Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq> 277 Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
266 See also header of sound/oss/aedsp16.c. 278 See also header of sound/oss/aedsp16.c.
267 279
268 aha152x= [HW,SCSI] 280 aha152x= [HW,SCSI]
269 See Documentation/scsi/aha152x.txt. 281 See Documentation/scsi/aha152x.txt.
270 282
271 aha1542= [HW,SCSI] 283 aha1542= [HW,SCSI]
272 Format: <portbase>[,<buson>,<busoff>[,<dmaspeed>]] 284 Format: <portbase>[,<buson>,<busoff>[,<dmaspeed>]]
273 285
274 aic7xxx= [HW,SCSI] 286 aic7xxx= [HW,SCSI]
275 See Documentation/scsi/aic7xxx.txt. 287 See Documentation/scsi/aic7xxx.txt.
276 288
277 aic79xx= [HW,SCSI] 289 aic79xx= [HW,SCSI]
278 See Documentation/scsi/aic79xx.txt. 290 See Documentation/scsi/aic79xx.txt.
279 291
280 amd_iommu= [HW,X86-84] 292 amd_iommu= [HW,X86-84]
281 Pass parameters to the AMD IOMMU driver in the system. 293 Pass parameters to the AMD IOMMU driver in the system.
282 Possible values are: 294 Possible values are:
283 isolate - enable device isolation (each device, as far 295 isolate - enable device isolation (each device, as far
284 as possible, will get its own protection 296 as possible, will get its own protection
285 domain) 297 domain)
286 fullflush - enable flushing of IO/TLB entries when 298 fullflush - enable flushing of IO/TLB entries when
287 they are unmapped. Otherwise they are 299 they are unmapped. Otherwise they are
288 flushed before they will be reused, which 300 flushed before they will be reused, which
289 is a lot of faster 301 is a lot of faster
290 302
291 amd_iommu_size= [HW,X86-64] 303 amd_iommu_size= [HW,X86-64]
292 Define the size of the aperture for the AMD IOMMU 304 Define the size of the aperture for the AMD IOMMU
293 driver. Possible values are: 305 driver. Possible values are:
294 '32M', '64M' (default), '128M', '256M', '512M', '1G' 306 '32M', '64M' (default), '128M', '256M', '512M', '1G'
295 307
296 amijoy.map= [HW,JOY] Amiga joystick support 308 amijoy.map= [HW,JOY] Amiga joystick support
297 Map of devices attached to JOY0DAT and JOY1DAT 309 Map of devices attached to JOY0DAT and JOY1DAT
298 Format: <a>,<b> 310 Format: <a>,<b>
299 See also Documentation/kernel/input/joystick.txt 311 See also Documentation/kernel/input/joystick.txt
300 312
301 analog.map= [HW,JOY] Analog joystick and gamepad support 313 analog.map= [HW,JOY] Analog joystick and gamepad support
302 Specifies type or capabilities of an analog joystick 314 Specifies type or capabilities of an analog joystick
303 connected to one of 16 gameports 315 connected to one of 16 gameports
304 Format: <type1>,<type2>,..<type16> 316 Format: <type1>,<type2>,..<type16>
305 317
306 apc= [HW,SPARC] 318 apc= [HW,SPARC]
307 Power management functions (SPARCstation-4/5 + deriv.) 319 Power management functions (SPARCstation-4/5 + deriv.)
308 Format: noidle 320 Format: noidle
309 Disable APC CPU standby support. SPARCstation-Fox does 321 Disable APC CPU standby support. SPARCstation-Fox does
310 not play well with APC CPU idle - disable it if you have 322 not play well with APC CPU idle - disable it if you have
311 APC and your system crashes randomly. 323 APC and your system crashes randomly.
312 324
313 apic= [APIC,i386] Advanced Programmable Interrupt Controller 325 apic= [APIC,i386] Advanced Programmable Interrupt Controller
314 Change the output verbosity whilst booting 326 Change the output verbosity whilst booting
315 Format: { quiet (default) | verbose | debug } 327 Format: { quiet (default) | verbose | debug }
316 Change the amount of debugging information output 328 Change the amount of debugging information output
317 when initialising the APIC and IO-APIC components. 329 when initialising the APIC and IO-APIC components.
318 330
319 apm= [APM] Advanced Power Management 331 apm= [APM] Advanced Power Management
320 See header of arch/x86/kernel/apm_32.c. 332 See header of arch/x86/kernel/apm_32.c.
321 333
322 arcrimi= [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards 334 arcrimi= [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards
323 Format: <io>,<irq>,<nodeID> 335 Format: <io>,<irq>,<nodeID>
324 336
325 ataflop= [HW,M68k] 337 ataflop= [HW,M68k]
326 338
327 atarimouse= [HW,MOUSE] Atari Mouse 339 atarimouse= [HW,MOUSE] Atari Mouse
328 340
329 atascsi= [HW,SCSI] Atari SCSI 341 atascsi= [HW,SCSI] Atari SCSI
330 342
331 atkbd.extra= [HW] Enable extra LEDs and keys on IBM RapidAccess, 343 atkbd.extra= [HW] Enable extra LEDs and keys on IBM RapidAccess,
332 EzKey and similar keyboards 344 EzKey and similar keyboards
333 345
334 atkbd.reset= [HW] Reset keyboard during initialization 346 atkbd.reset= [HW] Reset keyboard during initialization
335 347
336 atkbd.set= [HW] Select keyboard code set 348 atkbd.set= [HW] Select keyboard code set
337 Format: <int> (2 = AT (default), 3 = PS/2) 349 Format: <int> (2 = AT (default), 3 = PS/2)
338 350
339 atkbd.scroll= [HW] Enable scroll wheel on MS Office and similar 351 atkbd.scroll= [HW] Enable scroll wheel on MS Office and similar
340 keyboards 352 keyboards
341 353
342 atkbd.softraw= [HW] Choose between synthetic and real raw mode 354 atkbd.softraw= [HW] Choose between synthetic and real raw mode
343 Format: <bool> (0 = real, 1 = synthetic (default)) 355 Format: <bool> (0 = real, 1 = synthetic (default))
344 356
345 atkbd.softrepeat= [HW] 357 atkbd.softrepeat= [HW]
346 Use software keyboard repeat 358 Use software keyboard repeat
347 359
348 autotest [IA64] 360 autotest [IA64]
349 361
350 baycom_epp= [HW,AX25] 362 baycom_epp= [HW,AX25]
351 Format: <io>,<mode> 363 Format: <io>,<mode>
352 364
353 baycom_par= [HW,AX25] BayCom Parallel Port AX.25 Modem 365 baycom_par= [HW,AX25] BayCom Parallel Port AX.25 Modem
354 Format: <io>,<mode> 366 Format: <io>,<mode>
355 See header of drivers/net/hamradio/baycom_par.c. 367 See header of drivers/net/hamradio/baycom_par.c.
356 368
357 baycom_ser_fdx= [HW,AX25] 369 baycom_ser_fdx= [HW,AX25]
358 BayCom Serial Port AX.25 Modem (Full Duplex Mode) 370 BayCom Serial Port AX.25 Modem (Full Duplex Mode)
359 Format: <io>,<irq>,<mode>[,<baud>] 371 Format: <io>,<irq>,<mode>[,<baud>]
360 See header of drivers/net/hamradio/baycom_ser_fdx.c. 372 See header of drivers/net/hamradio/baycom_ser_fdx.c.
361 373
362 baycom_ser_hdx= [HW,AX25] 374 baycom_ser_hdx= [HW,AX25]
363 BayCom Serial Port AX.25 Modem (Half Duplex Mode) 375 BayCom Serial Port AX.25 Modem (Half Duplex Mode)
364 Format: <io>,<irq>,<mode> 376 Format: <io>,<irq>,<mode>
365 See header of drivers/net/hamradio/baycom_ser_hdx.c. 377 See header of drivers/net/hamradio/baycom_ser_hdx.c.
366 378
367 boot_delay= Milliseconds to delay each printk during boot. 379 boot_delay= Milliseconds to delay each printk during boot.
368 Values larger than 10 seconds (10000) are changed to 380 Values larger than 10 seconds (10000) are changed to
369 no delay (0). 381 no delay (0).
370 Format: integer 382 Format: integer
371 383
372 bootmem_debug [KNL] Enable bootmem allocator debug messages. 384 bootmem_debug [KNL] Enable bootmem allocator debug messages.
373 385
374 bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards) 386 bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
375 bttv.radio= Most important insmod options are available as 387 bttv.radio= Most important insmod options are available as
376 kernel args too. 388 kernel args too.
377 bttv.pll= See Documentation/video4linux/bttv/Insmod-options 389 bttv.pll= See Documentation/video4linux/bttv/Insmod-options
378 bttv.tuner= and Documentation/video4linux/bttv/CARDLIST 390 bttv.tuner= and Documentation/video4linux/bttv/CARDLIST
379 391
380 BusLogic= [HW,SCSI] 392 BusLogic= [HW,SCSI]
381 See drivers/scsi/BusLogic.c, comment before function 393 See drivers/scsi/BusLogic.c, comment before function
382 BusLogic_ParseDriverOptions(). 394 BusLogic_ParseDriverOptions().
383 395
384 c101= [NET] Moxa C101 synchronous serial card 396 c101= [NET] Moxa C101 synchronous serial card
385 397
386 cachesize= [BUGS=X86-32] Override level 2 CPU cache size detection. 398 cachesize= [BUGS=X86-32] Override level 2 CPU cache size detection.
387 Sometimes CPU hardware bugs make them report the cache 399 Sometimes CPU hardware bugs make them report the cache
388 size incorrectly. The kernel will attempt work arounds 400 size incorrectly. The kernel will attempt work arounds
389 to fix known problems, but for some CPUs it is not 401 to fix known problems, but for some CPUs it is not
390 possible to determine what the correct size should be. 402 possible to determine what the correct size should be.
391 This option provides an override for these situations. 403 This option provides an override for these situations.
392 404
393 security= [SECURITY] Choose a security module to enable at boot. 405 security= [SECURITY] Choose a security module to enable at boot.
394 If this boot parameter is not specified, only the first 406 If this boot parameter is not specified, only the first
395 security module asking for security registration will be 407 security module asking for security registration will be
396 loaded. An invalid security module name will be treated 408 loaded. An invalid security module name will be treated
397 as if no module has been chosen. 409 as if no module has been chosen.
398 410
399 capability.disable= 411 capability.disable=
400 [SECURITY] Disable capabilities. This would normally 412 [SECURITY] Disable capabilities. This would normally
401 be used only if an alternative security model is to be 413 be used only if an alternative security model is to be
402 configured. Potentially dangerous and should only be 414 configured. Potentially dangerous and should only be
403 used if you are entirely sure of the consequences. 415 used if you are entirely sure of the consequences.
404 416
405 ccw_timeout_log [S390] 417 ccw_timeout_log [S390]
406 See Documentation/s390/CommonIO for details. 418 See Documentation/s390/CommonIO for details.
407 419
408 cgroup_disable= [KNL] Disable a particular controller 420 cgroup_disable= [KNL] Disable a particular controller
409 Format: {name of the controller(s) to disable} 421 Format: {name of the controller(s) to disable}
410 {Currently supported controllers - "memory"} 422 {Currently supported controllers - "memory"}
411 423
412 checkreqprot [SELINUX] Set initial checkreqprot flag value. 424 checkreqprot [SELINUX] Set initial checkreqprot flag value.
413 Format: { "0" | "1" } 425 Format: { "0" | "1" }
414 See security/selinux/Kconfig help text. 426 See security/selinux/Kconfig help text.
415 0 -- check protection applied by kernel (includes 427 0 -- check protection applied by kernel (includes
416 any implied execute protection). 428 any implied execute protection).
417 1 -- check protection requested by application. 429 1 -- check protection requested by application.
418 Default value is set via a kernel config option. 430 Default value is set via a kernel config option.
419 Value can be changed at runtime via 431 Value can be changed at runtime via
420 /selinux/checkreqprot. 432 /selinux/checkreqprot.
421 433
422 cio_ignore= [S390] 434 cio_ignore= [S390]
423 See Documentation/s390/CommonIO for details. 435 See Documentation/s390/CommonIO for details.
424 436
425 clock= [BUGS=X86-32, HW] gettimeofday clocksource override. 437 clock= [BUGS=X86-32, HW] gettimeofday clocksource override.
426 [Deprecated] 438 [Deprecated]
427 Forces specified clocksource (if available) to be used 439 Forces specified clocksource (if available) to be used
428 when calculating gettimeofday(). If specified 440 when calculating gettimeofday(). If specified
429 clocksource is not available, it defaults to PIT. 441 clocksource is not available, it defaults to PIT.
430 Format: { pit | tsc | cyclone | pmtmr } 442 Format: { pit | tsc | cyclone | pmtmr }
431 443
432 clocksource= [GENERIC_TIME] Override the default clocksource 444 clocksource= [GENERIC_TIME] Override the default clocksource
433 Format: <string> 445 Format: <string>
434 Override the default clocksource and use the clocksource 446 Override the default clocksource and use the clocksource
435 with the name specified. 447 with the name specified.
436 Some clocksource names to choose from, depending on 448 Some clocksource names to choose from, depending on
437 the platform: 449 the platform:
438 [all] jiffies (this is the base, fallback clocksource) 450 [all] jiffies (this is the base, fallback clocksource)
439 [ACPI] acpi_pm 451 [ACPI] acpi_pm
440 [ARM] imx_timer1,OSTS,netx_timer,mpu_timer2, 452 [ARM] imx_timer1,OSTS,netx_timer,mpu_timer2,
441 pxa_timer,timer3,32k_counter,timer0_1 453 pxa_timer,timer3,32k_counter,timer0_1
442 [AVR32] avr32 454 [AVR32] avr32
443 [X86-32] pit,hpet,tsc,vmi-timer; 455 [X86-32] pit,hpet,tsc,vmi-timer;
444 scx200_hrt on Geode; cyclone on IBM x440 456 scx200_hrt on Geode; cyclone on IBM x440
445 [MIPS] MIPS 457 [MIPS] MIPS
446 [PARISC] cr16 458 [PARISC] cr16
447 [S390] tod 459 [S390] tod
448 [SH] SuperH 460 [SH] SuperH
449 [SPARC64] tick 461 [SPARC64] tick
450 [X86-64] hpet,tsc 462 [X86-64] hpet,tsc
451 463
452 clearcpuid=BITNUM [X86] 464 clearcpuid=BITNUM [X86]
453 Disable CPUID feature X for the kernel. See 465 Disable CPUID feature X for the kernel. See
454 include/asm-x86/cpufeature.h for the valid bit numbers. 466 include/asm-x86/cpufeature.h for the valid bit numbers.
455 Note the Linux specific bits are not necessarily 467 Note the Linux specific bits are not necessarily
456 stable over kernel options, but the vendor specific 468 stable over kernel options, but the vendor specific
457 ones should be. 469 ones should be.
458 Also note that user programs calling CPUID directly 470 Also note that user programs calling CPUID directly
459 or using the feature without checking anything 471 or using the feature without checking anything
460 will still see it. This just prevents it from 472 will still see it. This just prevents it from
461 being used by the kernel or shown in /proc/cpuinfo. 473 being used by the kernel or shown in /proc/cpuinfo.
462 Also note the kernel might malfunction if you disable 474 Also note the kernel might malfunction if you disable
463 some critical bits. 475 some critical bits.
464 476
465 code_bytes [IA32/X86_64] How many bytes of object code to print 477 code_bytes [IA32/X86_64] How many bytes of object code to print
466 in an oops report. 478 in an oops report.
467 Range: 0 - 8192 479 Range: 0 - 8192
468 Default: 64 480 Default: 64
469 481
470 hpet= [X86-32,HPET] option to control HPET usage 482 hpet= [X86-32,HPET] option to control HPET usage
471 Format: { enable (default) | disable | force } 483 Format: { enable (default) | disable | force }
472 disable: disable HPET and use PIT instead 484 disable: disable HPET and use PIT instead
473 force: allow force enabled of undocumented chips (ICH4, 485 force: allow force enabled of undocumented chips (ICH4,
474 VIA, nVidia) 486 VIA, nVidia)
475 487
476 com20020= [HW,NET] ARCnet - COM20020 chipset 488 com20020= [HW,NET] ARCnet - COM20020 chipset
477 Format: 489 Format:
478 <io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]] 490 <io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]]
479 491
480 com90io= [HW,NET] ARCnet - COM90xx chipset (IO-mapped buffers) 492 com90io= [HW,NET] ARCnet - COM90xx chipset (IO-mapped buffers)
481 Format: <io>[,<irq>] 493 Format: <io>[,<irq>]
482 494
483 com90xx= [HW,NET] 495 com90xx= [HW,NET]
484 ARCnet - COM90xx chipset (memory-mapped buffers) 496 ARCnet - COM90xx chipset (memory-mapped buffers)
485 Format: <io>[,<irq>[,<memstart>]] 497 Format: <io>[,<irq>[,<memstart>]]
486 498
487 condev= [HW,S390] console device 499 condev= [HW,S390] console device
488 conmode= 500 conmode=
489 501
490 console= [KNL] Output console device and options. 502 console= [KNL] Output console device and options.
491 503
492 tty<n> Use the virtual console device <n>. 504 tty<n> Use the virtual console device <n>.
493 505
494 ttyS<n>[,options] 506 ttyS<n>[,options]
495 ttyUSB0[,options] 507 ttyUSB0[,options]
496 Use the specified serial port. The options are of 508 Use the specified serial port. The options are of
497 the form "bbbbpnf", where "bbbb" is the baud rate, 509 the form "bbbbpnf", where "bbbb" is the baud rate,
498 "p" is parity ("n", "o", or "e"), "n" is number of 510 "p" is parity ("n", "o", or "e"), "n" is number of
499 bits, and "f" is flow control ("r" for RTS or 511 bits, and "f" is flow control ("r" for RTS or
500 omit it). Default is "9600n8". 512 omit it). Default is "9600n8".
501 513
502 See Documentation/serial-console.txt for more 514 See Documentation/serial-console.txt for more
503 information. See 515 information. See
504 Documentation/networking/netconsole.txt for an 516 Documentation/networking/netconsole.txt for an
505 alternative. 517 alternative.
506 518
507 uart[8250],io,<addr>[,options] 519 uart[8250],io,<addr>[,options]
508 uart[8250],mmio,<addr>[,options] 520 uart[8250],mmio,<addr>[,options]
509 Start an early, polled-mode console on the 8250/16550 521 Start an early, polled-mode console on the 8250/16550
510 UART at the specified I/O port or MMIO address, 522 UART at the specified I/O port or MMIO address,
511 switching to the matching ttyS device later. The 523 switching to the matching ttyS device later. The
512 options are the same as for ttyS, above. 524 options are the same as for ttyS, above.
513 525
514 If the device connected to the port is not a TTY but a braille 526 If the device connected to the port is not a TTY but a braille
515 device, prepend "brl," before the device type, for instance 527 device, prepend "brl," before the device type, for instance
516 console=brl,ttyS0 528 console=brl,ttyS0
517 For now, only VisioBraille is supported. 529 For now, only VisioBraille is supported.
518 530
519 earlycon= [KNL] Output early console device and options. 531 earlycon= [KNL] Output early console device and options.
520 uart[8250],io,<addr>[,options] 532 uart[8250],io,<addr>[,options]
521 uart[8250],mmio,<addr>[,options] 533 uart[8250],mmio,<addr>[,options]
522 Start an early, polled-mode console on the 8250/16550 534 Start an early, polled-mode console on the 8250/16550
523 UART at the specified I/O port or MMIO address. 535 UART at the specified I/O port or MMIO address.
524 The options are the same as for ttyS, above. 536 The options are the same as for ttyS, above.
525 537
526 no_console_suspend 538 no_console_suspend
527 [HW] Never suspend the console 539 [HW] Never suspend the console
528 Disable suspending of consoles during suspend and 540 Disable suspending of consoles during suspend and
529 hibernate operations. Once disabled, debugging 541 hibernate operations. Once disabled, debugging
530 messages can reach various consoles while the rest 542 messages can reach various consoles while the rest
531 of the system is being put to sleep (ie, while 543 of the system is being put to sleep (ie, while
532 debugging driver suspend/resume hooks). This may 544 debugging driver suspend/resume hooks). This may
533 not work reliably with all consoles, but is known 545 not work reliably with all consoles, but is known
534 to work with serial and VGA consoles. 546 to work with serial and VGA consoles.
535 547
536 cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver 548 cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver
537 Format: 549 Format:
538 <first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>] 550 <first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
539 551
540 crashkernel=nn[KMG]@ss[KMG] 552 crashkernel=nn[KMG]@ss[KMG]
541 [KNL] Reserve a chunk of physical memory to 553 [KNL] Reserve a chunk of physical memory to
542 hold a kernel to switch to with kexec on panic. 554 hold a kernel to switch to with kexec on panic.
543 555
544 crashkernel=range1:size1[,range2:size2,...][@offset] 556 crashkernel=range1:size1[,range2:size2,...][@offset]
545 [KNL] Same as above, but depends on the memory 557 [KNL] Same as above, but depends on the memory
546 in the running system. The syntax of range is 558 in the running system. The syntax of range is
547 start-[end] where start and end are both 559 start-[end] where start and end are both
548 a memory unit (amount[KMG]). See also 560 a memory unit (amount[KMG]). See also
549 Documentation/kdump/kdump.txt for a example. 561 Documentation/kdump/kdump.txt for a example.
550 562
551 cs4232= [HW,OSS] 563 cs4232= [HW,OSS]
552 Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq> 564 Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>
553 565
554 cs89x0_dma= [HW,NET] 566 cs89x0_dma= [HW,NET]
555 Format: <dma> 567 Format: <dma>
556 568
557 cs89x0_media= [HW,NET] 569 cs89x0_media= [HW,NET]
558 Format: { rj45 | aui | bnc } 570 Format: { rj45 | aui | bnc }
559 571
560 dasd= [HW,NET] 572 dasd= [HW,NET]
561 See header of drivers/s390/block/dasd_devmap.c. 573 See header of drivers/s390/block/dasd_devmap.c.
562 574
563 db9.dev[2|3]= [HW,JOY] Multisystem joystick support via parallel port 575 db9.dev[2|3]= [HW,JOY] Multisystem joystick support via parallel port
564 (one device per port) 576 (one device per port)
565 Format: <port#>,<type> 577 Format: <port#>,<type>
566 See also Documentation/input/joystick-parport.txt 578 See also Documentation/input/joystick-parport.txt
567 579
568 debug [KNL] Enable kernel debugging (events log level). 580 debug [KNL] Enable kernel debugging (events log level).
569 581
570 debug_locks_verbose= 582 debug_locks_verbose=
571 [KNL] verbose self-tests 583 [KNL] verbose self-tests
572 Format=<0|1> 584 Format=<0|1>
573 Print debugging info while doing the locking API 585 Print debugging info while doing the locking API
574 self-tests. 586 self-tests.
575 We default to 0 (no extra messages), setting it to 587 We default to 0 (no extra messages), setting it to
576 1 will print _a lot_ more information - normally 588 1 will print _a lot_ more information - normally
577 only useful to kernel developers. 589 only useful to kernel developers.
578 590
579 debug_objects [KNL] Enable object debugging 591 debug_objects [KNL] Enable object debugging
580 592
581 debugpat [X86] Enable PAT debugging 593 debugpat [X86] Enable PAT debugging
582 594
583 decnet.addr= [HW,NET] 595 decnet.addr= [HW,NET]
584 Format: <area>[,<node>] 596 Format: <area>[,<node>]
585 See also Documentation/networking/decnet.txt. 597 See also Documentation/networking/decnet.txt.
586 598
587 vt.default_blu= [VT] 599 vt.default_blu= [VT]
588 Format: <blue0>,<blue1>,<blue2>,...,<blue15> 600 Format: <blue0>,<blue1>,<blue2>,...,<blue15>
589 Change the default blue palette of the console. 601 Change the default blue palette of the console.
590 This is a 16-member array composed of values 602 This is a 16-member array composed of values
591 ranging from 0-255. 603 ranging from 0-255.
592 604
593 vt.default_grn= [VT] 605 vt.default_grn= [VT]
594 Format: <green0>,<green1>,<green2>,...,<green15> 606 Format: <green0>,<green1>,<green2>,...,<green15>
595 Change the default green palette of the console. 607 Change the default green palette of the console.
596 This is a 16-member array composed of values 608 This is a 16-member array composed of values
597 ranging from 0-255. 609 ranging from 0-255.
598 610
599 vt.default_red= [VT] 611 vt.default_red= [VT]
600 Format: <red0>,<red1>,<red2>,...,<red15> 612 Format: <red0>,<red1>,<red2>,...,<red15>
601 Change the default red palette of the console. 613 Change the default red palette of the console.
602 This is a 16-member array composed of values 614 This is a 16-member array composed of values
603 ranging from 0-255. 615 ranging from 0-255.
604 616
605 vt.default_utf8= 617 vt.default_utf8=
606 [VT] 618 [VT]
607 Format=<0|1> 619 Format=<0|1>
608 Set system-wide default UTF-8 mode for all tty's. 620 Set system-wide default UTF-8 mode for all tty's.
609 Default is 1, i.e. UTF-8 mode is enabled for all 621 Default is 1, i.e. UTF-8 mode is enabled for all
610 newly opened terminals. 622 newly opened terminals.
611 623
612 dhash_entries= [KNL] 624 dhash_entries= [KNL]
613 Set number of hash buckets for dentry cache. 625 Set number of hash buckets for dentry cache.
614 626
615 digi= [HW,SERIAL] 627 digi= [HW,SERIAL]
616 IO parameters + enable/disable command. 628 IO parameters + enable/disable command.
617 629
618 digiepca= [HW,SERIAL] 630 digiepca= [HW,SERIAL]
619 See drivers/char/README.epca and 631 See drivers/char/README.epca and
620 Documentation/digiepca.txt. 632 Documentation/digiepca.txt.
621 633
622 disable_mtrr_cleanup [X86] 634 disable_mtrr_cleanup [X86]
623 enable_mtrr_cleanup [X86] 635 enable_mtrr_cleanup [X86]
624 The kernel tries to adjust MTRR layout from continuous 636 The kernel tries to adjust MTRR layout from continuous
625 to discrete, to make X server driver able to add WB 637 to discrete, to make X server driver able to add WB
626 entry later. This parameter enables/disables that. 638 entry later. This parameter enables/disables that.
627 639
628 mtrr_chunk_size=nn[KMG] [X86] 640 mtrr_chunk_size=nn[KMG] [X86]
629 used for mtrr cleanup. It is largest continous chunk 641 used for mtrr cleanup. It is largest continous chunk
630 that could hold holes aka. UC entries. 642 that could hold holes aka. UC entries.
631 643
632 mtrr_gran_size=nn[KMG] [X86] 644 mtrr_gran_size=nn[KMG] [X86]
633 Used for mtrr cleanup. It is granularity of mtrr block. 645 Used for mtrr cleanup. It is granularity of mtrr block.
634 Default is 1. 646 Default is 1.
635 Large value could prevent small alignment from 647 Large value could prevent small alignment from
636 using up MTRRs. 648 using up MTRRs.
637 649
638 mtrr_spare_reg_nr=n [X86] 650 mtrr_spare_reg_nr=n [X86]
639 Format: <integer> 651 Format: <integer>
640 Range: 0,7 : spare reg number 652 Range: 0,7 : spare reg number
641 Default : 1 653 Default : 1
642 Used for mtrr cleanup. It is spare mtrr entries number. 654 Used for mtrr cleanup. It is spare mtrr entries number.
643 Set to 2 or more if your graphical card needs more. 655 Set to 2 or more if your graphical card needs more.
644 656
645 disable_mtrr_trim [X86, Intel and AMD only] 657 disable_mtrr_trim [X86, Intel and AMD only]
646 By default the kernel will trim any uncacheable 658 By default the kernel will trim any uncacheable
647 memory out of your available memory pool based on 659 memory out of your available memory pool based on
648 MTRR settings. This parameter disables that behavior, 660 MTRR settings. This parameter disables that behavior,
649 possibly causing your machine to run very slowly. 661 possibly causing your machine to run very slowly.
650 662
651 dmasound= [HW,OSS] Sound subsystem buffers 663 dmasound= [HW,OSS] Sound subsystem buffers
652 664
653 dscc4.setup= [NET] 665 dscc4.setup= [NET]
654 666
655 dtc3181e= [HW,SCSI] 667 dtc3181e= [HW,SCSI]
656 668
657 earlyprintk= [X86-32,X86-64,SH,BLACKFIN] 669 earlyprintk= [X86-32,X86-64,SH,BLACKFIN]
658 earlyprintk=vga 670 earlyprintk=vga
659 earlyprintk=serial[,ttySn[,baudrate]] 671 earlyprintk=serial[,ttySn[,baudrate]]
660 earlyprintk=dbgp 672 earlyprintk=dbgp
661 673
662 Append ",keep" to not disable it when the real console 674 Append ",keep" to not disable it when the real console
663 takes over. 675 takes over.
664 676
665 Only vga or serial or usb debug port at a time. 677 Only vga or serial or usb debug port at a time.
666 678
667 Currently only ttyS0 and ttyS1 are supported. 679 Currently only ttyS0 and ttyS1 are supported.
668 680
669 Interaction with the standard serial driver is not 681 Interaction with the standard serial driver is not
670 very good. 682 very good.
671 683
672 The VGA output is eventually overwritten by the real 684 The VGA output is eventually overwritten by the real
673 console. 685 console.
674 686
675 eata= [HW,SCSI] 687 eata= [HW,SCSI]
676 688
677 edd= [EDD] 689 edd= [EDD]
678 Format: {"off" | "on" | "skip[mbr]"} 690 Format: {"off" | "on" | "skip[mbr]"}
679 691
680 eisa_irq_edge= [PARISC,HW] 692 eisa_irq_edge= [PARISC,HW]
681 See header of drivers/parisc/eisa.c. 693 See header of drivers/parisc/eisa.c.
682 694
683 elanfreq= [X86-32] 695 elanfreq= [X86-32]
684 See comment before function elanfreq_setup() in 696 See comment before function elanfreq_setup() in
685 arch/x86/kernel/cpu/cpufreq/elanfreq.c. 697 arch/x86/kernel/cpu/cpufreq/elanfreq.c.
686 698
687 elevator= [IOSCHED] 699 elevator= [IOSCHED]
688 Format: {"anticipatory" | "cfq" | "deadline" | "noop"} 700 Format: {"anticipatory" | "cfq" | "deadline" | "noop"}
689 See Documentation/block/as-iosched.txt and 701 See Documentation/block/as-iosched.txt and
690 Documentation/block/deadline-iosched.txt for details. 702 Documentation/block/deadline-iosched.txt for details.
691 703
692 elfcorehdr= [IA64,PPC,SH,X86-32,X86_64] 704 elfcorehdr= [IA64,PPC,SH,X86-32,X86_64]
693 Specifies physical address of start of kernel core 705 Specifies physical address of start of kernel core
694 image elf header. Generally kexec loader will 706 image elf header. Generally kexec loader will
695 pass this option to capture kernel. 707 pass this option to capture kernel.
696 See Documentation/kdump/kdump.txt for details. 708 See Documentation/kdump/kdump.txt for details.
697 709
698 enforcing [SELINUX] Set initial enforcing status. 710 enforcing [SELINUX] Set initial enforcing status.
699 Format: {"0" | "1"} 711 Format: {"0" | "1"}
700 See security/selinux/Kconfig help text. 712 See security/selinux/Kconfig help text.
701 0 -- permissive (log only, no denials). 713 0 -- permissive (log only, no denials).
702 1 -- enforcing (deny and log). 714 1 -- enforcing (deny and log).
703 Default value is 0. 715 Default value is 0.
704 Value can be changed at runtime via /selinux/enforce. 716 Value can be changed at runtime via /selinux/enforce.
705 717
706 es1371= [HW,OSS] 718 es1371= [HW,OSS]
707 Format: <spdif>,[<nomix>,[<amplifier>]] 719 Format: <spdif>,[<nomix>,[<amplifier>]]
708 See also header of sound/oss/es1371.c. 720 See also header of sound/oss/es1371.c.
709 721
710 ether= [HW,NET] Ethernet cards parameters 722 ether= [HW,NET] Ethernet cards parameters
711 This option is obsoleted by the "netdev=" option, which 723 This option is obsoleted by the "netdev=" option, which
712 has equivalent usage. See its documentation for details. 724 has equivalent usage. See its documentation for details.
713 725
714 eurwdt= [HW,WDT] Eurotech CPU-1220/1410 onboard watchdog. 726 eurwdt= [HW,WDT] Eurotech CPU-1220/1410 onboard watchdog.
715 Format: <io>[,<irq>] 727 Format: <io>[,<irq>]
716 728
717 failslab= 729 failslab=
718 fail_page_alloc= 730 fail_page_alloc=
719 fail_make_request=[KNL] 731 fail_make_request=[KNL]
720 General fault injection mechanism. 732 General fault injection mechanism.
721 Format: <interval>,<probability>,<space>,<times> 733 Format: <interval>,<probability>,<space>,<times>
722 See also /Documentation/fault-injection/. 734 See also /Documentation/fault-injection/.
723 735
724 fd_mcs= [HW,SCSI] 736 fd_mcs= [HW,SCSI]
725 See header of drivers/scsi/fd_mcs.c. 737 See header of drivers/scsi/fd_mcs.c.
726 738
727 fdomain= [HW,SCSI] 739 fdomain= [HW,SCSI]
728 See header of drivers/scsi/fdomain.c. 740 See header of drivers/scsi/fdomain.c.
729 741
730 floppy= [HW] 742 floppy= [HW]
731 See Documentation/floppy.txt. 743 See Documentation/floppy.txt.
732 744
733 force_pal_cache_flush 745 force_pal_cache_flush
734 [IA-64] Avoid check_sal_cache_flush which may hang on 746 [IA-64] Avoid check_sal_cache_flush which may hang on
735 buggy SAL_CACHE_FLUSH implementations. Using this 747 buggy SAL_CACHE_FLUSH implementations. Using this
736 parameter will force ia64_sal_cache_flush to call 748 parameter will force ia64_sal_cache_flush to call
737 ia64_pal_cache_flush instead of SAL_CACHE_FLUSH. 749 ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.
738 750
739 gamecon.map[2|3]= 751 gamecon.map[2|3]=
740 [HW,JOY] Multisystem joystick and NES/SNES/PSX pad 752 [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
741 support via parallel port (up to 5 devices per port) 753 support via parallel port (up to 5 devices per port)
742 Format: <port#>,<pad1>,<pad2>,<pad3>,<pad4>,<pad5> 754 Format: <port#>,<pad1>,<pad2>,<pad3>,<pad4>,<pad5>
743 See also Documentation/input/joystick-parport.txt 755 See also Documentation/input/joystick-parport.txt
744 756
745 gamma= [HW,DRM] 757 gamma= [HW,DRM]
746 758
747 gart_fix_e820= [X86_64] disable the fix e820 for K8 GART 759 gart_fix_e820= [X86_64] disable the fix e820 for K8 GART
748 Format: off | on 760 Format: off | on
749 default: on 761 default: on
750 762
751 gdth= [HW,SCSI] 763 gdth= [HW,SCSI]
752 See header of drivers/scsi/gdth.c. 764 See header of drivers/scsi/gdth.c.
753 765
754 gpt [EFI] Forces disk with valid GPT signature but 766 gpt [EFI] Forces disk with valid GPT signature but
755 invalid Protective MBR to be treated as GPT. 767 invalid Protective MBR to be treated as GPT.
756 768
757 gvp11= [HW,SCSI] 769 gvp11= [HW,SCSI]
758 770
759 hashdist= [KNL,NUMA] Large hashes allocated during boot 771 hashdist= [KNL,NUMA] Large hashes allocated during boot
760 are distributed across NUMA nodes. Defaults on 772 are distributed across NUMA nodes. Defaults on
761 for IA-64, off otherwise. 773 for IA-64, off otherwise.
762 Format: 0 | 1 (for off | on) 774 Format: 0 | 1 (for off | on)
763 775
764 hcl= [IA-64] SGI's Hardware Graph compatibility layer 776 hcl= [IA-64] SGI's Hardware Graph compatibility layer
765 777
766 hd= [EIDE] (E)IDE hard drive subsystem geometry 778 hd= [EIDE] (E)IDE hard drive subsystem geometry
767 Format: <cyl>,<head>,<sect> 779 Format: <cyl>,<head>,<sect>
768 780
769 highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact 781 highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact
770 size of <nn>. This works even on boxes that have no 782 size of <nn>. This works even on boxes that have no
771 highmem otherwise. This also works to reduce highmem 783 highmem otherwise. This also works to reduce highmem
772 size on bigger boxes. 784 size on bigger boxes.
773 785
774 highres= [KNL] Enable/disable high resolution timer mode. 786 highres= [KNL] Enable/disable high resolution timer mode.
775 Valid parameters: "on", "off" 787 Valid parameters: "on", "off"
776 Default: "on" 788 Default: "on"
777 789
778 hisax= [HW,ISDN] 790 hisax= [HW,ISDN]
779 See Documentation/isdn/README.HiSax. 791 See Documentation/isdn/README.HiSax.
780 792
781 hugepages= [HW,X86-32,IA-64] HugeTLB pages to allocate at boot. 793 hugepages= [HW,X86-32,IA-64] HugeTLB pages to allocate at boot.
782 hugepagesz= [HW,IA-64,PPC,X86-64] The size of the HugeTLB pages. 794 hugepagesz= [HW,IA-64,PPC,X86-64] The size of the HugeTLB pages.
783 On x86-64 and powerpc, this option can be specified 795 On x86-64 and powerpc, this option can be specified
784 multiple times interleaved with hugepages= to reserve 796 multiple times interleaved with hugepages= to reserve
785 huge pages of different sizes. Valid pages sizes on 797 huge pages of different sizes. Valid pages sizes on
786 x86-64 are 2M (when the CPU supports "pse") and 1G 798 x86-64 are 2M (when the CPU supports "pse") and 1G
787 (when the CPU supports the "pdpe1gb" cpuinfo flag) 799 (when the CPU supports the "pdpe1gb" cpuinfo flag)
788 Note that 1GB pages can only be allocated at boot time 800 Note that 1GB pages can only be allocated at boot time
789 using hugepages= and not freed afterwards. 801 using hugepages= and not freed afterwards.
790 default_hugepagesz= 802 default_hugepagesz=
791 [same as hugepagesz=] The size of the default 803 [same as hugepagesz=] The size of the default
792 HugeTLB page size. This is the size represented by 804 HugeTLB page size. This is the size represented by
793 the legacy /proc/ hugepages APIs, used for SHM, and 805 the legacy /proc/ hugepages APIs, used for SHM, and
794 default size when mounting hugetlbfs filesystems. 806 default size when mounting hugetlbfs filesystems.
795 Defaults to the default architecture's huge page size 807 Defaults to the default architecture's huge page size
796 if not specified. 808 if not specified.
797 809
798 hlt [BUGS=ARM,SH] 810 hlt [BUGS=ARM,SH]
799 811
800 i8042.debug [HW] Toggle i8042 debug mode 812 i8042.debug [HW] Toggle i8042 debug mode
801 i8042.direct [HW] Put keyboard port into non-translated mode 813 i8042.direct [HW] Put keyboard port into non-translated mode
802 i8042.dumbkbd [HW] Pretend that controller can only read data from 814 i8042.dumbkbd [HW] Pretend that controller can only read data from
803 keyboard and cannot control its state 815 keyboard and cannot control its state
804 (Don't attempt to blink the leds) 816 (Don't attempt to blink the leds)
805 i8042.noaux [HW] Don't check for auxiliary (== mouse) port 817 i8042.noaux [HW] Don't check for auxiliary (== mouse) port
806 i8042.nokbd [HW] Don't check/create keyboard port 818 i8042.nokbd [HW] Don't check/create keyboard port
807 i8042.noloop [HW] Disable the AUX Loopback command while probing 819 i8042.noloop [HW] Disable the AUX Loopback command while probing
808 for the AUX port 820 for the AUX port
809 i8042.nomux [HW] Don't check presence of an active multiplexing 821 i8042.nomux [HW] Don't check presence of an active multiplexing
810 controller 822 controller
811 i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX 823 i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
812 controllers 824 controllers
813 i8042.panicblink= 825 i8042.panicblink=
814 [HW] Frequency with which keyboard LEDs should blink 826 [HW] Frequency with which keyboard LEDs should blink
815 when kernel panics (default is 0.5 sec) 827 when kernel panics (default is 0.5 sec)
816 i8042.reset [HW] Reset the controller during init and cleanup 828 i8042.reset [HW] Reset the controller during init and cleanup
817 i8042.unlock [HW] Unlock (ignore) the keylock 829 i8042.unlock [HW] Unlock (ignore) the keylock
818 830
819 i810= [HW,DRM] 831 i810= [HW,DRM]
820 832
821 i8k.ignore_dmi [HW] Continue probing hardware even if DMI data 833 i8k.ignore_dmi [HW] Continue probing hardware even if DMI data
822 indicates that the driver is running on unsupported 834 indicates that the driver is running on unsupported
823 hardware. 835 hardware.
824 i8k.force [HW] Activate i8k driver even if SMM BIOS signature 836 i8k.force [HW] Activate i8k driver even if SMM BIOS signature
825 does not match list of supported models. 837 does not match list of supported models.
826 i8k.power_status 838 i8k.power_status
827 [HW] Report power status in /proc/i8k 839 [HW] Report power status in /proc/i8k
828 (disabled by default) 840 (disabled by default)
829 i8k.restricted [HW] Allow controlling fans only if SYS_ADMIN 841 i8k.restricted [HW] Allow controlling fans only if SYS_ADMIN
830 capability is set. 842 capability is set.
831 843
832 ibmmcascsi= [HW,MCA,SCSI] IBM MicroChannel SCSI adapter 844 ibmmcascsi= [HW,MCA,SCSI] IBM MicroChannel SCSI adapter
833 See Documentation/mca.txt. 845 See Documentation/mca.txt.
834 846
835 icn= [HW,ISDN] 847 icn= [HW,ISDN]
836 Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]] 848 Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]
837 849
838 ide= [HW] (E)IDE subsystem 850 ide= [HW] (E)IDE subsystem
839 Format: ide=nodma or ide=doubler 851 Format: ide=nodma or ide=doubler
840 See Documentation/ide/ide.txt. 852 See Documentation/ide/ide.txt.
841 853
842 idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed 854 idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
843 See Documentation/ide/ide.txt. 855 See Documentation/ide/ide.txt.
844 856
845 idle= [X86] 857 idle= [X86]
846 Format: idle=poll or idle=mwait, idle=halt, idle=nomwait 858 Format: idle=poll or idle=mwait, idle=halt, idle=nomwait
847 Poll forces a polling idle loop that can slightly improves the performance 859 Poll forces a polling idle loop that can slightly improves the performance
848 of waking up a idle CPU, but will use a lot of power and make the system 860 of waking up a idle CPU, but will use a lot of power and make the system
849 run hot. Not recommended. 861 run hot. Not recommended.
850 idle=mwait. On systems which support MONITOR/MWAIT but the kernel chose 862 idle=mwait. On systems which support MONITOR/MWAIT but the kernel chose
851 to not use it because it doesn't save as much power as a normal idle 863 to not use it because it doesn't save as much power as a normal idle
852 loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same 864 loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
853 as idle=poll. 865 as idle=poll.
854 idle=halt. Halt is forced to be used for CPU idle. 866 idle=halt. Halt is forced to be used for CPU idle.
855 In such case C2/C3 won't be used again. 867 In such case C2/C3 won't be used again.
856 idle=nomwait. Disable mwait for CPU C-states 868 idle=nomwait. Disable mwait for CPU C-states
857 869
858 ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem 870 ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
859 Claim all unknown PCI IDE storage controllers. 871 Claim all unknown PCI IDE storage controllers.
860 872
861 ignore_loglevel [KNL] 873 ignore_loglevel [KNL]
862 Ignore loglevel setting - this will print /all/ 874 Ignore loglevel setting - this will print /all/
863 kernel messages to the console. Useful for debugging. 875 kernel messages to the console. Useful for debugging.
864 876
865 ihash_entries= [KNL] 877 ihash_entries= [KNL]
866 Set number of hash buckets for inode cache. 878 Set number of hash buckets for inode cache.
867 879
868 in2000= [HW,SCSI] 880 in2000= [HW,SCSI]
869 See header of drivers/scsi/in2000.c. 881 See header of drivers/scsi/in2000.c.
870 882
871 init= [KNL] 883 init= [KNL]
872 Format: <full_path> 884 Format: <full_path>
873 Run specified binary instead of /sbin/init as init 885 Run specified binary instead of /sbin/init as init
874 process. 886 process.
875 887
876 initcall_debug [KNL] Trace initcalls as they are executed. Useful 888 initcall_debug [KNL] Trace initcalls as they are executed. Useful
877 for working out where the kernel is dying during 889 for working out where the kernel is dying during
878 startup. 890 startup.
879 891
880 initrd= [BOOT] Specify the location of the initial ramdisk 892 initrd= [BOOT] Specify the location of the initial ramdisk
881 893
882 inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver 894 inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver
883 Format: <irq> 895 Format: <irq>
884 896
885 inttest= [IA64] 897 inttest= [IA64]
886 898
887 iommu= [x86] 899 iommu= [x86]
888 off 900 off
889 force 901 force
890 noforce 902 noforce
891 biomerge 903 biomerge
892 panic 904 panic
893 nopanic 905 nopanic
894 merge 906 merge
895 nomerge 907 nomerge
896 forcesac 908 forcesac
897 soft 909 soft
898 910
899 911
900 intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option 912 intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option
901 off 913 off
902 Disable intel iommu driver. 914 Disable intel iommu driver.
903 igfx_off [Default Off] 915 igfx_off [Default Off]
904 By default, gfx is mapped as normal device. If a gfx 916 By default, gfx is mapped as normal device. If a gfx
905 device has a dedicated DMAR unit, the DMAR unit is 917 device has a dedicated DMAR unit, the DMAR unit is
906 bypassed by not enabling DMAR with this option. In 918 bypassed by not enabling DMAR with this option. In
907 this case, gfx device will use physical address for 919 this case, gfx device will use physical address for
908 DMA. 920 DMA.
909 forcedac [x86_64] 921 forcedac [x86_64]
910 With this option iommu will not optimize to look 922 With this option iommu will not optimize to look
911 for io virtual address below 32 bit forcing dual 923 for io virtual address below 32 bit forcing dual
912 address cycle on pci bus for cards supporting greater 924 address cycle on pci bus for cards supporting greater
913 than 32 bit addressing. The default is to look 925 than 32 bit addressing. The default is to look
914 for translation below 32 bit and if not available 926 for translation below 32 bit and if not available
915 then look in the higher range. 927 then look in the higher range.
916 strict [Default Off] 928 strict [Default Off]
917 With this option on every unmap_single operation will 929 With this option on every unmap_single operation will
918 result in a hardware IOTLB flush operation as opposed 930 result in a hardware IOTLB flush operation as opposed
919 to batching them for performance. 931 to batching them for performance.
920 932
921 io_delay= [X86-32,X86-64] I/O delay method 933 io_delay= [X86-32,X86-64] I/O delay method
922 0x80 934 0x80
923 Standard port 0x80 based delay 935 Standard port 0x80 based delay
924 0xed 936 0xed
925 Alternate port 0xed based delay (needed on some systems) 937 Alternate port 0xed based delay (needed on some systems)
926 udelay 938 udelay
927 Simple two microseconds delay 939 Simple two microseconds delay
928 none 940 none
929 No delay 941 No delay
930 942
931 io7= [HW] IO7 for Marvel based alpha systems 943 io7= [HW] IO7 for Marvel based alpha systems
932 See comment before marvel_specify_io7 in 944 See comment before marvel_specify_io7 in
933 arch/alpha/kernel/core_marvel.c. 945 arch/alpha/kernel/core_marvel.c.
934 946
935 ip= [IP_PNP] 947 ip= [IP_PNP]
936 See Documentation/filesystems/nfsroot.txt. 948 See Documentation/filesystems/nfsroot.txt.
937 949
938 ip2= [HW] Set IO/IRQ pairs for up to 4 IntelliPort boards 950 ip2= [HW] Set IO/IRQ pairs for up to 4 IntelliPort boards
939 See comment before ip2_setup() in 951 See comment before ip2_setup() in
940 drivers/char/ip2/ip2base.c. 952 drivers/char/ip2/ip2base.c.
941 953
942 ips= [HW,SCSI] Adaptec / IBM ServeRAID controller 954 ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
943 See header of drivers/scsi/ips.c. 955 See header of drivers/scsi/ips.c.
944 956
945 ports= [IP_VS_FTP] IPVS ftp helper module 957 ports= [IP_VS_FTP] IPVS ftp helper module
946 Default is 21. 958 Default is 21.
947 Up to 8 (IP_VS_APP_MAX_PORTS) ports 959 Up to 8 (IP_VS_APP_MAX_PORTS) ports
948 may be specified. 960 may be specified.
949 Format: <port>,<port>.... 961 Format: <port>,<port>....
950 962
951 irqfixup [HW] 963 irqfixup [HW]
952 When an interrupt is not handled search all handlers 964 When an interrupt is not handled search all handlers
953 for it. Intended to get systems with badly broken 965 for it. Intended to get systems with badly broken
954 firmware running. 966 firmware running.
955 967
956 irqpoll [HW] 968 irqpoll [HW]
957 When an interrupt is not handled search all handlers 969 When an interrupt is not handled search all handlers
958 for it. Also check all handlers each timer 970 for it. Also check all handlers each timer
959 interrupt. Intended to get systems with badly broken 971 interrupt. Intended to get systems with badly broken
960 firmware running. 972 firmware running.
961 973
962 isapnp= [ISAPNP] 974 isapnp= [ISAPNP]
963 Format: <RDP>,<reset>,<pci_scan>,<verbosity> 975 Format: <RDP>,<reset>,<pci_scan>,<verbosity>
964 976
965 isolcpus= [KNL,SMP] Isolate CPUs from the general scheduler. 977 isolcpus= [KNL,SMP] Isolate CPUs from the general scheduler.
966 Format: 978 Format:
967 <cpu number>,...,<cpu number> 979 <cpu number>,...,<cpu number>
968 or 980 or
969 <cpu number>-<cpu number> 981 <cpu number>-<cpu number>
970 (must be a positive range in ascending order) 982 (must be a positive range in ascending order)
971 or a mixture 983 or a mixture
972 <cpu number>,...,<cpu number>-<cpu number> 984 <cpu number>,...,<cpu number>-<cpu number>
973 985
974 This option can be used to specify one or more CPUs 986 This option can be used to specify one or more CPUs
975 to isolate from the general SMP balancing and scheduling 987 to isolate from the general SMP balancing and scheduling
976 algorithms. You can move a process onto or off an 988 algorithms. You can move a process onto or off an
977 "isolated" CPU via the CPU affinity syscalls or cpuset. 989 "isolated" CPU via the CPU affinity syscalls or cpuset.
978 <cpu number> begins at 0 and the maximum value is 990 <cpu number> begins at 0 and the maximum value is
979 "number of CPUs in system - 1". 991 "number of CPUs in system - 1".
980 992
981 This option is the preferred way to isolate CPUs. The 993 This option is the preferred way to isolate CPUs. The
982 alternative -- manually setting the CPU mask of all 994 alternative -- manually setting the CPU mask of all
983 tasks in the system -- can cause problems and 995 tasks in the system -- can cause problems and
984 suboptimal load balancer performance. 996 suboptimal load balancer performance.
985 997
986 iucv= [HW,NET] 998 iucv= [HW,NET]
987 999
988 js= [HW,JOY] Analog joystick 1000 js= [HW,JOY] Analog joystick
989 See Documentation/input/joystick.txt. 1001 See Documentation/input/joystick.txt.
990 1002
991 kernelcore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter 1003 kernelcore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter
992 specifies the amount of memory usable by the kernel 1004 specifies the amount of memory usable by the kernel
993 for non-movable allocations. The requested amount is 1005 for non-movable allocations. The requested amount is
994 spread evenly throughout all nodes in the system. The 1006 spread evenly throughout all nodes in the system. The
995 remaining memory in each node is used for Movable 1007 remaining memory in each node is used for Movable
996 pages. In the event, a node is too small to have both 1008 pages. In the event, a node is too small to have both
997 kernelcore and Movable pages, kernelcore pages will 1009 kernelcore and Movable pages, kernelcore pages will
998 take priority and other nodes will have a larger number 1010 take priority and other nodes will have a larger number
999 of kernelcore pages. The Movable zone is used for the 1011 of kernelcore pages. The Movable zone is used for the
1000 allocation of pages that may be reclaimed or moved 1012 allocation of pages that may be reclaimed or moved
1001 by the page migration subsystem. This means that 1013 by the page migration subsystem. This means that
1002 HugeTLB pages may not be allocated from this zone. 1014 HugeTLB pages may not be allocated from this zone.
1003 Note that allocations like PTEs-from-HighMem still 1015 Note that allocations like PTEs-from-HighMem still
1004 use the HighMem zone if it exists, and the Normal 1016 use the HighMem zone if it exists, and the Normal
1005 zone if it does not. 1017 zone if it does not.
1006 1018
1007 movablecore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter 1019 movablecore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter
1008 is similar to kernelcore except it specifies the 1020 is similar to kernelcore except it specifies the
1009 amount of memory used for migratable allocations. 1021 amount of memory used for migratable allocations.
1010 If both kernelcore and movablecore is specified, 1022 If both kernelcore and movablecore is specified,
1011 then kernelcore will be at *least* the specified 1023 then kernelcore will be at *least* the specified
1012 value but may be more. If movablecore on its own 1024 value but may be more. If movablecore on its own
1013 is specified, the administrator must be careful 1025 is specified, the administrator must be careful
1014 that the amount of memory usable for all allocations 1026 that the amount of memory usable for all allocations
1015 is not too small. 1027 is not too small.
1016 1028
1017 keepinitrd [HW,ARM] 1029 keepinitrd [HW,ARM]
1018 1030
1019 kstack=N [X86-32,X86-64] Print N words from the kernel stack 1031 kstack=N [X86-32,X86-64] Print N words from the kernel stack
1020 in oops dumps. 1032 in oops dumps.
1021 1033
1022 kgdboc= [HW] kgdb over consoles. 1034 kgdboc= [HW] kgdb over consoles.
1023 Requires a tty driver that supports console polling. 1035 Requires a tty driver that supports console polling.
1024 (only serial suported for now) 1036 (only serial suported for now)
1025 Format: <serial_device>[,baud] 1037 Format: <serial_device>[,baud]
1026 1038
1027 kmac= [MIPS] korina ethernet MAC address. 1039 kmac= [MIPS] korina ethernet MAC address.
1028 Configure the RouterBoard 532 series on-chip 1040 Configure the RouterBoard 532 series on-chip
1029 Ethernet adapter MAC address. 1041 Ethernet adapter MAC address.
1030 1042
1031 l2cr= [PPC] 1043 l2cr= [PPC]
1032 1044
1033 l3cr= [PPC] 1045 l3cr= [PPC]
1034 1046
1035 lapic [X86-32,APIC] Enable the local APIC even if BIOS 1047 lapic [X86-32,APIC] Enable the local APIC even if BIOS
1036 disabled it. 1048 disabled it.
1037 1049
1038 lapic_timer_c2_ok [X86-32,x86-64,APIC] trust the local apic timer in 1050 lapic_timer_c2_ok [X86-32,x86-64,APIC] trust the local apic timer in
1039 C2 power state. 1051 C2 power state.
1040 1052
1041 libata.dma= [LIBATA] DMA control 1053 libata.dma= [LIBATA] DMA control
1042 libata.dma=0 Disable all PATA and SATA DMA 1054 libata.dma=0 Disable all PATA and SATA DMA
1043 libata.dma=1 PATA and SATA Disk DMA only 1055 libata.dma=1 PATA and SATA Disk DMA only
1044 libata.dma=2 ATAPI (CDROM) DMA only 1056 libata.dma=2 ATAPI (CDROM) DMA only
1045 libata.dma=4 Compact Flash DMA only 1057 libata.dma=4 Compact Flash DMA only
1046 Combinations also work, so libata.dma=3 enables DMA 1058 Combinations also work, so libata.dma=3 enables DMA
1047 for disks and CDROMs, but not CFs. 1059 for disks and CDROMs, but not CFs.
1048 1060
1049 libata.noacpi [LIBATA] Disables use of ACPI in libata suspend/resume 1061 libata.noacpi [LIBATA] Disables use of ACPI in libata suspend/resume
1050 when set. 1062 when set.
1051 Format: <int> 1063 Format: <int>
1052 1064
1053 libata.force= [LIBATA] Force configurations. The format is comma 1065 libata.force= [LIBATA] Force configurations. The format is comma
1054 separated list of "[ID:]VAL" where ID is 1066 separated list of "[ID:]VAL" where ID is
1055 PORT[:DEVICE]. PORT and DEVICE are decimal numbers 1067 PORT[:DEVICE]. PORT and DEVICE are decimal numbers
1056 matching port, link or device. Basically, it matches 1068 matching port, link or device. Basically, it matches
1057 the ATA ID string printed on console by libata. If 1069 the ATA ID string printed on console by libata. If
1058 the whole ID part is omitted, the last PORT and DEVICE 1070 the whole ID part is omitted, the last PORT and DEVICE
1059 values are used. If ID hasn't been specified yet, the 1071 values are used. If ID hasn't been specified yet, the
1060 configuration applies to all ports, links and devices. 1072 configuration applies to all ports, links and devices.
1061 1073
1062 If only DEVICE is omitted, the parameter applies to 1074 If only DEVICE is omitted, the parameter applies to
1063 the port and all links and devices behind it. DEVICE 1075 the port and all links and devices behind it. DEVICE
1064 number of 0 either selects the first device or the 1076 number of 0 either selects the first device or the
1065 first fan-out link behind PMP device. It does not 1077 first fan-out link behind PMP device. It does not
1066 select the host link. DEVICE number of 15 selects the 1078 select the host link. DEVICE number of 15 selects the
1067 host link and device attached to it. 1079 host link and device attached to it.
1068 1080
1069 The VAL specifies the configuration to force. As long 1081 The VAL specifies the configuration to force. As long
1070 as there's no ambiguity shortcut notation is allowed. 1082 as there's no ambiguity shortcut notation is allowed.
1071 For example, both 1.5 and 1.5G would work for 1.5Gbps. 1083 For example, both 1.5 and 1.5G would work for 1.5Gbps.
1072 The following configurations can be forced. 1084 The following configurations can be forced.
1073 1085
1074 * Cable type: 40c, 80c, short40c, unk, ign or sata. 1086 * Cable type: 40c, 80c, short40c, unk, ign or sata.
1075 Any ID with matching PORT is used. 1087 Any ID with matching PORT is used.
1076 1088
1077 * SATA link speed limit: 1.5Gbps or 3.0Gbps. 1089 * SATA link speed limit: 1.5Gbps or 3.0Gbps.
1078 1090
1079 * Transfer mode: pio[0-7], mwdma[0-4] and udma[0-7]. 1091 * Transfer mode: pio[0-7], mwdma[0-4] and udma[0-7].
1080 udma[/][16,25,33,44,66,100,133] notation is also 1092 udma[/][16,25,33,44,66,100,133] notation is also
1081 allowed. 1093 allowed.
1082 1094
1083 * [no]ncq: Turn on or off NCQ. 1095 * [no]ncq: Turn on or off NCQ.
1084 1096
1085 * nohrst, nosrst, norst: suppress hard, soft 1097 * nohrst, nosrst, norst: suppress hard, soft
1086 and both resets. 1098 and both resets.
1087 1099
1088 If there are multiple matching configurations changing 1100 If there are multiple matching configurations changing
1089 the same attribute, the last one is used. 1101 the same attribute, the last one is used.
1090 1102
1091 load_ramdisk= [RAM] List of ramdisks to load from floppy 1103 load_ramdisk= [RAM] List of ramdisks to load from floppy
1092 See Documentation/ramdisk.txt. 1104 See Documentation/ramdisk.txt.
1093 1105
1094 lockd.nlm_grace_period=P [NFS] Assign grace period. 1106 lockd.nlm_grace_period=P [NFS] Assign grace period.
1095 Format: <integer> 1107 Format: <integer>
1096 1108
1097 lockd.nlm_tcpport=N [NFS] Assign TCP port. 1109 lockd.nlm_tcpport=N [NFS] Assign TCP port.
1098 Format: <integer> 1110 Format: <integer>
1099 1111
1100 lockd.nlm_timeout=T [NFS] Assign timeout value. 1112 lockd.nlm_timeout=T [NFS] Assign timeout value.
1101 Format: <integer> 1113 Format: <integer>
1102 1114
1103 lockd.nlm_udpport=M [NFS] Assign UDP port. 1115 lockd.nlm_udpport=M [NFS] Assign UDP port.
1104 Format: <integer> 1116 Format: <integer>
1105 1117
1106 logibm.irq= [HW,MOUSE] Logitech Bus Mouse Driver 1118 logibm.irq= [HW,MOUSE] Logitech Bus Mouse Driver
1107 Format: <irq> 1119 Format: <irq>
1108 1120
1109 loglevel= All Kernel Messages with a loglevel smaller than the 1121 loglevel= All Kernel Messages with a loglevel smaller than the
1110 console loglevel will be printed to the console. It can 1122 console loglevel will be printed to the console. It can
1111 also be changed with klogd or other programs. The 1123 also be changed with klogd or other programs. The
1112 loglevels are defined as follows: 1124 loglevels are defined as follows:
1113 1125
1114 0 (KERN_EMERG) system is unusable 1126 0 (KERN_EMERG) system is unusable
1115 1 (KERN_ALERT) action must be taken immediately 1127 1 (KERN_ALERT) action must be taken immediately
1116 2 (KERN_CRIT) critical conditions 1128 2 (KERN_CRIT) critical conditions
1117 3 (KERN_ERR) error conditions 1129 3 (KERN_ERR) error conditions
1118 4 (KERN_WARNING) warning conditions 1130 4 (KERN_WARNING) warning conditions
1119 5 (KERN_NOTICE) normal but significant condition 1131 5 (KERN_NOTICE) normal but significant condition
1120 6 (KERN_INFO) informational 1132 6 (KERN_INFO) informational
1121 7 (KERN_DEBUG) debug-level messages 1133 7 (KERN_DEBUG) debug-level messages
1122 1134
1123 log_buf_len=n Sets the size of the printk ring buffer, in bytes. 1135 log_buf_len=n Sets the size of the printk ring buffer, in bytes.
1124 Format: { n | nk | nM } 1136 Format: { n | nk | nM }
1125 n must be a power of two. The default size 1137 n must be a power of two. The default size
1126 is set in the kernel config file. 1138 is set in the kernel config file.
1127 1139
1128 logo.nologo [FB] Disables display of the built-in Linux logo. 1140 logo.nologo [FB] Disables display of the built-in Linux logo.
1129 This may be used to provide more screen space for 1141 This may be used to provide more screen space for
1130 kernel log messages and is useful when debugging 1142 kernel log messages and is useful when debugging
1131 kernel boot problems. 1143 kernel boot problems.
1132 1144
1133 lp=0 [LP] Specify parallel ports to use, e.g, 1145 lp=0 [LP] Specify parallel ports to use, e.g,
1134 lp=port[,port...] lp=none,parport0 (lp0 not configured, lp1 uses 1146 lp=port[,port...] lp=none,parport0 (lp0 not configured, lp1 uses
1135 lp=reset first parallel port). 'lp=0' disables the 1147 lp=reset first parallel port). 'lp=0' disables the
1136 lp=auto printer driver. 'lp=reset' (which can be 1148 lp=auto printer driver. 'lp=reset' (which can be
1137 specified in addition to the ports) causes 1149 specified in addition to the ports) causes
1138 attached printers to be reset. Using 1150 attached printers to be reset. Using
1139 lp=port1,port2,... specifies the parallel ports 1151 lp=port1,port2,... specifies the parallel ports
1140 to associate lp devices with, starting with 1152 to associate lp devices with, starting with
1141 lp0. A port specification may be 'none' to skip 1153 lp0. A port specification may be 'none' to skip
1142 that lp device, or a parport name such as 1154 that lp device, or a parport name such as
1143 'parport0'. Specifying 'lp=auto' instead of a 1155 'parport0'. Specifying 'lp=auto' instead of a
1144 port specification list means that device IDs 1156 port specification list means that device IDs
1145 from each port should be examined, to see if 1157 from each port should be examined, to see if
1146 an IEEE 1284-compliant printer is attached; if 1158 an IEEE 1284-compliant printer is attached; if
1147 so, the driver will manage that printer. 1159 so, the driver will manage that printer.
1148 See also header of drivers/char/lp.c. 1160 See also header of drivers/char/lp.c.
1149 1161
1150 lpj=n [KNL] 1162 lpj=n [KNL]
1151 Sets loops_per_jiffy to given constant, thus avoiding 1163 Sets loops_per_jiffy to given constant, thus avoiding
1152 time-consuming boot-time autodetection (up to 250 ms per 1164 time-consuming boot-time autodetection (up to 250 ms per
1153 CPU). 0 enables autodetection (default). To determine 1165 CPU). 0 enables autodetection (default). To determine
1154 the correct value for your kernel, boot with normal 1166 the correct value for your kernel, boot with normal
1155 autodetection and see what value is printed. Note that 1167 autodetection and see what value is printed. Note that
1156 on SMP systems the preset will be applied to all CPUs, 1168 on SMP systems the preset will be applied to all CPUs,
1157 which is likely to cause problems if your CPUs need 1169 which is likely to cause problems if your CPUs need
1158 significantly divergent settings. An incorrect value 1170 significantly divergent settings. An incorrect value
1159 will cause delays in the kernel to be wrong, leading to 1171 will cause delays in the kernel to be wrong, leading to
1160 unpredictable I/O errors and other breakage. Although 1172 unpredictable I/O errors and other breakage. Although
1161 unlikely, in the extreme case this might damage your 1173 unlikely, in the extreme case this might damage your
1162 hardware. 1174 hardware.
1163 1175
1164 ltpc= [NET] 1176 ltpc= [NET]
1165 Format: <io>,<irq>,<dma> 1177 Format: <io>,<irq>,<dma>
1166 1178
1167 mac5380= [HW,SCSI] Format: 1179 mac5380= [HW,SCSI] Format:
1168 <can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags> 1180 <can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
1169 1181
1170 machvec= [IA64] Force the use of a particular machine-vector 1182 machvec= [IA64] Force the use of a particular machine-vector
1171 (machvec) in a generic kernel. 1183 (machvec) in a generic kernel.
1172 Example: machvec=hpzx1_swiotlb 1184 Example: machvec=hpzx1_swiotlb
1173 1185
1174 max_loop= [LOOP] Maximum number of loopback devices that can 1186 max_loop= [LOOP] Maximum number of loopback devices that can
1175 be mounted 1187 be mounted
1176 Format: <1-256> 1188 Format: <1-256>
1177 1189
1178 maxcpus= [SMP] Maximum number of processors that an SMP kernel 1190 maxcpus= [SMP] Maximum number of processors that an SMP kernel
1179 should make use of. maxcpus=n : n >= 0 limits the 1191 should make use of. maxcpus=n : n >= 0 limits the
1180 kernel to using 'n' processors. n=0 is a special case, 1192 kernel to using 'n' processors. n=0 is a special case,
1181 it is equivalent to "nosmp", which also disables 1193 it is equivalent to "nosmp", which also disables
1182 the IO APIC. 1194 the IO APIC.
1183 1195
1184 max_addr=[KMG] [KNL,BOOT,ia64] All physical memory greater than or 1196 max_addr=[KMG] [KNL,BOOT,ia64] All physical memory greater than or
1185 equal to this physical address is ignored. 1197 equal to this physical address is ignored.
1186 1198
1187 max_luns= [SCSI] Maximum number of LUNs to probe. 1199 max_luns= [SCSI] Maximum number of LUNs to probe.
1188 Should be between 1 and 2^32-1. 1200 Should be between 1 and 2^32-1.
1189 1201
1190 max_report_luns= 1202 max_report_luns=
1191 [SCSI] Maximum number of LUNs received. 1203 [SCSI] Maximum number of LUNs received.
1192 Should be between 1 and 16384. 1204 Should be between 1 and 16384.
1193 1205
1194 mcatest= [IA-64] 1206 mcatest= [IA-64]
1195 1207
1196 mce [X86-32] Machine Check Exception 1208 mce [X86-32] Machine Check Exception
1197 1209
1198 mce=option [X86-64] See Documentation/x86/x86_64/boot-options.txt 1210 mce=option [X86-64] See Documentation/x86/x86_64/boot-options.txt
1199 1211
1200 md= [HW] RAID subsystems devices and level 1212 md= [HW] RAID subsystems devices and level
1201 See Documentation/md.txt. 1213 See Documentation/md.txt.
1202 1214
1203 mdacon= [MDA] 1215 mdacon= [MDA]
1204 Format: <first>,<last> 1216 Format: <first>,<last>
1205 Specifies range of consoles to be captured by the MDA. 1217 Specifies range of consoles to be captured by the MDA.
1206 1218
1207 mem=nn[KMG] [KNL,BOOT] Force usage of a specific amount of memory 1219 mem=nn[KMG] [KNL,BOOT] Force usage of a specific amount of memory
1208 Amount of memory to be used when the kernel is not able 1220 Amount of memory to be used when the kernel is not able
1209 to see the whole system memory or for test. 1221 to see the whole system memory or for test.
1210 [X86-32] Use together with memmap= to avoid physical 1222 [X86-32] Use together with memmap= to avoid physical
1211 address space collisions. Without memmap= PCI devices 1223 address space collisions. Without memmap= PCI devices
1212 could be placed at addresses belonging to unused RAM. 1224 could be placed at addresses belonging to unused RAM.
1213 1225
1214 mem=nopentium [BUGS=X86-32] Disable usage of 4MB pages for kernel 1226 mem=nopentium [BUGS=X86-32] Disable usage of 4MB pages for kernel
1215 memory. 1227 memory.
1216 1228
1217 memchunk=nn[KMG] 1229 memchunk=nn[KMG]
1218 [KNL,SH] Allow user to override the default size for 1230 [KNL,SH] Allow user to override the default size for
1219 per-device physically contiguous DMA buffers. 1231 per-device physically contiguous DMA buffers.
1220 1232
1221 memmap=exactmap [KNL,X86-32,X86_64] Enable setting of an exact 1233 memmap=exactmap [KNL,X86-32,X86_64] Enable setting of an exact
1222 E820 memory map, as specified by the user. 1234 E820 memory map, as specified by the user.
1223 Such memmap=exactmap lines can be constructed based on 1235 Such memmap=exactmap lines can be constructed based on
1224 BIOS output or other requirements. See the memmap=nn@ss 1236 BIOS output or other requirements. See the memmap=nn@ss
1225 option description. 1237 option description.
1226 1238
1227 memmap=nn[KMG]@ss[KMG] 1239 memmap=nn[KMG]@ss[KMG]
1228 [KNL] Force usage of a specific region of memory 1240 [KNL] Force usage of a specific region of memory
1229 Region of memory to be used, from ss to ss+nn. 1241 Region of memory to be used, from ss to ss+nn.
1230 1242
1231 memmap=nn[KMG]#ss[KMG] 1243 memmap=nn[KMG]#ss[KMG]
1232 [KNL,ACPI] Mark specific memory as ACPI data. 1244 [KNL,ACPI] Mark specific memory as ACPI data.
1233 Region of memory to be used, from ss to ss+nn. 1245 Region of memory to be used, from ss to ss+nn.
1234 1246
1235 memmap=nn[KMG]$ss[KMG] 1247 memmap=nn[KMG]$ss[KMG]
1236 [KNL,ACPI] Mark specific memory as reserved. 1248 [KNL,ACPI] Mark specific memory as reserved.
1237 Region of memory to be used, from ss to ss+nn. 1249 Region of memory to be used, from ss to ss+nn.
1238 Example: Exclude memory from 0x18690000-0x1869ffff 1250 Example: Exclude memory from 0x18690000-0x1869ffff
1239 memmap=64K$0x18690000 1251 memmap=64K$0x18690000
1240 or 1252 or
1241 memmap=0x10000$0x18690000 1253 memmap=0x10000$0x18690000
1242 1254
1243 memory_corruption_check=0/1 [X86] 1255 memory_corruption_check=0/1 [X86]
1244 Some BIOSes seem to corrupt the first 64k of 1256 Some BIOSes seem to corrupt the first 64k of
1245 memory when doing things like suspend/resume. 1257 memory when doing things like suspend/resume.
1246 Setting this option will scan the memory 1258 Setting this option will scan the memory
1247 looking for corruption. Enabling this will 1259 looking for corruption. Enabling this will
1248 both detect corruption and prevent the kernel 1260 both detect corruption and prevent the kernel
1249 from using the memory being corrupted. 1261 from using the memory being corrupted.
1250 However, its intended as a diagnostic tool; if 1262 However, its intended as a diagnostic tool; if
1251 repeatable BIOS-originated corruption always 1263 repeatable BIOS-originated corruption always
1252 affects the same memory, you can use memmap= 1264 affects the same memory, you can use memmap=
1253 to prevent the kernel from using that memory. 1265 to prevent the kernel from using that memory.
1254 1266
1255 memory_corruption_check_size=size [X86] 1267 memory_corruption_check_size=size [X86]
1256 By default it checks for corruption in the low 1268 By default it checks for corruption in the low
1257 64k, making this memory unavailable for normal 1269 64k, making this memory unavailable for normal
1258 use. Use this parameter to scan for 1270 use. Use this parameter to scan for
1259 corruption in more or less memory. 1271 corruption in more or less memory.
1260 1272
1261 memory_corruption_check_period=seconds [X86] 1273 memory_corruption_check_period=seconds [X86]
1262 By default it checks for corruption every 60 1274 By default it checks for corruption every 60
1263 seconds. Use this parameter to check at some 1275 seconds. Use this parameter to check at some
1264 other rate. 0 disables periodic checking. 1276 other rate. 0 disables periodic checking.
1265 1277
1266 memtest= [KNL,X86] Enable memtest 1278 memtest= [KNL,X86] Enable memtest
1267 Format: <integer> 1279 Format: <integer>
1268 range: 0,4 : pattern number 1280 range: 0,4 : pattern number
1269 default : 0 <disable> 1281 default : 0 <disable>
1270 1282
1271 meye.*= [HW] Set MotionEye Camera parameters 1283 meye.*= [HW] Set MotionEye Camera parameters
1272 See Documentation/video4linux/meye.txt. 1284 See Documentation/video4linux/meye.txt.
1273 1285
1274 mfgpt_irq= [IA-32] Specify the IRQ to use for the 1286 mfgpt_irq= [IA-32] Specify the IRQ to use for the
1275 Multi-Function General Purpose Timers on AMD Geode 1287 Multi-Function General Purpose Timers on AMD Geode
1276 platforms. 1288 platforms.
1277 1289
1278 mfgptfix [X86-32] Fix MFGPT timers on AMD Geode platforms when 1290 mfgptfix [X86-32] Fix MFGPT timers on AMD Geode platforms when
1279 the BIOS has incorrectly applied a workaround. TinyBIOS 1291 the BIOS has incorrectly applied a workaround. TinyBIOS
1280 version 0.98 is known to be affected, 0.99 fixes the 1292 version 0.98 is known to be affected, 0.99 fixes the
1281 problem by letting the user disable the workaround. 1293 problem by letting the user disable the workaround.
1282 1294
1283 mga= [HW,DRM] 1295 mga= [HW,DRM]
1284 1296
1285 mminit_loglevel= 1297 mminit_loglevel=
1286 [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this 1298 [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
1287 parameter allows control of the logging verbosity for 1299 parameter allows control of the logging verbosity for
1288 the additional memory initialisation checks. A value 1300 the additional memory initialisation checks. A value
1289 of 0 disables mminit logging and a level of 4 will 1301 of 0 disables mminit logging and a level of 4 will
1290 log everything. Information is printed at KERN_DEBUG 1302 log everything. Information is printed at KERN_DEBUG
1291 so loglevel=8 may also need to be specified. 1303 so loglevel=8 may also need to be specified.
1292 1304
1293 mousedev.tap_time= 1305 mousedev.tap_time=
1294 [MOUSE] Maximum time between finger touching and 1306 [MOUSE] Maximum time between finger touching and
1295 leaving touchpad surface for touch to be considered 1307 leaving touchpad surface for touch to be considered
1296 a tap and be reported as a left button click (for 1308 a tap and be reported as a left button click (for
1297 touchpads working in absolute mode only). 1309 touchpads working in absolute mode only).
1298 Format: <msecs> 1310 Format: <msecs>
1299 mousedev.xres= [MOUSE] Horizontal screen resolution, used for devices 1311 mousedev.xres= [MOUSE] Horizontal screen resolution, used for devices
1300 reporting absolute coordinates, such as tablets 1312 reporting absolute coordinates, such as tablets
1301 mousedev.yres= [MOUSE] Vertical screen resolution, used for devices 1313 mousedev.yres= [MOUSE] Vertical screen resolution, used for devices
1302 reporting absolute coordinates, such as tablets 1314 reporting absolute coordinates, such as tablets
1303 1315
1304 mpu401= [HW,OSS] 1316 mpu401= [HW,OSS]
1305 Format: <io>,<irq> 1317 Format: <io>,<irq>
1306 1318
1307 MTD_Partition= [MTD] 1319 MTD_Partition= [MTD]
1308 Format: <name>,<region-number>,<size>,<offset> 1320 Format: <name>,<region-number>,<size>,<offset>
1309 1321
1310 MTD_Region= [MTD] Format: 1322 MTD_Region= [MTD] Format:
1311 <name>,<region-number>[,<base>,<size>,<buswidth>,<altbuswidth>] 1323 <name>,<region-number>[,<base>,<size>,<buswidth>,<altbuswidth>]
1312 1324
1313 mtdparts= [MTD] 1325 mtdparts= [MTD]
1314 See drivers/mtd/cmdlinepart.c. 1326 See drivers/mtd/cmdlinepart.c.
1315 1327
1316 mtdset= [ARM] 1328 mtdset= [ARM]
1317 ARM/S3C2412 JIVE boot control 1329 ARM/S3C2412 JIVE boot control
1318 1330
1319 See arch/arm/mach-s3c2412/mach-jive.c 1331 See arch/arm/mach-s3c2412/mach-jive.c
1320 1332
1321 mtouchusb.raw_coordinates= 1333 mtouchusb.raw_coordinates=
1322 [HW] Make the MicroTouch USB driver use raw coordinates 1334 [HW] Make the MicroTouch USB driver use raw coordinates
1323 ('y', default) or cooked coordinates ('n') 1335 ('y', default) or cooked coordinates ('n')
1324 1336
1325 n2= [NET] SDL Inc. RISCom/N2 synchronous serial card 1337 n2= [NET] SDL Inc. RISCom/N2 synchronous serial card
1326 1338
1327 NCR_D700= [HW,SCSI] 1339 NCR_D700= [HW,SCSI]
1328 See header of drivers/scsi/NCR_D700.c. 1340 See header of drivers/scsi/NCR_D700.c.
1329 1341
1330 ncr5380= [HW,SCSI] 1342 ncr5380= [HW,SCSI]
1331 1343
1332 ncr53c400= [HW,SCSI] 1344 ncr53c400= [HW,SCSI]
1333 1345
1334 ncr53c400a= [HW,SCSI] 1346 ncr53c400a= [HW,SCSI]
1335 1347
1336 ncr53c406a= [HW,SCSI] 1348 ncr53c406a= [HW,SCSI]
1337 1349
1338 ncr53c8xx= [HW,SCSI] 1350 ncr53c8xx= [HW,SCSI]
1339 1351
1340 netdev= [NET] Network devices parameters 1352 netdev= [NET] Network devices parameters
1341 Format: <irq>,<io>,<mem_start>,<mem_end>,<name> 1353 Format: <irq>,<io>,<mem_start>,<mem_end>,<name>
1342 Note that mem_start is often overloaded to mean 1354 Note that mem_start is often overloaded to mean
1343 something different and driver-specific. 1355 something different and driver-specific.
1344 This usage is only documented in each driver source 1356 This usage is only documented in each driver source
1345 file if at all. 1357 file if at all.
1346 1358
1347 nf_conntrack.acct= 1359 nf_conntrack.acct=
1348 [NETFILTER] Enable connection tracking flow accounting 1360 [NETFILTER] Enable connection tracking flow accounting
1349 0 to disable accounting 1361 0 to disable accounting
1350 1 to enable accounting 1362 1 to enable accounting
1351 Default value depends on CONFIG_NF_CT_ACCT that is 1363 Default value depends on CONFIG_NF_CT_ACCT that is
1352 going to be removed in 2.6.29. 1364 going to be removed in 2.6.29.
1353 1365
1354 nfsaddrs= [NFS] 1366 nfsaddrs= [NFS]
1355 See Documentation/filesystems/nfsroot.txt. 1367 See Documentation/filesystems/nfsroot.txt.
1356 1368
1357 nfsroot= [NFS] nfs root filesystem for disk-less boxes. 1369 nfsroot= [NFS] nfs root filesystem for disk-less boxes.
1358 See Documentation/filesystems/nfsroot.txt. 1370 See Documentation/filesystems/nfsroot.txt.
1359 1371
1360 nfs.callback_tcpport= 1372 nfs.callback_tcpport=
1361 [NFS] set the TCP port on which the NFSv4 callback 1373 [NFS] set the TCP port on which the NFSv4 callback
1362 channel should listen. 1374 channel should listen.
1363 1375
1364 nfs.idmap_cache_timeout= 1376 nfs.idmap_cache_timeout=
1365 [NFS] set the maximum lifetime for idmapper cache 1377 [NFS] set the maximum lifetime for idmapper cache
1366 entries. 1378 entries.
1367 1379
1368 nfs.enable_ino64= 1380 nfs.enable_ino64=
1369 [NFS] enable 64-bit inode numbers. 1381 [NFS] enable 64-bit inode numbers.
1370 If zero, the NFS client will fake up a 32-bit inode 1382 If zero, the NFS client will fake up a 32-bit inode
1371 number for the readdir() and stat() syscalls instead 1383 number for the readdir() and stat() syscalls instead
1372 of returning the full 64-bit number. 1384 of returning the full 64-bit number.
1373 The default is to return 64-bit inode numbers. 1385 The default is to return 64-bit inode numbers.
1374 1386
1375 nmi_debug= [KNL,AVR32] Specify one or more actions to take 1387 nmi_debug= [KNL,AVR32] Specify one or more actions to take
1376 when a NMI is triggered. 1388 when a NMI is triggered.
1377 Format: [state][,regs][,debounce][,die] 1389 Format: [state][,regs][,debounce][,die]
1378 1390
1379 nmi_watchdog= [KNL,BUGS=X86-32] Debugging features for SMP kernels 1391 nmi_watchdog= [KNL,BUGS=X86-32] Debugging features for SMP kernels
1380 1392
1381 no387 [BUGS=X86-32] Tells the kernel to use the 387 maths 1393 no387 [BUGS=X86-32] Tells the kernel to use the 387 maths
1382 emulation library even if a 387 maths coprocessor 1394 emulation library even if a 387 maths coprocessor
1383 is present. 1395 is present.
1384 1396
1385 noaliencache [MM, NUMA, SLAB] Disables the allocation of alien 1397 noaliencache [MM, NUMA, SLAB] Disables the allocation of alien
1386 caches in the slab allocator. Saves per-node memory, 1398 caches in the slab allocator. Saves per-node memory,
1387 but will impact performance. 1399 but will impact performance.
1388 1400
1389 noalign [KNL,ARM] 1401 noalign [KNL,ARM]
1390 1402
1391 noapic [SMP,APIC] Tells the kernel to not make use of any 1403 noapic [SMP,APIC] Tells the kernel to not make use of any
1392 IOAPICs that may be present in the system. 1404 IOAPICs that may be present in the system.
1393 1405
1394 nobats [PPC] Do not use BATs for mapping kernel lowmem 1406 nobats [PPC] Do not use BATs for mapping kernel lowmem
1395 on "Classic" PPC cores. 1407 on "Classic" PPC cores.
1396 1408
1397 nocache [ARM] 1409 nocache [ARM]
1398 1410
1399 nodelayacct [KNL] Disable per-task delay accounting 1411 nodelayacct [KNL] Disable per-task delay accounting
1400 1412
1401 nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects. 1413 nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
1402 1414
1403 nodsp [SH] Disable hardware DSP at boot time. 1415 nodsp [SH] Disable hardware DSP at boot time.
1404 1416
1405 noefi [X86-32,X86-64] Disable EFI runtime services support. 1417 noefi [X86-32,X86-64] Disable EFI runtime services support.
1406 1418
1407 noexec [IA-64] 1419 noexec [IA-64]
1408 1420
1409 noexec [X86-32,X86-64] 1421 noexec [X86-32,X86-64]
1410 On X86-32 available only on PAE configured kernels. 1422 On X86-32 available only on PAE configured kernels.
1411 noexec=on: enable non-executable mappings (default) 1423 noexec=on: enable non-executable mappings (default)
1412 noexec=off: disable non-executable mappings 1424 noexec=off: disable non-executable mappings
1413 1425
1414 noexec32 [X86-64] 1426 noexec32 [X86-64]
1415 This affects only 32-bit executables. 1427 This affects only 32-bit executables.
1416 noexec32=on: enable non-executable mappings (default) 1428 noexec32=on: enable non-executable mappings (default)
1417 read doesn't imply executable mappings 1429 read doesn't imply executable mappings
1418 noexec32=off: disable non-executable mappings 1430 noexec32=off: disable non-executable mappings
1419 read implies executable mappings 1431 read implies executable mappings
1420 1432
1421 nofpu [SH] Disable hardware FPU at boot time. 1433 nofpu [SH] Disable hardware FPU at boot time.
1422 1434
1423 nofxsr [BUGS=X86-32] Disables x86 floating point extended 1435 nofxsr [BUGS=X86-32] Disables x86 floating point extended
1424 register save and restore. The kernel will only save 1436 register save and restore. The kernel will only save
1425 legacy floating-point registers on task switch. 1437 legacy floating-point registers on task switch.
1426 1438
1427 noclflush [BUGS=X86] Don't use the CLFLUSH instruction 1439 noclflush [BUGS=X86] Don't use the CLFLUSH instruction
1428 1440
1429 nohlt [BUGS=ARM,SH] 1441 nohlt [BUGS=ARM,SH]
1430 1442
1431 no-hlt [BUGS=X86-32] Tells the kernel that the hlt 1443 no-hlt [BUGS=X86-32] Tells the kernel that the hlt
1432 instruction doesn't work correctly and not to 1444 instruction doesn't work correctly and not to
1433 use it. 1445 use it.
1434 1446
1435 nohalt [IA-64] Tells the kernel not to use the power saving 1447 nohalt [IA-64] Tells the kernel not to use the power saving
1436 function PAL_HALT_LIGHT when idle. This increases 1448 function PAL_HALT_LIGHT when idle. This increases
1437 power-consumption. On the positive side, it reduces 1449 power-consumption. On the positive side, it reduces
1438 interrupt wake-up latency, which may improve performance 1450 interrupt wake-up latency, which may improve performance
1439 in certain environments such as networked servers or 1451 in certain environments such as networked servers or
1440 real-time systems. 1452 real-time systems.
1441 1453
1442 nohz= [KNL] Boottime enable/disable dynamic ticks 1454 nohz= [KNL] Boottime enable/disable dynamic ticks
1443 Valid arguments: on, off 1455 Valid arguments: on, off
1444 Default: on 1456 Default: on
1445 1457
1446 noirqdebug [X86-32] Disables the code which attempts to detect and 1458 noirqdebug [X86-32] Disables the code which attempts to detect and
1447 disable unhandled interrupt sources. 1459 disable unhandled interrupt sources.
1448 1460
1449 no_timer_check [X86-32,X86_64,APIC] Disables the code which tests for 1461 no_timer_check [X86-32,X86_64,APIC] Disables the code which tests for
1450 broken timer IRQ sources. 1462 broken timer IRQ sources.
1451 1463
1452 noisapnp [ISAPNP] Disables ISA PnP code. 1464 noisapnp [ISAPNP] Disables ISA PnP code.
1453 1465
1454 noinitrd [RAM] Tells the kernel not to load any configured 1466 noinitrd [RAM] Tells the kernel not to load any configured
1455 initial RAM disk. 1467 initial RAM disk.
1456 1468
1457 nointroute [IA-64] 1469 nointroute [IA-64]
1458 1470
1459 nojitter [IA64] Disables jitter checking for ITC timers. 1471 nojitter [IA64] Disables jitter checking for ITC timers.
1460 1472
1461 nolapic [X86-32,APIC] Do not enable or use the local APIC. 1473 nolapic [X86-32,APIC] Do not enable or use the local APIC.
1462 1474
1463 nolapic_timer [X86-32,APIC] Do not use the local APIC timer. 1475 nolapic_timer [X86-32,APIC] Do not use the local APIC timer.
1464 1476
1465 nox2apic [X86-64,APIC] Do not enable x2APIC mode. 1477 nox2apic [X86-64,APIC] Do not enable x2APIC mode.
1466 1478
1467 x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of 1479 x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of
1468 default x2apic cluster mode on platforms 1480 default x2apic cluster mode on platforms
1469 supporting x2apic. 1481 supporting x2apic.
1470 1482
1471 noltlbs [PPC] Do not use large page/tlb entries for kernel 1483 noltlbs [PPC] Do not use large page/tlb entries for kernel
1472 lowmem mapping on PPC40x. 1484 lowmem mapping on PPC40x.
1473 1485
1474 nomca [IA-64] Disable machine check abort handling 1486 nomca [IA-64] Disable machine check abort handling
1475 1487
1476 nomce [X86-32] Machine Check Exception 1488 nomce [X86-32] Machine Check Exception
1477 1489
1478 nomfgpt [X86-32] Disable Multi-Function General Purpose 1490 nomfgpt [X86-32] Disable Multi-Function General Purpose
1479 Timer usage (for AMD Geode machines). 1491 Timer usage (for AMD Geode machines).
1480 1492
1481 noreplace-paravirt [X86-32,PV_OPS] Don't patch paravirt_ops 1493 noreplace-paravirt [X86-32,PV_OPS] Don't patch paravirt_ops
1482 1494
1483 noreplace-smp [X86-32,SMP] Don't replace SMP instructions 1495 noreplace-smp [X86-32,SMP] Don't replace SMP instructions
1484 with UP alternatives 1496 with UP alternatives
1485 1497
1486 noresidual [PPC] Don't use residual data on PReP machines. 1498 noresidual [PPC] Don't use residual data on PReP machines.
1487 1499
1488 noresume [SWSUSP] Disables resume and restores original swap 1500 noresume [SWSUSP] Disables resume and restores original swap
1489 space. 1501 space.
1490 1502
1491 no-scroll [VGA] Disables scrollback. 1503 no-scroll [VGA] Disables scrollback.
1492 This is required for the Braillex ib80-piezo Braille 1504 This is required for the Braillex ib80-piezo Braille
1493 reader made by F.H. Papenmeier (Germany). 1505 reader made by F.H. Papenmeier (Germany).
1494 1506
1495 nosbagart [IA-64] 1507 nosbagart [IA-64]
1496 1508
1497 nosep [BUGS=X86-32] Disables x86 SYSENTER/SYSEXIT support. 1509 nosep [BUGS=X86-32] Disables x86 SYSENTER/SYSEXIT support.
1498 1510
1499 nosmp [SMP] Tells an SMP kernel to act as a UP kernel, 1511 nosmp [SMP] Tells an SMP kernel to act as a UP kernel,
1500 and disable the IO APIC. legacy for "maxcpus=0". 1512 and disable the IO APIC. legacy for "maxcpus=0".
1501 1513
1502 nosoftlockup [KNL] Disable the soft-lockup detector. 1514 nosoftlockup [KNL] Disable the soft-lockup detector.
1503 1515
1504 nosync [HW,M68K] Disables sync negotiation for all devices. 1516 nosync [HW,M68K] Disables sync negotiation for all devices.
1505 1517
1506 notsc [BUGS=X86-32] Disable Time Stamp Counter 1518 notsc [BUGS=X86-32] Disable Time Stamp Counter
1507 1519
1508 nousb [USB] Disable the USB subsystem 1520 nousb [USB] Disable the USB subsystem
1509 1521
1510 nowb [ARM] 1522 nowb [ARM]
1511 1523
1512 nptcg= [IA64] Override max number of concurrent global TLB 1524 nptcg= [IA64] Override max number of concurrent global TLB
1513 purges which is reported from either PAL_VM_SUMMARY or 1525 purges which is reported from either PAL_VM_SUMMARY or
1514 SAL PALO. 1526 SAL PALO.
1515 1527
1516 numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA. 1528 numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA.
1517 one of ['zone', 'node', 'default'] can be specified 1529 one of ['zone', 'node', 'default'] can be specified
1518 This can be set from sysctl after boot. 1530 This can be set from sysctl after boot.
1519 See Documentation/sysctl/vm.txt for details. 1531 See Documentation/sysctl/vm.txt for details.
1520 1532
1521 nr_uarts= [SERIAL] maximum number of UARTs to be registered. 1533 nr_uarts= [SERIAL] maximum number of UARTs to be registered.
1522 1534
1523 olpc_ec_timeout= [OLPC] ms delay when issuing EC commands 1535 olpc_ec_timeout= [OLPC] ms delay when issuing EC commands
1524 Rather than timing out after 20 ms if an EC 1536 Rather than timing out after 20 ms if an EC
1525 command is not properly ACKed, override the length 1537 command is not properly ACKed, override the length
1526 of the timeout. We have interrupts disabled while 1538 of the timeout. We have interrupts disabled while
1527 waiting for the ACK, so if this is set too high 1539 waiting for the ACK, so if this is set too high
1528 interrupts *may* be lost! 1540 interrupts *may* be lost!
1529 1541
1530 opl3= [HW,OSS] 1542 opl3= [HW,OSS]
1531 Format: <io> 1543 Format: <io>
1532 1544
1533 oprofile.timer= [HW] 1545 oprofile.timer= [HW]
1534 Use timer interrupt instead of performance counters 1546 Use timer interrupt instead of performance counters
1535 1547
1536 osst= [HW,SCSI] SCSI Tape Driver 1548 osst= [HW,SCSI] SCSI Tape Driver
1537 Format: <buffer_size>,<write_threshold> 1549 Format: <buffer_size>,<write_threshold>
1538 See also Documentation/scsi/st.txt. 1550 See also Documentation/scsi/st.txt.
1539 1551
1540 panic= [KNL] Kernel behaviour on panic 1552 panic= [KNL] Kernel behaviour on panic
1541 Format: <timeout> 1553 Format: <timeout>
1542 1554
1543 parkbd.port= [HW] Parallel port number the keyboard adapter is 1555 parkbd.port= [HW] Parallel port number the keyboard adapter is
1544 connected to, default is 0. 1556 connected to, default is 0.
1545 Format: <parport#> 1557 Format: <parport#>
1546 parkbd.mode= [HW] Parallel port keyboard adapter mode of operation, 1558 parkbd.mode= [HW] Parallel port keyboard adapter mode of operation,
1547 0 for XT, 1 for AT (default is AT). 1559 0 for XT, 1 for AT (default is AT).
1548 Format: <mode> 1560 Format: <mode>
1549 1561
1550 parport= [HW,PPT] Specify parallel ports. 0 disables. 1562 parport= [HW,PPT] Specify parallel ports. 0 disables.
1551 Format: { 0 | auto | 0xBBB[,IRQ[,DMA]] } 1563 Format: { 0 | auto | 0xBBB[,IRQ[,DMA]] }
1552 Use 'auto' to force the driver to use any 1564 Use 'auto' to force the driver to use any
1553 IRQ/DMA settings detected (the default is to 1565 IRQ/DMA settings detected (the default is to
1554 ignore detected IRQ/DMA settings because of 1566 ignore detected IRQ/DMA settings because of
1555 possible conflicts). You can specify the base 1567 possible conflicts). You can specify the base
1556 address, IRQ, and DMA settings; IRQ and DMA 1568 address, IRQ, and DMA settings; IRQ and DMA
1557 should be numbers, or 'auto' (for using detected 1569 should be numbers, or 'auto' (for using detected
1558 settings on that particular port), or 'nofifo' 1570 settings on that particular port), or 'nofifo'
1559 (to avoid using a FIFO even if it is detected). 1571 (to avoid using a FIFO even if it is detected).
1560 Parallel ports are assigned in the order they 1572 Parallel ports are assigned in the order they
1561 are specified on the command line, starting 1573 are specified on the command line, starting
1562 with parport0. 1574 with parport0.
1563 1575
1564 parport_init_mode= [HW,PPT] 1576 parport_init_mode= [HW,PPT]
1565 Configure VIA parallel port to operate in 1577 Configure VIA parallel port to operate in
1566 a specific mode. This is necessary on Pegasos 1578 a specific mode. This is necessary on Pegasos
1567 computer where firmware has no options for setting 1579 computer where firmware has no options for setting
1568 up parallel port mode and sets it to spp. 1580 up parallel port mode and sets it to spp.
1569 Currently this function knows 686a and 8231 chips. 1581 Currently this function knows 686a and 8231 chips.
1570 Format: [spp|ps2|epp|ecp|ecpepp] 1582 Format: [spp|ps2|epp|ecp|ecpepp]
1571 1583
1572 pas2= [HW,OSS] Format: 1584 pas2= [HW,OSS] Format:
1573 <io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16> 1585 <io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16>
1574 1586
1575 pas16= [HW,SCSI] 1587 pas16= [HW,SCSI]
1576 See header of drivers/scsi/pas16.c. 1588 See header of drivers/scsi/pas16.c.
1577 1589
1578 pause_on_oops= 1590 pause_on_oops=
1579 Halt all CPUs after the first oops has been printed for 1591 Halt all CPUs after the first oops has been printed for
1580 the specified number of seconds. This is to be used if 1592 the specified number of seconds. This is to be used if
1581 your oopses keep scrolling off the screen. 1593 your oopses keep scrolling off the screen.
1582 1594
1583 pcbit= [HW,ISDN] 1595 pcbit= [HW,ISDN]
1584 1596
1585 pcd. [PARIDE] 1597 pcd. [PARIDE]
1586 See header of drivers/block/paride/pcd.c. 1598 See header of drivers/block/paride/pcd.c.
1587 See also Documentation/paride.txt. 1599 See also Documentation/paride.txt.
1588 1600
1589 pci=option[,option...] [PCI] various PCI subsystem options: 1601 pci=option[,option...] [PCI] various PCI subsystem options:
1590 off [X86] don't probe for the PCI bus 1602 off [X86] don't probe for the PCI bus
1591 bios [X86-32] force use of PCI BIOS, don't access 1603 bios [X86-32] force use of PCI BIOS, don't access
1592 the hardware directly. Use this if your machine 1604 the hardware directly. Use this if your machine
1593 has a non-standard PCI host bridge. 1605 has a non-standard PCI host bridge.
1594 nobios [X86-32] disallow use of PCI BIOS, only direct 1606 nobios [X86-32] disallow use of PCI BIOS, only direct
1595 hardware access methods are allowed. Use this 1607 hardware access methods are allowed. Use this
1596 if you experience crashes upon bootup and you 1608 if you experience crashes upon bootup and you
1597 suspect they are caused by the BIOS. 1609 suspect they are caused by the BIOS.
1598 conf1 [X86] Force use of PCI Configuration 1610 conf1 [X86] Force use of PCI Configuration
1599 Mechanism 1. 1611 Mechanism 1.
1600 conf2 [X86] Force use of PCI Configuration 1612 conf2 [X86] Force use of PCI Configuration
1601 Mechanism 2. 1613 Mechanism 2.
1602 noaer [PCIE] If the PCIEAER kernel config parameter is 1614 noaer [PCIE] If the PCIEAER kernel config parameter is
1603 enabled, this kernel boot option can be used to 1615 enabled, this kernel boot option can be used to
1604 disable the use of PCIE advanced error reporting. 1616 disable the use of PCIE advanced error reporting.
1605 nodomains [PCI] Disable support for multiple PCI 1617 nodomains [PCI] Disable support for multiple PCI
1606 root domains (aka PCI segments, in ACPI-speak). 1618 root domains (aka PCI segments, in ACPI-speak).
1607 nommconf [X86-32,X86_64] Disable use of MMCONFIG for PCI 1619 nommconf [X86-32,X86_64] Disable use of MMCONFIG for PCI
1608 Configuration 1620 Configuration
1609 nomsi [MSI] If the PCI_MSI kernel config parameter is 1621 nomsi [MSI] If the PCI_MSI kernel config parameter is
1610 enabled, this kernel boot option can be used to 1622 enabled, this kernel boot option can be used to
1611 disable the use of MSI interrupts system-wide. 1623 disable the use of MSI interrupts system-wide.
1612 biosirq [X86-32] Use PCI BIOS calls to get the interrupt 1624 biosirq [X86-32] Use PCI BIOS calls to get the interrupt
1613 routing table. These calls are known to be buggy 1625 routing table. These calls are known to be buggy
1614 on several machines and they hang the machine 1626 on several machines and they hang the machine
1615 when used, but on other computers it's the only 1627 when used, but on other computers it's the only
1616 way to get the interrupt routing table. Try 1628 way to get the interrupt routing table. Try
1617 this option if the kernel is unable to allocate 1629 this option if the kernel is unable to allocate
1618 IRQs or discover secondary PCI buses on your 1630 IRQs or discover secondary PCI buses on your
1619 motherboard. 1631 motherboard.
1620 rom [X86] Assign address space to expansion ROMs. 1632 rom [X86] Assign address space to expansion ROMs.
1621 Use with caution as certain devices share 1633 Use with caution as certain devices share
1622 address decoders between ROMs and other 1634 address decoders between ROMs and other
1623 resources. 1635 resources.
1624 norom [X86] Do not assign address space to 1636 norom [X86] Do not assign address space to
1625 expansion ROMs that do not already have 1637 expansion ROMs that do not already have
1626 BIOS assigned address ranges. 1638 BIOS assigned address ranges.
1627 irqmask=0xMMMM [X86] Set a bit mask of IRQs allowed to be 1639 irqmask=0xMMMM [X86] Set a bit mask of IRQs allowed to be
1628 assigned automatically to PCI devices. You can 1640 assigned automatically to PCI devices. You can
1629 make the kernel exclude IRQs of your ISA cards 1641 make the kernel exclude IRQs of your ISA cards
1630 this way. 1642 this way.
1631 pirqaddr=0xAAAAA [X86] Specify the physical address 1643 pirqaddr=0xAAAAA [X86] Specify the physical address
1632 of the PIRQ table (normally generated 1644 of the PIRQ table (normally generated
1633 by the BIOS) if it is outside the 1645 by the BIOS) if it is outside the
1634 F0000h-100000h range. 1646 F0000h-100000h range.
1635 lastbus=N [X86] Scan all buses thru bus #N. Can be 1647 lastbus=N [X86] Scan all buses thru bus #N. Can be
1636 useful if the kernel is unable to find your 1648 useful if the kernel is unable to find your
1637 secondary buses and you want to tell it 1649 secondary buses and you want to tell it
1638 explicitly which ones they are. 1650 explicitly which ones they are.
1639 assign-busses [X86] Always assign all PCI bus 1651 assign-busses [X86] Always assign all PCI bus
1640 numbers ourselves, overriding 1652 numbers ourselves, overriding
1641 whatever the firmware may have done. 1653 whatever the firmware may have done.
1642 usepirqmask [X86] Honor the possible IRQ mask stored 1654 usepirqmask [X86] Honor the possible IRQ mask stored
1643 in the BIOS $PIR table. This is needed on 1655 in the BIOS $PIR table. This is needed on
1644 some systems with broken BIOSes, notably 1656 some systems with broken BIOSes, notably
1645 some HP Pavilion N5400 and Omnibook XE3 1657 some HP Pavilion N5400 and Omnibook XE3
1646 notebooks. This will have no effect if ACPI 1658 notebooks. This will have no effect if ACPI
1647 IRQ routing is enabled. 1659 IRQ routing is enabled.
1648 noacpi [X86] Do not use ACPI for IRQ routing 1660 noacpi [X86] Do not use ACPI for IRQ routing
1649 or for PCI scanning. 1661 or for PCI scanning.
1650 use_crs [X86] Use _CRS for PCI resource 1662 use_crs [X86] Use _CRS for PCI resource
1651 allocation. 1663 allocation.
1652 routeirq Do IRQ routing for all PCI devices. 1664 routeirq Do IRQ routing for all PCI devices.
1653 This is normally done in pci_enable_device(), 1665 This is normally done in pci_enable_device(),
1654 so this option is a temporary workaround 1666 so this option is a temporary workaround
1655 for broken drivers that don't call it. 1667 for broken drivers that don't call it.
1656 skip_isa_align [X86] do not align io start addr, so can 1668 skip_isa_align [X86] do not align io start addr, so can
1657 handle more pci cards 1669 handle more pci cards
1658 firmware [ARM] Do not re-enumerate the bus but instead 1670 firmware [ARM] Do not re-enumerate the bus but instead
1659 just use the configuration from the 1671 just use the configuration from the
1660 bootloader. This is currently used on 1672 bootloader. This is currently used on
1661 IXP2000 systems where the bus has to be 1673 IXP2000 systems where the bus has to be
1662 configured a certain way for adjunct CPUs. 1674 configured a certain way for adjunct CPUs.
1663 noearly [X86] Don't do any early type 1 scanning. 1675 noearly [X86] Don't do any early type 1 scanning.
1664 This might help on some broken boards which 1676 This might help on some broken boards which
1665 machine check when some devices' config space 1677 machine check when some devices' config space
1666 is read. But various workarounds are disabled 1678 is read. But various workarounds are disabled
1667 and some IOMMU drivers will not work. 1679 and some IOMMU drivers will not work.
1668 bfsort Sort PCI devices into breadth-first order. 1680 bfsort Sort PCI devices into breadth-first order.
1669 This sorting is done to get a device 1681 This sorting is done to get a device
1670 order compatible with older (<= 2.4) kernels. 1682 order compatible with older (<= 2.4) kernels.
1671 nobfsort Don't sort PCI devices into breadth-first order. 1683 nobfsort Don't sort PCI devices into breadth-first order.
1672 cbiosize=nn[KMG] The fixed amount of bus space which is 1684 cbiosize=nn[KMG] The fixed amount of bus space which is
1673 reserved for the CardBus bridge's IO window. 1685 reserved for the CardBus bridge's IO window.
1674 The default value is 256 bytes. 1686 The default value is 256 bytes.
1675 cbmemsize=nn[KMG] The fixed amount of bus space which is 1687 cbmemsize=nn[KMG] The fixed amount of bus space which is
1676 reserved for the CardBus bridge's memory 1688 reserved for the CardBus bridge's memory
1677 window. The default value is 64 megabytes. 1689 window. The default value is 64 megabytes.
1678 1690
1679 pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power 1691 pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
1680 Management. 1692 Management.
1681 off Disable ASPM. 1693 off Disable ASPM.
1682 force Enable ASPM even on devices that claim not to support it. 1694 force Enable ASPM even on devices that claim not to support it.
1683 WARNING: Forcing ASPM on may cause system lockups. 1695 WARNING: Forcing ASPM on may cause system lockups.
1684 1696
1685 pcmv= [HW,PCMCIA] BadgePAD 4 1697 pcmv= [HW,PCMCIA] BadgePAD 4
1686 1698
1687 pd. [PARIDE] 1699 pd. [PARIDE]
1688 See Documentation/paride.txt. 1700 See Documentation/paride.txt.
1689 1701
1690 pdcchassis= [PARISC,HW] Disable/Enable PDC Chassis Status codes at 1702 pdcchassis= [PARISC,HW] Disable/Enable PDC Chassis Status codes at
1691 boot time. 1703 boot time.
1692 Format: { 0 | 1 } 1704 Format: { 0 | 1 }
1693 See arch/parisc/kernel/pdc_chassis.c 1705 See arch/parisc/kernel/pdc_chassis.c
1694 1706
1695 pf. [PARIDE] 1707 pf. [PARIDE]
1696 See Documentation/paride.txt. 1708 See Documentation/paride.txt.
1697 1709
1698 pg. [PARIDE] 1710 pg. [PARIDE]
1699 See Documentation/paride.txt. 1711 See Documentation/paride.txt.
1700 1712
1701 pirq= [SMP,APIC] Manual mp-table setup 1713 pirq= [SMP,APIC] Manual mp-table setup
1702 See Documentation/x86/i386/IO-APIC.txt. 1714 See Documentation/x86/i386/IO-APIC.txt.
1703 1715
1704 plip= [PPT,NET] Parallel port network link 1716 plip= [PPT,NET] Parallel port network link
1705 Format: { parport<nr> | timid | 0 } 1717 Format: { parport<nr> | timid | 0 }
1706 See also Documentation/parport.txt. 1718 See also Documentation/parport.txt.
1707 1719
1708 pmtmr= [X86] Manual setup of pmtmr I/O Port. 1720 pmtmr= [X86] Manual setup of pmtmr I/O Port.
1709 Override pmtimer IOPort with a hex value. 1721 Override pmtimer IOPort with a hex value.
1710 e.g. pmtmr=0x508 1722 e.g. pmtmr=0x508
1711 1723
1712 pnp.debug [PNP] 1724 pnp.debug [PNP]
1713 Enable PNP debug messages. This depends on the 1725 Enable PNP debug messages. This depends on the
1714 CONFIG_PNP_DEBUG_MESSAGES option. 1726 CONFIG_PNP_DEBUG_MESSAGES option.
1715 1727
1716 pnpacpi= [ACPI] 1728 pnpacpi= [ACPI]
1717 { off } 1729 { off }
1718 1730
1719 pnpbios= [ISAPNP] 1731 pnpbios= [ISAPNP]
1720 { on | off | curr | res | no-curr | no-res } 1732 { on | off | curr | res | no-curr | no-res }
1721 1733
1722 pnp_reserve_irq= 1734 pnp_reserve_irq=
1723 [ISAPNP] Exclude IRQs for the autoconfiguration 1735 [ISAPNP] Exclude IRQs for the autoconfiguration
1724 1736
1725 pnp_reserve_dma= 1737 pnp_reserve_dma=
1726 [ISAPNP] Exclude DMAs for the autoconfiguration 1738 [ISAPNP] Exclude DMAs for the autoconfiguration
1727 1739
1728 pnp_reserve_io= [ISAPNP] Exclude I/O ports for the autoconfiguration 1740 pnp_reserve_io= [ISAPNP] Exclude I/O ports for the autoconfiguration
1729 Ranges are in pairs (I/O port base and size). 1741 Ranges are in pairs (I/O port base and size).
1730 1742
1731 pnp_reserve_mem= 1743 pnp_reserve_mem=
1732 [ISAPNP] Exclude memory regions for the 1744 [ISAPNP] Exclude memory regions for the
1733 autoconfiguration. 1745 autoconfiguration.
1734 Ranges are in pairs (memory base and size). 1746 Ranges are in pairs (memory base and size).
1735 1747
1736 dynamic_printk 1748 dynamic_printk
1737 Enables pr_debug()/dev_dbg() calls if 1749 Enables pr_debug()/dev_dbg() calls if
1738 CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also 1750 CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also
1739 be switched on/off via <debugfs>/dynamic_printk/modules 1751 be switched on/off via <debugfs>/dynamic_printk/modules
1740 1752
1741 print-fatal-signals= 1753 print-fatal-signals=
1742 [KNL] debug: print fatal signals 1754 [KNL] debug: print fatal signals
1743 print-fatal-signals=1: print segfault info to 1755 print-fatal-signals=1: print segfault info to
1744 the kernel console. 1756 the kernel console.
1745 default: off. 1757 default: off.
1746 1758
1747 printk.time= Show timing data prefixed to each printk message line 1759 printk.time= Show timing data prefixed to each printk message line
1748 Format: <bool> (1/Y/y=enable, 0/N/n=disable) 1760 Format: <bool> (1/Y/y=enable, 0/N/n=disable)
1749 1761
1750 profile= [KNL] Enable kernel profiling via /proc/profile 1762 profile= [KNL] Enable kernel profiling via /proc/profile
1751 Format: [schedule,]<number> 1763 Format: [schedule,]<number>
1752 Param: "schedule" - profile schedule points. 1764 Param: "schedule" - profile schedule points.
1753 Param: <number> - step/bucket size as a power of 2 for 1765 Param: <number> - step/bucket size as a power of 2 for
1754 statistical time based profiling. 1766 statistical time based profiling.
1755 Param: "sleep" - profile D-state sleeping (millisecs). 1767 Param: "sleep" - profile D-state sleeping (millisecs).
1756 Requires CONFIG_SCHEDSTATS 1768 Requires CONFIG_SCHEDSTATS
1757 Param: "kvm" - profile VM exits. 1769 Param: "kvm" - profile VM exits.
1758 1770
1759 processor.max_cstate= [HW,ACPI] 1771 processor.max_cstate= [HW,ACPI]
1760 Limit processor to maximum C-state 1772 Limit processor to maximum C-state
1761 max_cstate=9 overrides any DMI blacklist limit. 1773 max_cstate=9 overrides any DMI blacklist limit.
1762 1774
1763 processor.nocst [HW,ACPI] 1775 processor.nocst [HW,ACPI]
1764 Ignore the _CST method to determine C-states, 1776 Ignore the _CST method to determine C-states,
1765 instead using the legacy FADT method 1777 instead using the legacy FADT method
1766 1778
1767 prompt_ramdisk= [RAM] List of RAM disks to prompt for floppy disk 1779 prompt_ramdisk= [RAM] List of RAM disks to prompt for floppy disk
1768 before loading. 1780 before loading.
1769 See Documentation/ramdisk.txt. 1781 See Documentation/ramdisk.txt.
1770 1782
1771 psmouse.proto= [HW,MOUSE] Highest PS2 mouse protocol extension to 1783 psmouse.proto= [HW,MOUSE] Highest PS2 mouse protocol extension to
1772 probe for; one of (bare|imps|exps|lifebook|any). 1784 probe for; one of (bare|imps|exps|lifebook|any).
1773 psmouse.rate= [HW,MOUSE] Set desired mouse report rate, in reports 1785 psmouse.rate= [HW,MOUSE] Set desired mouse report rate, in reports
1774 per second. 1786 per second.
1775 psmouse.resetafter= [HW,MOUSE] 1787 psmouse.resetafter= [HW,MOUSE]
1776 Try to reset the device after so many bad packets 1788 Try to reset the device after so many bad packets
1777 (0 = never). 1789 (0 = never).
1778 psmouse.resolution= 1790 psmouse.resolution=
1779 [HW,MOUSE] Set desired mouse resolution, in dpi. 1791 [HW,MOUSE] Set desired mouse resolution, in dpi.
1780 psmouse.smartscroll= 1792 psmouse.smartscroll=
1781 [HW,MOUSE] Controls Logitech smartscroll autorepeat. 1793 [HW,MOUSE] Controls Logitech smartscroll autorepeat.
1782 0 = disabled, 1 = enabled (default). 1794 0 = disabled, 1 = enabled (default).
1783 1795
1784 pss= [HW,OSS] Personal Sound System (ECHO ESC614) 1796 pss= [HW,OSS] Personal Sound System (ECHO ESC614)
1785 Format: 1797 Format:
1786 <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq> 1798 <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
1787 1799
1788 pt. [PARIDE] 1800 pt. [PARIDE]
1789 See Documentation/paride.txt. 1801 See Documentation/paride.txt.
1790 1802
1791 pty.legacy_count= 1803 pty.legacy_count=
1792 [KNL] Number of legacy pty's. Overwrites compiled-in 1804 [KNL] Number of legacy pty's. Overwrites compiled-in
1793 default number. 1805 default number.
1794 1806
1795 quiet [KNL] Disable most log messages 1807 quiet [KNL] Disable most log messages
1796 1808
1797 r128= [HW,DRM] 1809 r128= [HW,DRM]
1798 1810
1799 raid= [HW,RAID] 1811 raid= [HW,RAID]
1800 See Documentation/md.txt. 1812 See Documentation/md.txt.
1801 1813
1802 ramdisk_blocksize= [RAM] 1814 ramdisk_blocksize= [RAM]
1803 See Documentation/ramdisk.txt. 1815 See Documentation/ramdisk.txt.
1804 1816
1805 ramdisk_size= [RAM] Sizes of RAM disks in kilobytes 1817 ramdisk_size= [RAM] Sizes of RAM disks in kilobytes
1806 See Documentation/ramdisk.txt. 1818 See Documentation/ramdisk.txt.
1807 1819
1808 rcupdate.blimit= [KNL,BOOT] 1820 rcupdate.blimit= [KNL,BOOT]
1809 Set maximum number of finished RCU callbacks to process 1821 Set maximum number of finished RCU callbacks to process
1810 in one batch. 1822 in one batch.
1811 1823
1812 rcupdate.qhimark= [KNL,BOOT] 1824 rcupdate.qhimark= [KNL,BOOT]
1813 Set threshold of queued 1825 Set threshold of queued
1814 RCU callbacks over which batch limiting is disabled. 1826 RCU callbacks over which batch limiting is disabled.
1815 1827
1816 rcupdate.qlowmark= [KNL,BOOT] 1828 rcupdate.qlowmark= [KNL,BOOT]
1817 Set threshold of queued RCU callbacks below which 1829 Set threshold of queued RCU callbacks below which
1818 batch limiting is re-enabled. 1830 batch limiting is re-enabled.
1819 1831
1820 rdinit= [KNL] 1832 rdinit= [KNL]
1821 Format: <full_path> 1833 Format: <full_path>
1822 Run specified binary instead of /init from the ramdisk, 1834 Run specified binary instead of /init from the ramdisk,
1823 used for early userspace startup. See initrd. 1835 used for early userspace startup. See initrd.
1824 1836
1825 reboot= [BUGS=X86-32,BUGS=ARM,BUGS=IA-64] Rebooting mode 1837 reboot= [BUGS=X86-32,BUGS=ARM,BUGS=IA-64] Rebooting mode
1826 Format: <reboot_mode>[,<reboot_mode2>[,...]] 1838 Format: <reboot_mode>[,<reboot_mode2>[,...]]
1827 See arch/*/kernel/reboot.c or arch/*/kernel/process.c 1839 See arch/*/kernel/reboot.c or arch/*/kernel/process.c
1828 1840
1829 relax_domain_level= 1841 relax_domain_level=
1830 [KNL, SMP] Set scheduler's default relax_domain_level. 1842 [KNL, SMP] Set scheduler's default relax_domain_level.
1831 See Documentation/cpusets.txt. 1843 See Documentation/cpusets.txt.
1832 1844
1833 reserve= [KNL,BUGS] Force the kernel to ignore some iomem area 1845 reserve= [KNL,BUGS] Force the kernel to ignore some iomem area
1834 1846
1835 reservetop= [X86-32] 1847 reservetop= [X86-32]
1836 Format: nn[KMG] 1848 Format: nn[KMG]
1837 Reserves a hole at the top of the kernel virtual 1849 Reserves a hole at the top of the kernel virtual
1838 address space. 1850 address space.
1839 1851
1840 reset_devices [KNL] Force drivers to reset the underlying device 1852 reset_devices [KNL] Force drivers to reset the underlying device
1841 during initialization. 1853 during initialization.
1842 1854
1843 resume= [SWSUSP] 1855 resume= [SWSUSP]
1844 Specify the partition device for software suspend 1856 Specify the partition device for software suspend
1845 1857
1846 resume_offset= [SWSUSP] 1858 resume_offset= [SWSUSP]
1847 Specify the offset from the beginning of the partition 1859 Specify the offset from the beginning of the partition
1848 given by "resume=" at which the swap header is located, 1860 given by "resume=" at which the swap header is located,
1849 in <PAGE_SIZE> units (needed only for swap files). 1861 in <PAGE_SIZE> units (needed only for swap files).
1850 See Documentation/power/swsusp-and-swap-files.txt 1862 See Documentation/power/swsusp-and-swap-files.txt
1851 1863
1852 retain_initrd [RAM] Keep initrd memory after extraction 1864 retain_initrd [RAM] Keep initrd memory after extraction
1853 1865
1854 rhash_entries= [KNL,NET] 1866 rhash_entries= [KNL,NET]
1855 Set number of hash buckets for route cache 1867 Set number of hash buckets for route cache
1856 1868
1857 riscom8= [HW,SERIAL] 1869 riscom8= [HW,SERIAL]
1858 Format: <io_board1>[,<io_board2>[,...<io_boardN>]] 1870 Format: <io_board1>[,<io_board2>[,...<io_boardN>]]
1859 1871
1860 ro [KNL] Mount root device read-only on boot 1872 ro [KNL] Mount root device read-only on boot
1861 1873
1862 root= [KNL] Root filesystem 1874 root= [KNL] Root filesystem
1863 1875
1864 rootdelay= [KNL] Delay (in seconds) to pause before attempting to 1876 rootdelay= [KNL] Delay (in seconds) to pause before attempting to
1865 mount the root filesystem 1877 mount the root filesystem
1866 1878
1867 rootflags= [KNL] Set root filesystem mount option string 1879 rootflags= [KNL] Set root filesystem mount option string
1868 1880
1869 rootfstype= [KNL] Set root filesystem type 1881 rootfstype= [KNL] Set root filesystem type
1870 1882
1871 rootwait [KNL] Wait (indefinitely) for root device to show up. 1883 rootwait [KNL] Wait (indefinitely) for root device to show up.
1872 Useful for devices that are detected asynchronously 1884 Useful for devices that are detected asynchronously
1873 (e.g. USB and MMC devices). 1885 (e.g. USB and MMC devices).
1874 1886
1875 root_plug.vendor_id= 1887 root_plug.vendor_id=
1876 [ROOTPLUG] Override the default vendor ID 1888 [ROOTPLUG] Override the default vendor ID
1877 1889
1878 root_plug.product_id= 1890 root_plug.product_id=
1879 [ROOTPLUG] Override the default product ID 1891 [ROOTPLUG] Override the default product ID
1880 1892
1881 root_plug.debug= 1893 root_plug.debug=
1882 [ROOTPLUG] Enable debugging output 1894 [ROOTPLUG] Enable debugging output
1883 1895
1884 rw [KNL] Mount root device read-write on boot 1896 rw [KNL] Mount root device read-write on boot
1885 1897
1886 S [KNL] Run init in single mode 1898 S [KNL] Run init in single mode
1887 1899
1888 sa1100ir [NET] 1900 sa1100ir [NET]
1889 See drivers/net/irda/sa1100_ir.c. 1901 See drivers/net/irda/sa1100_ir.c.
1890 1902
1891 sbni= [NET] Granch SBNI12 leased line adapter 1903 sbni= [NET] Granch SBNI12 leased line adapter
1892 1904
1893 sc1200wdt= [HW,WDT] SC1200 WDT (watchdog) driver 1905 sc1200wdt= [HW,WDT] SC1200 WDT (watchdog) driver
1894 Format: <io>[,<timeout>[,<isapnp>]] 1906 Format: <io>[,<timeout>[,<isapnp>]]
1895 1907
1896 scsi_debug_*= [SCSI] 1908 scsi_debug_*= [SCSI]
1897 See drivers/scsi/scsi_debug.c. 1909 See drivers/scsi/scsi_debug.c.
1898 1910
1899 scsi_default_dev_flags= 1911 scsi_default_dev_flags=
1900 [SCSI] SCSI default device flags 1912 [SCSI] SCSI default device flags
1901 Format: <integer> 1913 Format: <integer>
1902 1914
1903 scsi_dev_flags= [SCSI] Black/white list entry for vendor and model 1915 scsi_dev_flags= [SCSI] Black/white list entry for vendor and model
1904 Format: <vendor>:<model>:<flags> 1916 Format: <vendor>:<model>:<flags>
1905 (flags are integer value) 1917 (flags are integer value)
1906 1918
1907 scsi_logging_level= [SCSI] a bit mask of logging levels 1919 scsi_logging_level= [SCSI] a bit mask of logging levels
1908 See drivers/scsi/scsi_logging.h for bits. Also 1920 See drivers/scsi/scsi_logging.h for bits. Also
1909 settable via sysctl at dev.scsi.logging_level 1921 settable via sysctl at dev.scsi.logging_level
1910 (/proc/sys/dev/scsi/logging_level). 1922 (/proc/sys/dev/scsi/logging_level).
1911 There is also a nice 'scsi_logging_level' script in the 1923 There is also a nice 'scsi_logging_level' script in the
1912 S390-tools package, available for download at 1924 S390-tools package, available for download at
1913 http://www-128.ibm.com/developerworks/linux/linux390/s390-tools-1.5.4.html 1925 http://www-128.ibm.com/developerworks/linux/linux390/s390-tools-1.5.4.html
1914 1926
1915 scsi_mod.scan= [SCSI] sync (default) scans SCSI busses as they are 1927 scsi_mod.scan= [SCSI] sync (default) scans SCSI busses as they are
1916 discovered. async scans them in kernel threads, 1928 discovered. async scans them in kernel threads,
1917 allowing boot to proceed. none ignores them, expecting 1929 allowing boot to proceed. none ignores them, expecting
1918 user space to do the scan. 1930 user space to do the scan.
1919 1931
1920 selinux [SELINUX] Disable or enable SELinux at boot time. 1932 selinux [SELINUX] Disable or enable SELinux at boot time.
1921 Format: { "0" | "1" } 1933 Format: { "0" | "1" }
1922 See security/selinux/Kconfig help text. 1934 See security/selinux/Kconfig help text.
1923 0 -- disable. 1935 0 -- disable.
1924 1 -- enable. 1936 1 -- enable.
1925 Default value is set via kernel config option. 1937 Default value is set via kernel config option.
1926 If enabled at boot time, /selinux/disable can be used 1938 If enabled at boot time, /selinux/disable can be used
1927 later to disable prior to initial policy load. 1939 later to disable prior to initial policy load.
1928 1940
1929 selinux_compat_net = 1941 selinux_compat_net =
1930 [SELINUX] Set initial selinux_compat_net flag value. 1942 [SELINUX] Set initial selinux_compat_net flag value.
1931 Format: { "0" | "1" } 1943 Format: { "0" | "1" }
1932 0 -- use new secmark-based packet controls 1944 0 -- use new secmark-based packet controls
1933 1 -- use legacy packet controls 1945 1 -- use legacy packet controls
1934 Default value is 0 (preferred). 1946 Default value is 0 (preferred).
1935 Value can be changed at runtime via 1947 Value can be changed at runtime via
1936 /selinux/compat_net. 1948 /selinux/compat_net.
1937 1949
1938 serialnumber [BUGS=X86-32] 1950 serialnumber [BUGS=X86-32]
1939 1951
1940 shapers= [NET] 1952 shapers= [NET]
1941 Maximal number of shapers. 1953 Maximal number of shapers.
1942 1954
1943 show_msr= [x86] show boot-time MSR settings 1955 show_msr= [x86] show boot-time MSR settings
1944 Format: { <integer> } 1956 Format: { <integer> }
1945 Show boot-time (BIOS-initialized) MSR settings. 1957 Show boot-time (BIOS-initialized) MSR settings.
1946 The parameter means the number of CPUs to show, 1958 The parameter means the number of CPUs to show,
1947 for example 1 means boot CPU only. 1959 for example 1 means boot CPU only.
1948 1960
1949 sim710= [SCSI,HW] 1961 sim710= [SCSI,HW]
1950 See header of drivers/scsi/sim710.c. 1962 See header of drivers/scsi/sim710.c.
1951 1963
1952 simeth= [IA-64] 1964 simeth= [IA-64]
1953 simscsi= 1965 simscsi=
1954 1966
1955 slram= [HW,MTD] 1967 slram= [HW,MTD]
1956 1968
1957 slub_debug[=options[,slabs]] [MM, SLUB] 1969 slub_debug[=options[,slabs]] [MM, SLUB]
1958 Enabling slub_debug allows one to determine the 1970 Enabling slub_debug allows one to determine the
1959 culprit if slab objects become corrupted. Enabling 1971 culprit if slab objects become corrupted. Enabling
1960 slub_debug can create guard zones around objects and 1972 slub_debug can create guard zones around objects and
1961 may poison objects when not in use. Also tracks the 1973 may poison objects when not in use. Also tracks the
1962 last alloc / free. For more information see 1974 last alloc / free. For more information see
1963 Documentation/vm/slub.txt. 1975 Documentation/vm/slub.txt.
1964 1976
1965 slub_max_order= [MM, SLUB] 1977 slub_max_order= [MM, SLUB]
1966 Determines the maximum allowed order for slabs. 1978 Determines the maximum allowed order for slabs.
1967 A high setting may cause OOMs due to memory 1979 A high setting may cause OOMs due to memory
1968 fragmentation. For more information see 1980 fragmentation. For more information see
1969 Documentation/vm/slub.txt. 1981 Documentation/vm/slub.txt.
1970 1982
1971 slub_min_objects= [MM, SLUB] 1983 slub_min_objects= [MM, SLUB]
1972 The minimum number of objects per slab. SLUB will 1984 The minimum number of objects per slab. SLUB will
1973 increase the slab order up to slub_max_order to 1985 increase the slab order up to slub_max_order to
1974 generate a sufficiently large slab able to contain 1986 generate a sufficiently large slab able to contain
1975 the number of objects indicated. The higher the number 1987 the number of objects indicated. The higher the number
1976 of objects the smaller the overhead of tracking slabs 1988 of objects the smaller the overhead of tracking slabs
1977 and the less frequently locks need to be acquired. 1989 and the less frequently locks need to be acquired.
1978 For more information see Documentation/vm/slub.txt. 1990 For more information see Documentation/vm/slub.txt.
1979 1991
1980 slub_min_order= [MM, SLUB] 1992 slub_min_order= [MM, SLUB]
1981 Determines the mininum page order for slabs. Must be 1993 Determines the mininum page order for slabs. Must be
1982 lower than slub_max_order. 1994 lower than slub_max_order.
1983 For more information see Documentation/vm/slub.txt. 1995 For more information see Documentation/vm/slub.txt.
1984 1996
1985 slub_nomerge [MM, SLUB] 1997 slub_nomerge [MM, SLUB]
1986 Disable merging of slabs with similar size. May be 1998 Disable merging of slabs with similar size. May be
1987 necessary if there is some reason to distinguish 1999 necessary if there is some reason to distinguish
1988 allocs to different slabs. Debug options disable 2000 allocs to different slabs. Debug options disable
1989 merging on their own. 2001 merging on their own.
1990 For more information see Documentation/vm/slub.txt. 2002 For more information see Documentation/vm/slub.txt.
1991 2003
1992 smart2= [HW] 2004 smart2= [HW]
1993 Format: <io1>[,<io2>[,...,<io8>]] 2005 Format: <io1>[,<io2>[,...,<io8>]]
1994 2006
1995 smp-alt-once [X86-32,SMP] On a hotplug CPU system, only 2007 smp-alt-once [X86-32,SMP] On a hotplug CPU system, only
1996 attempt to substitute SMP alternatives once at boot. 2008 attempt to substitute SMP alternatives once at boot.
1997 2009
1998 smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices 2010 smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices
1999 smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port 2011 smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port
2000 smsc-ircc2.ircc_sir= [HW] SIR base I/O port 2012 smsc-ircc2.ircc_sir= [HW] SIR base I/O port
2001 smsc-ircc2.ircc_fir= [HW] FIR base I/O port 2013 smsc-ircc2.ircc_fir= [HW] FIR base I/O port
2002 smsc-ircc2.ircc_irq= [HW] IRQ line 2014 smsc-ircc2.ircc_irq= [HW] IRQ line
2003 smsc-ircc2.ircc_dma= [HW] DMA channel 2015 smsc-ircc2.ircc_dma= [HW] DMA channel
2004 smsc-ircc2.ircc_transceiver= [HW] Transceiver type: 2016 smsc-ircc2.ircc_transceiver= [HW] Transceiver type:
2005 0: Toshiba Satellite 1800 (GP data pin select) 2017 0: Toshiba Satellite 1800 (GP data pin select)
2006 1: Fast pin select (default) 2018 1: Fast pin select (default)
2007 2: ATC IRMode 2019 2: ATC IRMode
2008 2020
2009 snd-ad1816a= [HW,ALSA] 2021 snd-ad1816a= [HW,ALSA]
2010 2022
2011 snd-ad1848= [HW,ALSA] 2023 snd-ad1848= [HW,ALSA]
2012 2024
2013 snd-ali5451= [HW,ALSA] 2025 snd-ali5451= [HW,ALSA]
2014 2026
2015 snd-als100= [HW,ALSA] 2027 snd-als100= [HW,ALSA]
2016 2028
2017 snd-als4000= [HW,ALSA] 2029 snd-als4000= [HW,ALSA]
2018 2030
2019 snd-azt2320= [HW,ALSA] 2031 snd-azt2320= [HW,ALSA]
2020 2032
2021 snd-cmi8330= [HW,ALSA] 2033 snd-cmi8330= [HW,ALSA]
2022 2034
2023 snd-cmipci= [HW,ALSA] 2035 snd-cmipci= [HW,ALSA]
2024 2036
2025 snd-cs4231= [HW,ALSA] 2037 snd-cs4231= [HW,ALSA]
2026 2038
2027 snd-cs4232= [HW,ALSA] 2039 snd-cs4232= [HW,ALSA]
2028 2040
2029 snd-cs4236= [HW,ALSA] 2041 snd-cs4236= [HW,ALSA]
2030 2042
2031 snd-cs4281= [HW,ALSA] 2043 snd-cs4281= [HW,ALSA]
2032 2044
2033 snd-cs46xx= [HW,ALSA] 2045 snd-cs46xx= [HW,ALSA]
2034 2046
2035 snd-dt019x= [HW,ALSA] 2047 snd-dt019x= [HW,ALSA]
2036 2048
2037 snd-dummy= [HW,ALSA] 2049 snd-dummy= [HW,ALSA]
2038 2050
2039 snd-emu10k1= [HW,ALSA] 2051 snd-emu10k1= [HW,ALSA]
2040 2052
2041 snd-ens1370= [HW,ALSA] 2053 snd-ens1370= [HW,ALSA]
2042 2054
2043 snd-ens1371= [HW,ALSA] 2055 snd-ens1371= [HW,ALSA]
2044 2056
2045 snd-es968= [HW,ALSA] 2057 snd-es968= [HW,ALSA]
2046 2058
2047 snd-es1688= [HW,ALSA] 2059 snd-es1688= [HW,ALSA]
2048 2060
2049 snd-es18xx= [HW,ALSA] 2061 snd-es18xx= [HW,ALSA]
2050 2062
2051 snd-es1938= [HW,ALSA] 2063 snd-es1938= [HW,ALSA]
2052 2064
2053 snd-es1968= [HW,ALSA] 2065 snd-es1968= [HW,ALSA]
2054 2066
2055 snd-fm801= [HW,ALSA] 2067 snd-fm801= [HW,ALSA]
2056 2068
2057 snd-gusclassic= [HW,ALSA] 2069 snd-gusclassic= [HW,ALSA]
2058 2070
2059 snd-gusextreme= [HW,ALSA] 2071 snd-gusextreme= [HW,ALSA]
2060 2072
2061 snd-gusmax= [HW,ALSA] 2073 snd-gusmax= [HW,ALSA]
2062 2074
2063 snd-hdsp= [HW,ALSA] 2075 snd-hdsp= [HW,ALSA]
2064 2076
2065 snd-ice1712= [HW,ALSA] 2077 snd-ice1712= [HW,ALSA]
2066 2078
2067 snd-intel8x0= [HW,ALSA] 2079 snd-intel8x0= [HW,ALSA]
2068 2080
2069 snd-interwave= [HW,ALSA] 2081 snd-interwave= [HW,ALSA]
2070 2082
2071 snd-interwave-stb= 2083 snd-interwave-stb=
2072 [HW,ALSA] 2084 [HW,ALSA]
2073 2085
2074 snd-korg1212= [HW,ALSA] 2086 snd-korg1212= [HW,ALSA]
2075 2087
2076 snd-maestro3= [HW,ALSA] 2088 snd-maestro3= [HW,ALSA]
2077 2089
2078 snd-mpu401= [HW,ALSA] 2090 snd-mpu401= [HW,ALSA]
2079 2091
2080 snd-mtpav= [HW,ALSA] 2092 snd-mtpav= [HW,ALSA]
2081 2093
2082 snd-nm256= [HW,ALSA] 2094 snd-nm256= [HW,ALSA]
2083 2095
2084 snd-opl3sa2= [HW,ALSA] 2096 snd-opl3sa2= [HW,ALSA]
2085 2097
2086 snd-opti92x-ad1848= 2098 snd-opti92x-ad1848=
2087 [HW,ALSA] 2099 [HW,ALSA]
2088 2100
2089 snd-opti92x-cs4231= 2101 snd-opti92x-cs4231=
2090 [HW,ALSA] 2102 [HW,ALSA]
2091 2103
2092 snd-opti93x= [HW,ALSA] 2104 snd-opti93x= [HW,ALSA]
2093 2105
2094 snd-pmac= [HW,ALSA] 2106 snd-pmac= [HW,ALSA]
2095 2107
2096 snd-rme32= [HW,ALSA] 2108 snd-rme32= [HW,ALSA]
2097 2109
2098 snd-rme96= [HW,ALSA] 2110 snd-rme96= [HW,ALSA]
2099 2111
2100 snd-rme9652= [HW,ALSA] 2112 snd-rme9652= [HW,ALSA]
2101 2113
2102 snd-sb8= [HW,ALSA] 2114 snd-sb8= [HW,ALSA]
2103 2115
2104 snd-sb16= [HW,ALSA] 2116 snd-sb16= [HW,ALSA]
2105 2117
2106 snd-sbawe= [HW,ALSA] 2118 snd-sbawe= [HW,ALSA]
2107 2119
2108 snd-serial= [HW,ALSA] 2120 snd-serial= [HW,ALSA]
2109 2121
2110 snd-sgalaxy= [HW,ALSA] 2122 snd-sgalaxy= [HW,ALSA]
2111 2123
2112 snd-sonicvibes= [HW,ALSA] 2124 snd-sonicvibes= [HW,ALSA]
2113 2125
2114 snd-sun-amd7930= 2126 snd-sun-amd7930=
2115 [HW,ALSA] 2127 [HW,ALSA]
2116 2128
2117 snd-sun-cs4231= [HW,ALSA] 2129 snd-sun-cs4231= [HW,ALSA]
2118 2130
2119 snd-trident= [HW,ALSA] 2131 snd-trident= [HW,ALSA]
2120 2132
2121 snd-usb-audio= [HW,ALSA,USB] 2133 snd-usb-audio= [HW,ALSA,USB]
2122 2134
2123 snd-via82xx= [HW,ALSA] 2135 snd-via82xx= [HW,ALSA]
2124 2136
2125 snd-virmidi= [HW,ALSA] 2137 snd-virmidi= [HW,ALSA]
2126 2138
2127 snd-wavefront= [HW,ALSA] 2139 snd-wavefront= [HW,ALSA]
2128 2140
2129 snd-ymfpci= [HW,ALSA] 2141 snd-ymfpci= [HW,ALSA]
2130 2142
2131 softlockup_panic= 2143 softlockup_panic=
2132 [KNL] Should the soft-lockup detector generate panics. 2144 [KNL] Should the soft-lockup detector generate panics.
2133 2145
2134 sonypi.*= [HW] Sony Programmable I/O Control Device driver 2146 sonypi.*= [HW] Sony Programmable I/O Control Device driver
2135 See Documentation/sonypi.txt 2147 See Documentation/sonypi.txt
2136 2148
2137 specialix= [HW,SERIAL] Specialix multi-serial port adapter 2149 specialix= [HW,SERIAL] Specialix multi-serial port adapter
2138 See Documentation/specialix.txt. 2150 See Documentation/specialix.txt.
2139 2151
2140 spia_io_base= [HW,MTD] 2152 spia_io_base= [HW,MTD]
2141 spia_fio_base= 2153 spia_fio_base=
2142 spia_pedr= 2154 spia_pedr=
2143 spia_peddr= 2155 spia_peddr=
2144 2156
2145 sscape= [HW,OSS] 2157 sscape= [HW,OSS]
2146 Format: <io>,<irq>,<dma>,<mpu_io>,<mpu_irq> 2158 Format: <io>,<irq>,<dma>,<mpu_io>,<mpu_irq>
2147 2159
2148 st= [HW,SCSI] SCSI tape parameters (buffers, etc.) 2160 st= [HW,SCSI] SCSI tape parameters (buffers, etc.)
2149 See Documentation/scsi/st.txt. 2161 See Documentation/scsi/st.txt.
2150 2162
2151 sti= [PARISC,HW] 2163 sti= [PARISC,HW]
2152 Format: <num> 2164 Format: <num>
2153 Set the STI (builtin display/keyboard on the HP-PARISC 2165 Set the STI (builtin display/keyboard on the HP-PARISC
2154 machines) console (graphic card) which should be used 2166 machines) console (graphic card) which should be used
2155 as the initial boot-console. 2167 as the initial boot-console.
2156 See also comment in drivers/video/console/sticore.c. 2168 See also comment in drivers/video/console/sticore.c.
2157 2169
2158 sti_font= [HW] 2170 sti_font= [HW]
2159 See comment in drivers/video/console/sticore.c. 2171 See comment in drivers/video/console/sticore.c.
2160 2172
2161 stifb= [HW] 2173 stifb= [HW]
2162 Format: bpp:<bpp1>[:<bpp2>[:<bpp3>...]] 2174 Format: bpp:<bpp1>[:<bpp2>[:<bpp3>...]]
2163 2175
2164 sunrpc.pool_mode= 2176 sunrpc.pool_mode=
2165 [NFS] 2177 [NFS]
2166 Control how the NFS server code allocates CPUs to 2178 Control how the NFS server code allocates CPUs to
2167 service thread pools. Depending on how many NICs 2179 service thread pools. Depending on how many NICs
2168 you have and where their interrupts are bound, this 2180 you have and where their interrupts are bound, this
2169 option will affect which CPUs will do NFS serving. 2181 option will affect which CPUs will do NFS serving.
2170 Note: this parameter cannot be changed while the 2182 Note: this parameter cannot be changed while the
2171 NFS server is running. 2183 NFS server is running.
2172 2184
2173 auto the server chooses an appropriate mode 2185 auto the server chooses an appropriate mode
2174 automatically using heuristics 2186 automatically using heuristics
2175 global a single global pool contains all CPUs 2187 global a single global pool contains all CPUs
2176 percpu one pool for each CPU 2188 percpu one pool for each CPU
2177 pernode one pool for each NUMA node (equivalent 2189 pernode one pool for each NUMA node (equivalent
2178 to global on non-NUMA machines) 2190 to global on non-NUMA machines)
2179 2191
2180 swiotlb= [IA-64] Number of I/O TLB slabs 2192 swiotlb= [IA-64] Number of I/O TLB slabs
2181 2193
2182 switches= [HW,M68k] 2194 switches= [HW,M68k]
2183 2195
2184 sym53c416= [HW,SCSI] 2196 sym53c416= [HW,SCSI]
2185 See header of drivers/scsi/sym53c416.c. 2197 See header of drivers/scsi/sym53c416.c.
2186 2198
2187 sysrq_always_enabled 2199 sysrq_always_enabled
2188 [KNL] 2200 [KNL]
2189 Ignore sysrq setting - this boot parameter will 2201 Ignore sysrq setting - this boot parameter will
2190 neutralize any effect of /proc/sys/kernel/sysrq. 2202 neutralize any effect of /proc/sys/kernel/sysrq.
2191 Useful for debugging. 2203 Useful for debugging.
2192 2204
2193 t128= [HW,SCSI] 2205 t128= [HW,SCSI]
2194 See header of drivers/scsi/t128.c. 2206 See header of drivers/scsi/t128.c.
2195 2207
2196 tdfx= [HW,DRM] 2208 tdfx= [HW,DRM]
2197 2209
2198 test_suspend= [SUSPEND] 2210 test_suspend= [SUSPEND]
2199 Specify "mem" (for Suspend-to-RAM) or "standby" (for 2211 Specify "mem" (for Suspend-to-RAM) or "standby" (for
2200 standby suspend) as the system sleep state to briefly 2212 standby suspend) as the system sleep state to briefly
2201 enter during system startup. The system is woken from 2213 enter during system startup. The system is woken from
2202 this state using a wakeup-capable RTC alarm. 2214 this state using a wakeup-capable RTC alarm.
2203 2215
2204 thash_entries= [KNL,NET] 2216 thash_entries= [KNL,NET]
2205 Set number of hash buckets for TCP connection 2217 Set number of hash buckets for TCP connection
2206 2218
2207 thermal.act= [HW,ACPI] 2219 thermal.act= [HW,ACPI]
2208 -1: disable all active trip points in all thermal zones 2220 -1: disable all active trip points in all thermal zones
2209 <degrees C>: override all lowest active trip points 2221 <degrees C>: override all lowest active trip points
2210 2222
2211 thermal.crt= [HW,ACPI] 2223 thermal.crt= [HW,ACPI]
2212 -1: disable all critical trip points in all thermal zones 2224 -1: disable all critical trip points in all thermal zones
2213 <degrees C>: override all critical trip points 2225 <degrees C>: override all critical trip points
2214 2226
2215 thermal.nocrt= [HW,ACPI] 2227 thermal.nocrt= [HW,ACPI]
2216 Set to disable actions on ACPI thermal zone 2228 Set to disable actions on ACPI thermal zone
2217 critical and hot trip points. 2229 critical and hot trip points.
2218 2230
2219 thermal.off= [HW,ACPI] 2231 thermal.off= [HW,ACPI]
2220 1: disable ACPI thermal control 2232 1: disable ACPI thermal control
2221 2233
2222 thermal.psv= [HW,ACPI] 2234 thermal.psv= [HW,ACPI]
2223 -1: disable all passive trip points 2235 -1: disable all passive trip points
2224 <degrees C>: override all passive trip points to this value 2236 <degrees C>: override all passive trip points to this value
2225 2237
2226 thermal.tzp= [HW,ACPI] 2238 thermal.tzp= [HW,ACPI]
2227 Specify global default ACPI thermal zone polling rate 2239 Specify global default ACPI thermal zone polling rate
2228 <deci-seconds>: poll all this frequency 2240 <deci-seconds>: poll all this frequency
2229 0: no polling (default) 2241 0: no polling (default)
2230 2242
2231 tmscsim= [HW,SCSI] 2243 tmscsim= [HW,SCSI]
2232 See comment before function dc390_setup() in 2244 See comment before function dc390_setup() in
2233 drivers/scsi/tmscsim.c. 2245 drivers/scsi/tmscsim.c.
2234 2246
2235 tp720= [HW,PS2] 2247 tp720= [HW,PS2]
2236 2248
2237 trix= [HW,OSS] MediaTrix AudioTrix Pro 2249 trix= [HW,OSS] MediaTrix AudioTrix Pro
2238 Format: 2250 Format:
2239 <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq> 2251 <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
2240 2252
2241 turbografx.map[2|3]= [HW,JOY] 2253 turbografx.map[2|3]= [HW,JOY]
2242 TurboGraFX parallel port interface 2254 TurboGraFX parallel port interface
2243 Format: 2255 Format:
2244 <port#>,<js1>,<js2>,<js3>,<js4>,<js5>,<js6>,<js7> 2256 <port#>,<js1>,<js2>,<js3>,<js4>,<js5>,<js6>,<js7>
2245 See also Documentation/input/joystick-parport.txt 2257 See also Documentation/input/joystick-parport.txt
2246 2258
2247 u14-34f= [HW,SCSI] UltraStor 14F/34F SCSI host adapter 2259 u14-34f= [HW,SCSI] UltraStor 14F/34F SCSI host adapter
2248 See header of drivers/scsi/u14-34f.c. 2260 See header of drivers/scsi/u14-34f.c.
2249 2261
2250 uart401= [HW,OSS] 2262 uart401= [HW,OSS]
2251 Format: <io>,<irq> 2263 Format: <io>,<irq>
2252 2264
2253 uart6850= [HW,OSS] 2265 uart6850= [HW,OSS]
2254 Format: <io>,<irq> 2266 Format: <io>,<irq>
2255 2267
2256 uhci-hcd.ignore_oc= 2268 uhci-hcd.ignore_oc=
2257 [USB] Ignore overcurrent events (default N). 2269 [USB] Ignore overcurrent events (default N).
2258 Some badly-designed motherboards generate lots of 2270 Some badly-designed motherboards generate lots of
2259 bogus events, for ports that aren't wired to 2271 bogus events, for ports that aren't wired to
2260 anything. Set this parameter to avoid log spamming. 2272 anything. Set this parameter to avoid log spamming.
2261 Note that genuine overcurrent events won't be 2273 Note that genuine overcurrent events won't be
2262 reported either. 2274 reported either.
2263 2275
2264 unknown_nmi_panic 2276 unknown_nmi_panic
2265 [X86-32,X86-64] 2277 [X86-32,X86-64]
2266 Set unknown_nmi_panic=1 early on boot. 2278 Set unknown_nmi_panic=1 early on boot.
2267 2279
2268 usbcore.autosuspend= 2280 usbcore.autosuspend=
2269 [USB] The autosuspend time delay (in seconds) used 2281 [USB] The autosuspend time delay (in seconds) used
2270 for newly-detected USB devices (default 2). This 2282 for newly-detected USB devices (default 2). This
2271 is the time required before an idle device will be 2283 is the time required before an idle device will be
2272 autosuspended. Devices for which the delay is set 2284 autosuspended. Devices for which the delay is set
2273 to a negative value won't be autosuspended at all. 2285 to a negative value won't be autosuspended at all.
2274 2286
2275 usbcore.usbfs_snoop= 2287 usbcore.usbfs_snoop=
2276 [USB] Set to log all usbfs traffic (default 0 = off). 2288 [USB] Set to log all usbfs traffic (default 0 = off).
2277 2289
2278 usbcore.blinkenlights= 2290 usbcore.blinkenlights=
2279 [USB] Set to cycle leds on hubs (default 0 = off). 2291 [USB] Set to cycle leds on hubs (default 0 = off).
2280 2292
2281 usbcore.old_scheme_first= 2293 usbcore.old_scheme_first=
2282 [USB] Start with the old device initialization 2294 [USB] Start with the old device initialization
2283 scheme (default 0 = off). 2295 scheme (default 0 = off).
2284 2296
2285 usbcore.use_both_schemes= 2297 usbcore.use_both_schemes=
2286 [USB] Try the other device initialization scheme 2298 [USB] Try the other device initialization scheme
2287 if the first one fails (default 1 = enabled). 2299 if the first one fails (default 1 = enabled).
2288 2300
2289 usbcore.initial_descriptor_timeout= 2301 usbcore.initial_descriptor_timeout=
2290 [USB] Specifies timeout for the initial 64-byte 2302 [USB] Specifies timeout for the initial 64-byte
2291 USB_REQ_GET_DESCRIPTOR request in milliseconds 2303 USB_REQ_GET_DESCRIPTOR request in milliseconds
2292 (default 5000 = 5.0 seconds). 2304 (default 5000 = 5.0 seconds).
2293 2305
2294 usbhid.mousepoll= 2306 usbhid.mousepoll=
2295 [USBHID] The interval which mice are to be polled at. 2307 [USBHID] The interval which mice are to be polled at.
2296 2308
2297 add_efi_memmap [EFI; x86-32,X86-64] Include EFI memory map in 2309 add_efi_memmap [EFI; x86-32,X86-64] Include EFI memory map in
2298 kernel's map of available physical RAM. 2310 kernel's map of available physical RAM.
2299 2311
2300 vdso= [X86-32,SH,x86-64] 2312 vdso= [X86-32,SH,x86-64]
2301 vdso=2: enable compat VDSO (default with COMPAT_VDSO) 2313 vdso=2: enable compat VDSO (default with COMPAT_VDSO)
2302 vdso=1: enable VDSO (default) 2314 vdso=1: enable VDSO (default)
2303 vdso=0: disable VDSO mapping 2315 vdso=0: disable VDSO mapping
2304 2316
2305 vdso32= [X86-32,X86-64] 2317 vdso32= [X86-32,X86-64]
2306 vdso32=2: enable compat VDSO (default with COMPAT_VDSO) 2318 vdso32=2: enable compat VDSO (default with COMPAT_VDSO)
2307 vdso32=1: enable 32-bit VDSO (default) 2319 vdso32=1: enable 32-bit VDSO (default)
2308 vdso32=0: disable 32-bit VDSO mapping 2320 vdso32=0: disable 32-bit VDSO mapping
2309 2321
2310 vector= [IA-64,SMP] 2322 vector= [IA-64,SMP]
2311 vector=percpu: enable percpu vector domain 2323 vector=percpu: enable percpu vector domain
2312 2324
2313 video= [FB] Frame buffer configuration 2325 video= [FB] Frame buffer configuration
2314 See Documentation/fb/modedb.txt. 2326 See Documentation/fb/modedb.txt.
2315 2327
2316 vga= [BOOT,X86-32] Select a particular video mode 2328 vga= [BOOT,X86-32] Select a particular video mode
2317 See Documentation/x86/i386/boot.txt and 2329 See Documentation/x86/i386/boot.txt and
2318 Documentation/svga.txt. 2330 Documentation/svga.txt.
2319 Use vga=ask for menu. 2331 Use vga=ask for menu.
2320 This is actually a boot loader parameter; the value is 2332 This is actually a boot loader parameter; the value is
2321 passed to the kernel using a special protocol. 2333 passed to the kernel using a special protocol.
2322 2334
2323 vmalloc=nn[KMG] [KNL,BOOT] Forces the vmalloc area to have an exact 2335 vmalloc=nn[KMG] [KNL,BOOT] Forces the vmalloc area to have an exact
2324 size of <nn>. This can be used to increase the 2336 size of <nn>. This can be used to increase the
2325 minimum size (128MB on x86). It can also be used to 2337 minimum size (128MB on x86). It can also be used to
2326 decrease the size and leave more room for directly 2338 decrease the size and leave more room for directly
2327 mapped kernel RAM. 2339 mapped kernel RAM.
2328 2340
2329 vmhalt= [KNL,S390] Perform z/VM CP command after system halt. 2341 vmhalt= [KNL,S390] Perform z/VM CP command after system halt.
2330 Format: <command> 2342 Format: <command>
2331 2343
2332 vmpanic= [KNL,S390] Perform z/VM CP command after kernel panic. 2344 vmpanic= [KNL,S390] Perform z/VM CP command after kernel panic.
2333 Format: <command> 2345 Format: <command>
2334 2346
2335 vmpoff= [KNL,S390] Perform z/VM CP command after power off. 2347 vmpoff= [KNL,S390] Perform z/VM CP command after power off.
2336 Format: <command> 2348 Format: <command>
2337 2349
2338 waveartist= [HW,OSS] 2350 waveartist= [HW,OSS]
2339 Format: <io>,<irq>,<dma>,<dma2> 2351 Format: <io>,<irq>,<dma>,<dma2>
2340 2352
2341 wd33c93= [HW,SCSI] 2353 wd33c93= [HW,SCSI]
2342 See header of drivers/scsi/wd33c93.c. 2354 See header of drivers/scsi/wd33c93.c.
2343 2355
2344 wd7000= [HW,SCSI] 2356 wd7000= [HW,SCSI]
2345 See header of drivers/scsi/wd7000.c. 2357 See header of drivers/scsi/wd7000.c.
2346 2358
2347 wdt= [WDT] Watchdog 2359 wdt= [WDT] Watchdog
2348 See Documentation/watchdog/wdt.txt. 2360 See Documentation/watchdog/wdt.txt.
2349 2361
2350 xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks. 2362 xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks.
2351 xd_geo= See header of drivers/block/xd.c. 2363 xd_geo= See header of drivers/block/xd.c.
2352 2364
2353 xirc2ps_cs= [NET,PCMCIA] 2365 xirc2ps_cs= [NET,PCMCIA]
2354 Format: 2366 Format:
2355 <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]] 2367 <irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
2356 2368
2357 norandmaps Don't use address space randomization 2369 norandmaps Don't use address space randomization
2358 Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space 2370 Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space
2359 2371
2360 ______________________________________________________________________ 2372 ______________________________________________________________________
2361 2373
2362 TODO: 2374 TODO:
2363 2375
2364 Add documentation for ALSA options. 2376 Add documentation for ALSA options.
2365 Add more DRM drivers. 2377 Add more DRM drivers.
2366 2378
drivers/acpi/Makefile
1 # 1 #
2 # Makefile for the Linux ACPI interpreter 2 # Makefile for the Linux ACPI interpreter
3 # 3 #
4 4
5 export ACPI_CFLAGS 5 export ACPI_CFLAGS
6 6
7 ACPI_CFLAGS := -Os 7 ACPI_CFLAGS := -Os
8 8
9 ifdef CONFIG_ACPI_DEBUG 9 ifdef CONFIG_ACPI_DEBUG
10 ACPI_CFLAGS += -DACPI_DEBUG_OUTPUT 10 ACPI_CFLAGS += -DACPI_DEBUG_OUTPUT
11 endif 11 endif
12 12
13 EXTRA_CFLAGS += $(ACPI_CFLAGS) 13 EXTRA_CFLAGS += $(ACPI_CFLAGS)
14 14
15 # 15 #
16 # ACPI Boot-Time Table Parsing 16 # ACPI Boot-Time Table Parsing
17 # 17 #
18 obj-y += tables.o 18 obj-y += tables.o
19 obj-$(CONFIG_X86) += blacklist.o 19 obj-$(CONFIG_X86) += blacklist.o
20 20
21 # 21 #
22 # ACPI Core Subsystem (Interpreter) 22 # ACPI Core Subsystem (Interpreter)
23 # 23 #
24 obj-y += osl.o utils.o reboot.o\ 24 obj-y += osl.o utils.o reboot.o\
25 dispatcher/ events/ executer/ hardware/ \ 25 dispatcher/ events/ executer/ hardware/ \
26 namespace/ parser/ resources/ tables/ \ 26 namespace/ parser/ resources/ tables/ \
27 utilities/ 27 utilities/
28 28
29 # 29 #
30 # ACPI Bus and Device Drivers 30 # ACPI Bus and Device Drivers
31 # 31 #
32 processor-objs += processor_core.o processor_throttling.o \ 32 processor-objs += processor_core.o processor_throttling.o \
33 processor_idle.o processor_thermal.o 33 processor_idle.o processor_thermal.o
34 ifdef CONFIG_CPU_FREQ 34 ifdef CONFIG_CPU_FREQ
35 processor-objs += processor_perflib.o 35 processor-objs += processor_perflib.o
36 endif 36 endif
37 37
38 obj-y += sleep/ 38 obj-y += sleep/
39 obj-y += bus.o glue.o 39 obj-y += bus.o glue.o
40 obj-y += scan.o 40 obj-y += scan.o
41 # Keep EC driver first. Initialization of others depend on it. 41 # Keep EC driver first. Initialization of others depend on it.
42 obj-y += ec.o 42 obj-y += ec.o
43 obj-$(CONFIG_ACPI_AC) += ac.o 43 obj-$(CONFIG_ACPI_AC) += ac.o
44 obj-$(CONFIG_ACPI_BATTERY) += battery.o 44 obj-$(CONFIG_ACPI_BATTERY) += battery.o
45 obj-$(CONFIG_ACPI_BUTTON) += button.o 45 obj-$(CONFIG_ACPI_BUTTON) += button.o
46 obj-$(CONFIG_ACPI_FAN) += fan.o 46 obj-$(CONFIG_ACPI_FAN) += fan.o
47 obj-$(CONFIG_ACPI_DOCK) += dock.o 47 obj-$(CONFIG_ACPI_DOCK) += dock.o
48 obj-$(CONFIG_ACPI_VIDEO) += video.o 48 obj-$(CONFIG_ACPI_VIDEO) += video.o
49 ifdef CONFIG_ACPI_VIDEO
50 obj-y += video_detect.o
51 endif
52
49 obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o 53 obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
50 obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o 54 obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
51 obj-$(CONFIG_ACPI_PROCESSOR) += processor.o 55 obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
52 obj-$(CONFIG_ACPI_CONTAINER) += container.o 56 obj-$(CONFIG_ACPI_CONTAINER) += container.o
53 obj-$(CONFIG_ACPI_THERMAL) += thermal.o 57 obj-$(CONFIG_ACPI_THERMAL) += thermal.o
54 obj-y += power.o 58 obj-y += power.o
55 obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o 59 obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o
56 obj-$(CONFIG_ACPI_DEBUG) += debug.o 60 obj-$(CONFIG_ACPI_DEBUG) += debug.o
57 obj-$(CONFIG_ACPI_NUMA) += numa.o 61 obj-$(CONFIG_ACPI_NUMA) += numa.o
58 obj-$(CONFIG_ACPI_WMI) += wmi.o 62 obj-$(CONFIG_ACPI_WMI) += wmi.o
59 obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o 63 obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
60 obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o 64 obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
61 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o 65 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
62 obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o 66 obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
63 obj-$(CONFIG_ACPI_SBS) += sbshc.o 67 obj-$(CONFIG_ACPI_SBS) += sbshc.o
64 obj-$(CONFIG_ACPI_SBS) += sbs.o 68 obj-$(CONFIG_ACPI_SBS) += sbs.o
65 69
1 /* 1 /*
2 * Link physical devices with ACPI devices support 2 * Link physical devices with ACPI devices support
3 * 3 *
4 * Copyright (c) 2005 David Shaohua Li <shaohua.li@intel.com> 4 * Copyright (c) 2005 David Shaohua Li <shaohua.li@intel.com>
5 * Copyright (c) 2005 Intel Corp. 5 * Copyright (c) 2005 Intel Corp.
6 * 6 *
7 * This file is released under the GPLv2. 7 * This file is released under the GPLv2.
8 */ 8 */
9 #include <linux/init.h> 9 #include <linux/init.h>
10 #include <linux/list.h> 10 #include <linux/list.h>
11 #include <linux/device.h> 11 #include <linux/device.h>
12 #include <linux/rwsem.h> 12 #include <linux/rwsem.h>
13 #include <linux/acpi.h> 13 #include <linux/acpi.h>
14 14
15 #define ACPI_GLUE_DEBUG 0 15 #define ACPI_GLUE_DEBUG 0
16 #if ACPI_GLUE_DEBUG 16 #if ACPI_GLUE_DEBUG
17 #define DBG(x...) printk(PREFIX x) 17 #define DBG(x...) printk(PREFIX x)
18 #else 18 #else
19 #define DBG(x...) do { } while(0) 19 #define DBG(x...) do { } while(0)
20 #endif 20 #endif
21 static LIST_HEAD(bus_type_list); 21 static LIST_HEAD(bus_type_list);
22 static DECLARE_RWSEM(bus_type_sem); 22 static DECLARE_RWSEM(bus_type_sem);
23 23
24 int register_acpi_bus_type(struct acpi_bus_type *type) 24 int register_acpi_bus_type(struct acpi_bus_type *type)
25 { 25 {
26 if (acpi_disabled) 26 if (acpi_disabled)
27 return -ENODEV; 27 return -ENODEV;
28 if (type && type->bus && type->find_device) { 28 if (type && type->bus && type->find_device) {
29 down_write(&bus_type_sem); 29 down_write(&bus_type_sem);
30 list_add_tail(&type->list, &bus_type_list); 30 list_add_tail(&type->list, &bus_type_list);
31 up_write(&bus_type_sem); 31 up_write(&bus_type_sem);
32 printk(KERN_INFO PREFIX "bus type %s registered\n", 32 printk(KERN_INFO PREFIX "bus type %s registered\n",
33 type->bus->name); 33 type->bus->name);
34 return 0; 34 return 0;
35 } 35 }
36 return -ENODEV; 36 return -ENODEV;
37 } 37 }
38 38
39 int unregister_acpi_bus_type(struct acpi_bus_type *type) 39 int unregister_acpi_bus_type(struct acpi_bus_type *type)
40 { 40 {
41 if (acpi_disabled) 41 if (acpi_disabled)
42 return 0; 42 return 0;
43 if (type) { 43 if (type) {
44 down_write(&bus_type_sem); 44 down_write(&bus_type_sem);
45 list_del_init(&type->list); 45 list_del_init(&type->list);
46 up_write(&bus_type_sem); 46 up_write(&bus_type_sem);
47 printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", 47 printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n",
48 type->bus->name); 48 type->bus->name);
49 return 0; 49 return 0;
50 } 50 }
51 return -ENODEV; 51 return -ENODEV;
52 } 52 }
53 53
54 static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) 54 static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
55 { 55 {
56 struct acpi_bus_type *tmp, *ret = NULL; 56 struct acpi_bus_type *tmp, *ret = NULL;
57 57
58 down_read(&bus_type_sem); 58 down_read(&bus_type_sem);
59 list_for_each_entry(tmp, &bus_type_list, list) { 59 list_for_each_entry(tmp, &bus_type_list, list) {
60 if (tmp->bus == type) { 60 if (tmp->bus == type) {
61 ret = tmp; 61 ret = tmp;
62 break; 62 break;
63 } 63 }
64 } 64 }
65 up_read(&bus_type_sem); 65 up_read(&bus_type_sem);
66 return ret; 66 return ret;
67 } 67 }
68 68
69 static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) 69 static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
70 { 70 {
71 struct acpi_bus_type *tmp; 71 struct acpi_bus_type *tmp;
72 int ret = -ENODEV; 72 int ret = -ENODEV;
73 73
74 down_read(&bus_type_sem); 74 down_read(&bus_type_sem);
75 list_for_each_entry(tmp, &bus_type_list, list) { 75 list_for_each_entry(tmp, &bus_type_list, list) {
76 if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) { 76 if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) {
77 ret = 0; 77 ret = 0;
78 break; 78 break;
79 } 79 }
80 } 80 }
81 up_read(&bus_type_sem); 81 up_read(&bus_type_sem);
82 return ret; 82 return ret;
83 } 83 }
84 84
85 /* Get device's handler per its address under its parent */ 85 /* Get device's handler per its address under its parent */
86 struct acpi_find_child { 86 struct acpi_find_child {
87 acpi_handle handle; 87 acpi_handle handle;
88 acpi_integer address; 88 acpi_integer address;
89 }; 89 };
90 90
91 static acpi_status 91 static acpi_status
92 do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) 92 do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
93 { 93 {
94 acpi_status status; 94 acpi_status status;
95 struct acpi_device_info *info; 95 struct acpi_device_info *info;
96 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 96 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
97 struct acpi_find_child *find = context; 97 struct acpi_find_child *find = context;
98 98
99 status = acpi_get_object_info(handle, &buffer); 99 status = acpi_get_object_info(handle, &buffer);
100 if (ACPI_SUCCESS(status)) { 100 if (ACPI_SUCCESS(status)) {
101 info = buffer.pointer; 101 info = buffer.pointer;
102 if (info->address == find->address) 102 if (info->address == find->address)
103 find->handle = handle; 103 find->handle = handle;
104 kfree(buffer.pointer); 104 kfree(buffer.pointer);
105 } 105 }
106 return AE_OK; 106 return AE_OK;
107 } 107 }
108 108
109 acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address) 109 acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address)
110 { 110 {
111 struct acpi_find_child find = { NULL, address }; 111 struct acpi_find_child find = { NULL, address };
112 112
113 if (!parent) 113 if (!parent)
114 return NULL; 114 return NULL;
115 acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 115 acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
116 1, do_acpi_find_child, &find, NULL); 116 1, do_acpi_find_child, &find, NULL);
117 return find.handle; 117 return find.handle;
118 } 118 }
119 119
120 EXPORT_SYMBOL(acpi_get_child); 120 EXPORT_SYMBOL(acpi_get_child);
121 121
122 /* Link ACPI devices with physical devices */ 122 /* Link ACPI devices with physical devices */
123 static void acpi_glue_data_handler(acpi_handle handle, 123 static void acpi_glue_data_handler(acpi_handle handle,
124 u32 function, void *context) 124 u32 function, void *context)
125 { 125 {
126 /* we provide an empty handler */ 126 /* we provide an empty handler */
127 } 127 }
128 128
129 /* Note: a success call will increase reference count by one */ 129 /* Note: a success call will increase reference count by one */
130 struct device *acpi_get_physical_device(acpi_handle handle) 130 struct device *acpi_get_physical_device(acpi_handle handle)
131 { 131 {
132 acpi_status status; 132 acpi_status status;
133 struct device *dev; 133 struct device *dev;
134 134
135 status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev); 135 status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev);
136 if (ACPI_SUCCESS(status)) 136 if (ACPI_SUCCESS(status))
137 return get_device(dev); 137 return get_device(dev);
138 return NULL; 138 return NULL;
139 } 139 }
140 140
141 EXPORT_SYMBOL(acpi_get_physical_device); 141 EXPORT_SYMBOL(acpi_get_physical_device);
142 142
143 /* ToDo: When a PCI bridge is found, return the PCI device behind the bridge
144 * This should work in general, but did not on a Lenovo T61 for the
145 * graphics card. But this must be fixed when the PCI device is
146 * bound and the kernel device struct is attached to the acpi device
147 * Note: A success call will increase reference count by one
148 * Do call put_device(dev) on the returned device then
149 */
150 struct device *acpi_get_physical_pci_device(acpi_handle handle)
151 {
152 struct device *dev;
153 long long device_id;
154 acpi_status status;
155
156 status =
157 acpi_evaluate_integer(handle, "_ADR", NULL, &device_id);
158
159 if (ACPI_FAILURE(status))
160 return NULL;
161
162 /* We need to attempt to determine whether the _ADR refers to a
163 PCI device or not. There's no terribly good way to do this,
164 so the best we can hope for is to assume that there'll never
165 be a device in the host bridge */
166 if (device_id >= 0x10000) {
167 /* It looks like a PCI device. Does it exist? */
168 dev = acpi_get_physical_device(handle);
169 } else {
170 /* It doesn't look like a PCI device. Does its parent
171 exist? */
172 acpi_handle phandle;
173 if (acpi_get_parent(handle, &phandle))
174 return NULL;
175 dev = acpi_get_physical_device(phandle);
176 }
177 if (!dev)
178 return NULL;
179 return dev;
180 }
181 EXPORT_SYMBOL(acpi_get_physical_pci_device);
182
143 static int acpi_bind_one(struct device *dev, acpi_handle handle) 183 static int acpi_bind_one(struct device *dev, acpi_handle handle)
144 { 184 {
145 struct acpi_device *acpi_dev; 185 struct acpi_device *acpi_dev;
146 acpi_status status; 186 acpi_status status;
147 187
148 if (dev->archdata.acpi_handle) { 188 if (dev->archdata.acpi_handle) {
149 dev_warn(dev, "Drivers changed 'acpi_handle'\n"); 189 dev_warn(dev, "Drivers changed 'acpi_handle'\n");
150 return -EINVAL; 190 return -EINVAL;
151 } 191 }
152 get_device(dev); 192 get_device(dev);
153 status = acpi_attach_data(handle, acpi_glue_data_handler, dev); 193 status = acpi_attach_data(handle, acpi_glue_data_handler, dev);
154 if (ACPI_FAILURE(status)) { 194 if (ACPI_FAILURE(status)) {
155 put_device(dev); 195 put_device(dev);
156 return -EINVAL; 196 return -EINVAL;
157 } 197 }
158 dev->archdata.acpi_handle = handle; 198 dev->archdata.acpi_handle = handle;
159 199
160 status = acpi_bus_get_device(handle, &acpi_dev); 200 status = acpi_bus_get_device(handle, &acpi_dev);
161 if (!ACPI_FAILURE(status)) { 201 if (!ACPI_FAILURE(status)) {
162 int ret; 202 int ret;
163 203
164 ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, 204 ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
165 "firmware_node"); 205 "firmware_node");
166 ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, 206 ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
167 "physical_node"); 207 "physical_node");
168 if (acpi_dev->wakeup.flags.valid) { 208 if (acpi_dev->wakeup.flags.valid) {
169 device_set_wakeup_capable(dev, true); 209 device_set_wakeup_capable(dev, true);
170 device_set_wakeup_enable(dev, 210 device_set_wakeup_enable(dev,
171 acpi_dev->wakeup.state.enabled); 211 acpi_dev->wakeup.state.enabled);
172 } 212 }
173 } 213 }
174 214
175 return 0; 215 return 0;
176 } 216 }
177 217
178 static int acpi_unbind_one(struct device *dev) 218 static int acpi_unbind_one(struct device *dev)
179 { 219 {
180 if (!dev->archdata.acpi_handle) 220 if (!dev->archdata.acpi_handle)
181 return 0; 221 return 0;
182 if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { 222 if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) {
183 struct acpi_device *acpi_dev; 223 struct acpi_device *acpi_dev;
184 224
185 /* acpi_get_physical_device increase refcnt by one */ 225 /* acpi_get_physical_device increase refcnt by one */
186 put_device(dev); 226 put_device(dev);
187 227
188 if (!acpi_bus_get_device(dev->archdata.acpi_handle, 228 if (!acpi_bus_get_device(dev->archdata.acpi_handle,
189 &acpi_dev)) { 229 &acpi_dev)) {
190 sysfs_remove_link(&dev->kobj, "firmware_node"); 230 sysfs_remove_link(&dev->kobj, "firmware_node");
191 sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node"); 231 sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node");
192 } 232 }
193 233
194 acpi_detach_data(dev->archdata.acpi_handle, 234 acpi_detach_data(dev->archdata.acpi_handle,
195 acpi_glue_data_handler); 235 acpi_glue_data_handler);
196 dev->archdata.acpi_handle = NULL; 236 dev->archdata.acpi_handle = NULL;
197 /* acpi_bind_one increase refcnt by one */ 237 /* acpi_bind_one increase refcnt by one */
198 put_device(dev); 238 put_device(dev);
199 } else { 239 } else {
200 dev_err(dev, "Oops, 'acpi_handle' corrupt\n"); 240 dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
201 } 241 }
202 return 0; 242 return 0;
203 } 243 }
204 244
205 static int acpi_platform_notify(struct device *dev) 245 static int acpi_platform_notify(struct device *dev)
206 { 246 {
207 struct acpi_bus_type *type; 247 struct acpi_bus_type *type;
208 acpi_handle handle; 248 acpi_handle handle;
209 int ret = -EINVAL; 249 int ret = -EINVAL;
210 250
211 if (!dev->bus || !dev->parent) { 251 if (!dev->bus || !dev->parent) {
212 /* bridge devices genernally haven't bus or parent */ 252 /* bridge devices genernally haven't bus or parent */
213 ret = acpi_find_bridge_device(dev, &handle); 253 ret = acpi_find_bridge_device(dev, &handle);
214 goto end; 254 goto end;
215 } 255 }
216 type = acpi_get_bus_type(dev->bus); 256 type = acpi_get_bus_type(dev->bus);
217 if (!type) { 257 if (!type) {
218 DBG("No ACPI bus support for %s\n", dev->bus_id); 258 DBG("No ACPI bus support for %s\n", dev->bus_id);
219 ret = -EINVAL; 259 ret = -EINVAL;
220 goto end; 260 goto end;
221 } 261 }
222 if ((ret = type->find_device(dev, &handle)) != 0) 262 if ((ret = type->find_device(dev, &handle)) != 0)
223 DBG("Can't get handler for %s\n", dev->bus_id); 263 DBG("Can't get handler for %s\n", dev->bus_id);
224 end: 264 end:
225 if (!ret) 265 if (!ret)
226 acpi_bind_one(dev, handle); 266 acpi_bind_one(dev, handle);
227 267
228 #if ACPI_GLUE_DEBUG 268 #if ACPI_GLUE_DEBUG
229 if (!ret) { 269 if (!ret) {
230 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 270 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
231 271
232 acpi_get_name(dev->archdata.acpi_handle, 272 acpi_get_name(dev->archdata.acpi_handle,
233 ACPI_FULL_PATHNAME, &buffer); 273 ACPI_FULL_PATHNAME, &buffer);
234 DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); 274 DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer);
235 kfree(buffer.pointer); 275 kfree(buffer.pointer);
236 } else 276 } else
237 DBG("Device %s -> No ACPI support\n", dev->bus_id); 277 DBG("Device %s -> No ACPI support\n", dev->bus_id);
238 #endif 278 #endif
239 279
240 return ret; 280 return ret;
241 } 281 }
242 282
243 static int acpi_platform_notify_remove(struct device *dev) 283 static int acpi_platform_notify_remove(struct device *dev)
244 { 284 {
245 acpi_unbind_one(dev); 285 acpi_unbind_one(dev);
246 return 0; 286 return 0;
247 } 287 }
248 288
249 static int __init init_acpi_device_notify(void) 289 static int __init init_acpi_device_notify(void)
250 { 290 {
251 if (acpi_disabled) 291 if (acpi_disabled)
252 return 0; 292 return 0;
253 if (platform_notify || platform_notify_remove) { 293 if (platform_notify || platform_notify_remove) {
254 printk(KERN_ERR PREFIX "Can't use platform_notify\n"); 294 printk(KERN_ERR PREFIX "Can't use platform_notify\n");
255 return 0; 295 return 0;
256 } 296 }
257 platform_notify = acpi_platform_notify; 297 platform_notify = acpi_platform_notify;
258 platform_notify_remove = acpi_platform_notify_remove; 298 platform_notify_remove = acpi_platform_notify_remove;
259 return 0; 299 return 0;
260 } 300 }
261 301
262 arch_initcall(init_acpi_device_notify); 302 arch_initcall(init_acpi_device_notify);
263 303
1 /* 1 /*
2 * scan.c - support for transforming the ACPI namespace into individual objects 2 * scan.c - support for transforming the ACPI namespace into individual objects
3 */ 3 */
4 4
5 #include <linux/module.h> 5 #include <linux/module.h>
6 #include <linux/init.h> 6 #include <linux/init.h>
7 #include <linux/kernel.h> 7 #include <linux/kernel.h>
8 #include <linux/acpi.h> 8 #include <linux/acpi.h>
9 #include <linux/signal.h> 9 #include <linux/signal.h>
10 #include <linux/kthread.h> 10 #include <linux/kthread.h>
11 11
12 #include <acpi/acpi_drivers.h> 12 #include <acpi/acpi_drivers.h>
13 #include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */ 13 #include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */
14 14
15 #define _COMPONENT ACPI_BUS_COMPONENT 15 #define _COMPONENT ACPI_BUS_COMPONENT
16 ACPI_MODULE_NAME("scan"); 16 ACPI_MODULE_NAME("scan");
17 #define STRUCT_TO_INT(s) (*((int*)&s)) 17 #define STRUCT_TO_INT(s) (*((int*)&s))
18 extern struct acpi_device *acpi_root; 18 extern struct acpi_device *acpi_root;
19 19
20 #define ACPI_BUS_CLASS "system_bus" 20 #define ACPI_BUS_CLASS "system_bus"
21 #define ACPI_BUS_HID "LNXSYBUS" 21 #define ACPI_BUS_HID "LNXSYBUS"
22 #define ACPI_BUS_DEVICE_NAME "System Bus" 22 #define ACPI_BUS_DEVICE_NAME "System Bus"
23 23
24 static LIST_HEAD(acpi_device_list); 24 static LIST_HEAD(acpi_device_list);
25 static LIST_HEAD(acpi_bus_id_list); 25 static LIST_HEAD(acpi_bus_id_list);
26 DEFINE_SPINLOCK(acpi_device_lock); 26 DEFINE_SPINLOCK(acpi_device_lock);
27 LIST_HEAD(acpi_wakeup_device_list); 27 LIST_HEAD(acpi_wakeup_device_list);
28 28
29 struct acpi_device_bus_id{ 29 struct acpi_device_bus_id{
30 char bus_id[15]; 30 char bus_id[15];
31 unsigned int instance_no; 31 unsigned int instance_no;
32 struct list_head node; 32 struct list_head node;
33 }; 33 };
34 34
35 /* 35 /*
36 * Creates hid/cid(s) string needed for modalias and uevent 36 * Creates hid/cid(s) string needed for modalias and uevent
37 * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: 37 * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
38 * char *modalias: "acpi:IBM0001:ACPI0001" 38 * char *modalias: "acpi:IBM0001:ACPI0001"
39 */ 39 */
40 static int create_modalias(struct acpi_device *acpi_dev, char *modalias, 40 static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
41 int size) 41 int size)
42 { 42 {
43 int len; 43 int len;
44 int count; 44 int count;
45 45
46 if (!acpi_dev->flags.hardware_id && !acpi_dev->flags.compatible_ids) 46 if (!acpi_dev->flags.hardware_id && !acpi_dev->flags.compatible_ids)
47 return -ENODEV; 47 return -ENODEV;
48 48
49 len = snprintf(modalias, size, "acpi:"); 49 len = snprintf(modalias, size, "acpi:");
50 size -= len; 50 size -= len;
51 51
52 if (acpi_dev->flags.hardware_id) { 52 if (acpi_dev->flags.hardware_id) {
53 count = snprintf(&modalias[len], size, "%s:", 53 count = snprintf(&modalias[len], size, "%s:",
54 acpi_dev->pnp.hardware_id); 54 acpi_dev->pnp.hardware_id);
55 if (count < 0 || count >= size) 55 if (count < 0 || count >= size)
56 return -EINVAL; 56 return -EINVAL;
57 len += count; 57 len += count;
58 size -= count; 58 size -= count;
59 } 59 }
60 60
61 if (acpi_dev->flags.compatible_ids) { 61 if (acpi_dev->flags.compatible_ids) {
62 struct acpi_compatible_id_list *cid_list; 62 struct acpi_compatible_id_list *cid_list;
63 int i; 63 int i;
64 64
65 cid_list = acpi_dev->pnp.cid_list; 65 cid_list = acpi_dev->pnp.cid_list;
66 for (i = 0; i < cid_list->count; i++) { 66 for (i = 0; i < cid_list->count; i++) {
67 count = snprintf(&modalias[len], size, "%s:", 67 count = snprintf(&modalias[len], size, "%s:",
68 cid_list->id[i].value); 68 cid_list->id[i].value);
69 if (count < 0 || count >= size) { 69 if (count < 0 || count >= size) {
70 printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size", 70 printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size",
71 acpi_dev->pnp.device_name, i); 71 acpi_dev->pnp.device_name, i);
72 break; 72 break;
73 } 73 }
74 len += count; 74 len += count;
75 size -= count; 75 size -= count;
76 } 76 }
77 } 77 }
78 78
79 modalias[len] = '\0'; 79 modalias[len] = '\0';
80 return len; 80 return len;
81 } 81 }
82 82
83 static ssize_t 83 static ssize_t
84 acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { 84 acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) {
85 struct acpi_device *acpi_dev = to_acpi_device(dev); 85 struct acpi_device *acpi_dev = to_acpi_device(dev);
86 int len; 86 int len;
87 87
88 /* Device has no HID and no CID or string is >1024 */ 88 /* Device has no HID and no CID or string is >1024 */
89 len = create_modalias(acpi_dev, buf, 1024); 89 len = create_modalias(acpi_dev, buf, 1024);
90 if (len <= 0) 90 if (len <= 0)
91 return 0; 91 return 0;
92 buf[len++] = '\n'; 92 buf[len++] = '\n';
93 return len; 93 return len;
94 } 94 }
95 static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); 95 static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
96 96
97 static int acpi_bus_hot_remove_device(void *context) 97 static int acpi_bus_hot_remove_device(void *context)
98 { 98 {
99 struct acpi_device *device; 99 struct acpi_device *device;
100 acpi_handle handle = context; 100 acpi_handle handle = context;
101 struct acpi_object_list arg_list; 101 struct acpi_object_list arg_list;
102 union acpi_object arg; 102 union acpi_object arg;
103 acpi_status status = AE_OK; 103 acpi_status status = AE_OK;
104 104
105 if (acpi_bus_get_device(handle, &device)) 105 if (acpi_bus_get_device(handle, &device))
106 return 0; 106 return 0;
107 107
108 if (!device) 108 if (!device)
109 return 0; 109 return 0;
110 110
111 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 111 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
112 "Hot-removing device %s...\n", dev_name(&device->dev))); 112 "Hot-removing device %s...\n", dev_name(&device->dev)));
113 113
114 if (acpi_bus_trim(device, 1)) { 114 if (acpi_bus_trim(device, 1)) {
115 printk(KERN_ERR PREFIX 115 printk(KERN_ERR PREFIX
116 "Removing device failed\n"); 116 "Removing device failed\n");
117 return -1; 117 return -1;
118 } 118 }
119 119
120 /* power off device */ 120 /* power off device */
121 status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); 121 status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
122 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) 122 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
123 printk(KERN_WARNING PREFIX 123 printk(KERN_WARNING PREFIX
124 "Power-off device failed\n"); 124 "Power-off device failed\n");
125 125
126 if (device->flags.lockable) { 126 if (device->flags.lockable) {
127 arg_list.count = 1; 127 arg_list.count = 1;
128 arg_list.pointer = &arg; 128 arg_list.pointer = &arg;
129 arg.type = ACPI_TYPE_INTEGER; 129 arg.type = ACPI_TYPE_INTEGER;
130 arg.integer.value = 0; 130 arg.integer.value = 0;
131 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL); 131 acpi_evaluate_object(handle, "_LCK", &arg_list, NULL);
132 } 132 }
133 133
134 arg_list.count = 1; 134 arg_list.count = 1;
135 arg_list.pointer = &arg; 135 arg_list.pointer = &arg;
136 arg.type = ACPI_TYPE_INTEGER; 136 arg.type = ACPI_TYPE_INTEGER;
137 arg.integer.value = 1; 137 arg.integer.value = 1;
138 138
139 /* 139 /*
140 * TBD: _EJD support. 140 * TBD: _EJD support.
141 */ 141 */
142 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); 142 status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
143 if (ACPI_FAILURE(status)) 143 if (ACPI_FAILURE(status))
144 return -ENODEV; 144 return -ENODEV;
145 145
146 return 0; 146 return 0;
147 } 147 }
148 148
149 static ssize_t 149 static ssize_t
150 acpi_eject_store(struct device *d, struct device_attribute *attr, 150 acpi_eject_store(struct device *d, struct device_attribute *attr,
151 const char *buf, size_t count) 151 const char *buf, size_t count)
152 { 152 {
153 int ret = count; 153 int ret = count;
154 acpi_status status; 154 acpi_status status;
155 acpi_object_type type = 0; 155 acpi_object_type type = 0;
156 struct acpi_device *acpi_device = to_acpi_device(d); 156 struct acpi_device *acpi_device = to_acpi_device(d);
157 struct task_struct *task; 157 struct task_struct *task;
158 158
159 if ((!count) || (buf[0] != '1')) { 159 if ((!count) || (buf[0] != '1')) {
160 return -EINVAL; 160 return -EINVAL;
161 } 161 }
162 #ifndef FORCE_EJECT 162 #ifndef FORCE_EJECT
163 if (acpi_device->driver == NULL) { 163 if (acpi_device->driver == NULL) {
164 ret = -ENODEV; 164 ret = -ENODEV;
165 goto err; 165 goto err;
166 } 166 }
167 #endif 167 #endif
168 status = acpi_get_type(acpi_device->handle, &type); 168 status = acpi_get_type(acpi_device->handle, &type);
169 if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) { 169 if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) {
170 ret = -ENODEV; 170 ret = -ENODEV;
171 goto err; 171 goto err;
172 } 172 }
173 173
174 /* remove the device in another thread to fix the deadlock issue */ 174 /* remove the device in another thread to fix the deadlock issue */
175 task = kthread_run(acpi_bus_hot_remove_device, 175 task = kthread_run(acpi_bus_hot_remove_device,
176 acpi_device->handle, "acpi_hot_remove_device"); 176 acpi_device->handle, "acpi_hot_remove_device");
177 if (IS_ERR(task)) 177 if (IS_ERR(task))
178 ret = PTR_ERR(task); 178 ret = PTR_ERR(task);
179 err: 179 err:
180 return ret; 180 return ret;
181 } 181 }
182 182
183 static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); 183 static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);
184 184
185 static ssize_t 185 static ssize_t
186 acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) { 186 acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) {
187 struct acpi_device *acpi_dev = to_acpi_device(dev); 187 struct acpi_device *acpi_dev = to_acpi_device(dev);
188 188
189 return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id); 189 return sprintf(buf, "%s\n", acpi_dev->pnp.hardware_id);
190 } 190 }
191 static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); 191 static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL);
192 192
193 static ssize_t 193 static ssize_t
194 acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { 194 acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) {
195 struct acpi_device *acpi_dev = to_acpi_device(dev); 195 struct acpi_device *acpi_dev = to_acpi_device(dev);
196 struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; 196 struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL};
197 int result; 197 int result;
198 198
199 result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); 199 result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path);
200 if(result) 200 if(result)
201 goto end; 201 goto end;
202 202
203 result = sprintf(buf, "%s\n", (char*)path.pointer); 203 result = sprintf(buf, "%s\n", (char*)path.pointer);
204 kfree(path.pointer); 204 kfree(path.pointer);
205 end: 205 end:
206 return result; 206 return result;
207 } 207 }
208 static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); 208 static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
209 209
210 static int acpi_device_setup_files(struct acpi_device *dev) 210 static int acpi_device_setup_files(struct acpi_device *dev)
211 { 211 {
212 acpi_status status; 212 acpi_status status;
213 acpi_handle temp; 213 acpi_handle temp;
214 int result = 0; 214 int result = 0;
215 215
216 /* 216 /*
217 * Devices gotten from FADT don't have a "path" attribute 217 * Devices gotten from FADT don't have a "path" attribute
218 */ 218 */
219 if(dev->handle) { 219 if(dev->handle) {
220 result = device_create_file(&dev->dev, &dev_attr_path); 220 result = device_create_file(&dev->dev, &dev_attr_path);
221 if(result) 221 if(result)
222 goto end; 222 goto end;
223 } 223 }
224 224
225 if(dev->flags.hardware_id) { 225 if(dev->flags.hardware_id) {
226 result = device_create_file(&dev->dev, &dev_attr_hid); 226 result = device_create_file(&dev->dev, &dev_attr_hid);
227 if(result) 227 if(result)
228 goto end; 228 goto end;
229 } 229 }
230 230
231 if (dev->flags.hardware_id || dev->flags.compatible_ids){ 231 if (dev->flags.hardware_id || dev->flags.compatible_ids){
232 result = device_create_file(&dev->dev, &dev_attr_modalias); 232 result = device_create_file(&dev->dev, &dev_attr_modalias);
233 if(result) 233 if(result)
234 goto end; 234 goto end;
235 } 235 }
236 236
237 /* 237 /*
238 * If device has _EJ0, 'eject' file is created that is used to trigger 238 * If device has _EJ0, 'eject' file is created that is used to trigger
239 * hot-removal function from userland. 239 * hot-removal function from userland.
240 */ 240 */
241 status = acpi_get_handle(dev->handle, "_EJ0", &temp); 241 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
242 if (ACPI_SUCCESS(status)) 242 if (ACPI_SUCCESS(status))
243 result = device_create_file(&dev->dev, &dev_attr_eject); 243 result = device_create_file(&dev->dev, &dev_attr_eject);
244 end: 244 end:
245 return result; 245 return result;
246 } 246 }
247 247
248 static void acpi_device_remove_files(struct acpi_device *dev) 248 static void acpi_device_remove_files(struct acpi_device *dev)
249 { 249 {
250 acpi_status status; 250 acpi_status status;
251 acpi_handle temp; 251 acpi_handle temp;
252 252
253 /* 253 /*
254 * If device has _EJ0, 'eject' file is created that is used to trigger 254 * If device has _EJ0, 'eject' file is created that is used to trigger
255 * hot-removal function from userland. 255 * hot-removal function from userland.
256 */ 256 */
257 status = acpi_get_handle(dev->handle, "_EJ0", &temp); 257 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
258 if (ACPI_SUCCESS(status)) 258 if (ACPI_SUCCESS(status))
259 device_remove_file(&dev->dev, &dev_attr_eject); 259 device_remove_file(&dev->dev, &dev_attr_eject);
260 260
261 if (dev->flags.hardware_id || dev->flags.compatible_ids) 261 if (dev->flags.hardware_id || dev->flags.compatible_ids)
262 device_remove_file(&dev->dev, &dev_attr_modalias); 262 device_remove_file(&dev->dev, &dev_attr_modalias);
263 263
264 if(dev->flags.hardware_id) 264 if(dev->flags.hardware_id)
265 device_remove_file(&dev->dev, &dev_attr_hid); 265 device_remove_file(&dev->dev, &dev_attr_hid);
266 if(dev->handle) 266 if(dev->handle)
267 device_remove_file(&dev->dev, &dev_attr_path); 267 device_remove_file(&dev->dev, &dev_attr_path);
268 } 268 }
269 /* -------------------------------------------------------------------------- 269 /* --------------------------------------------------------------------------
270 ACPI Bus operations 270 ACPI Bus operations
271 -------------------------------------------------------------------------- */ 271 -------------------------------------------------------------------------- */
272 272
273 int acpi_match_device_ids(struct acpi_device *device, 273 int acpi_match_device_ids(struct acpi_device *device,
274 const struct acpi_device_id *ids) 274 const struct acpi_device_id *ids)
275 { 275 {
276 const struct acpi_device_id *id; 276 const struct acpi_device_id *id;
277 277
278 /* 278 /*
279 * If the device is not present, it is unnecessary to load device 279 * If the device is not present, it is unnecessary to load device
280 * driver for it. 280 * driver for it.
281 */ 281 */
282 if (!device->status.present) 282 if (!device->status.present)
283 return -ENODEV; 283 return -ENODEV;
284 284
285 if (device->flags.hardware_id) { 285 if (device->flags.hardware_id) {
286 for (id = ids; id->id[0]; id++) { 286 for (id = ids; id->id[0]; id++) {
287 if (!strcmp((char*)id->id, device->pnp.hardware_id)) 287 if (!strcmp((char*)id->id, device->pnp.hardware_id))
288 return 0; 288 return 0;
289 } 289 }
290 } 290 }
291 291
292 if (device->flags.compatible_ids) { 292 if (device->flags.compatible_ids) {
293 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; 293 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
294 int i; 294 int i;
295 295
296 for (id = ids; id->id[0]; id++) { 296 for (id = ids; id->id[0]; id++) {
297 /* compare multiple _CID entries against driver ids */ 297 /* compare multiple _CID entries against driver ids */
298 for (i = 0; i < cid_list->count; i++) { 298 for (i = 0; i < cid_list->count; i++) {
299 if (!strcmp((char*)id->id, 299 if (!strcmp((char*)id->id,
300 cid_list->id[i].value)) 300 cid_list->id[i].value))
301 return 0; 301 return 0;
302 } 302 }
303 } 303 }
304 } 304 }
305 305
306 return -ENOENT; 306 return -ENOENT;
307 } 307 }
308 EXPORT_SYMBOL(acpi_match_device_ids); 308 EXPORT_SYMBOL(acpi_match_device_ids);
309 309
310 static void acpi_device_release(struct device *dev) 310 static void acpi_device_release(struct device *dev)
311 { 311 {
312 struct acpi_device *acpi_dev = to_acpi_device(dev); 312 struct acpi_device *acpi_dev = to_acpi_device(dev);
313 313
314 kfree(acpi_dev->pnp.cid_list); 314 kfree(acpi_dev->pnp.cid_list);
315 kfree(acpi_dev); 315 kfree(acpi_dev);
316 } 316 }
317 317
318 static int acpi_device_suspend(struct device *dev, pm_message_t state) 318 static int acpi_device_suspend(struct device *dev, pm_message_t state)
319 { 319 {
320 struct acpi_device *acpi_dev = to_acpi_device(dev); 320 struct acpi_device *acpi_dev = to_acpi_device(dev);
321 struct acpi_driver *acpi_drv = acpi_dev->driver; 321 struct acpi_driver *acpi_drv = acpi_dev->driver;
322 322
323 if (acpi_drv && acpi_drv->ops.suspend) 323 if (acpi_drv && acpi_drv->ops.suspend)
324 return acpi_drv->ops.suspend(acpi_dev, state); 324 return acpi_drv->ops.suspend(acpi_dev, state);
325 return 0; 325 return 0;
326 } 326 }
327 327
328 static int acpi_device_resume(struct device *dev) 328 static int acpi_device_resume(struct device *dev)
329 { 329 {
330 struct acpi_device *acpi_dev = to_acpi_device(dev); 330 struct acpi_device *acpi_dev = to_acpi_device(dev);
331 struct acpi_driver *acpi_drv = acpi_dev->driver; 331 struct acpi_driver *acpi_drv = acpi_dev->driver;
332 332
333 if (acpi_drv && acpi_drv->ops.resume) 333 if (acpi_drv && acpi_drv->ops.resume)
334 return acpi_drv->ops.resume(acpi_dev); 334 return acpi_drv->ops.resume(acpi_dev);
335 return 0; 335 return 0;
336 } 336 }
337 337
338 static int acpi_bus_match(struct device *dev, struct device_driver *drv) 338 static int acpi_bus_match(struct device *dev, struct device_driver *drv)
339 { 339 {
340 struct acpi_device *acpi_dev = to_acpi_device(dev); 340 struct acpi_device *acpi_dev = to_acpi_device(dev);
341 struct acpi_driver *acpi_drv = to_acpi_driver(drv); 341 struct acpi_driver *acpi_drv = to_acpi_driver(drv);
342 342
343 return !acpi_match_device_ids(acpi_dev, acpi_drv->ids); 343 return !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
344 } 344 }
345 345
346 static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) 346 static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
347 { 347 {
348 struct acpi_device *acpi_dev = to_acpi_device(dev); 348 struct acpi_device *acpi_dev = to_acpi_device(dev);
349 int len; 349 int len;
350 350
351 if (add_uevent_var(env, "MODALIAS=")) 351 if (add_uevent_var(env, "MODALIAS="))
352 return -ENOMEM; 352 return -ENOMEM;
353 len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], 353 len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
354 sizeof(env->buf) - env->buflen); 354 sizeof(env->buf) - env->buflen);
355 if (len >= (sizeof(env->buf) - env->buflen)) 355 if (len >= (sizeof(env->buf) - env->buflen))
356 return -ENOMEM; 356 return -ENOMEM;
357 env->buflen += len; 357 env->buflen += len;
358 return 0; 358 return 0;
359 } 359 }
360 360
361 static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *); 361 static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
362 static int acpi_start_single_object(struct acpi_device *); 362 static int acpi_start_single_object(struct acpi_device *);
363 static int acpi_device_probe(struct device * dev) 363 static int acpi_device_probe(struct device * dev)
364 { 364 {
365 struct acpi_device *acpi_dev = to_acpi_device(dev); 365 struct acpi_device *acpi_dev = to_acpi_device(dev);
366 struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); 366 struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
367 int ret; 367 int ret;
368 368
369 ret = acpi_bus_driver_init(acpi_dev, acpi_drv); 369 ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
370 if (!ret) { 370 if (!ret) {
371 if (acpi_dev->bus_ops.acpi_op_start) 371 if (acpi_dev->bus_ops.acpi_op_start)
372 acpi_start_single_object(acpi_dev); 372 acpi_start_single_object(acpi_dev);
373 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 373 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
374 "Found driver [%s] for device [%s]\n", 374 "Found driver [%s] for device [%s]\n",
375 acpi_drv->name, acpi_dev->pnp.bus_id)); 375 acpi_drv->name, acpi_dev->pnp.bus_id));
376 get_device(dev); 376 get_device(dev);
377 } 377 }
378 return ret; 378 return ret;
379 } 379 }
380 380
381 static int acpi_device_remove(struct device * dev) 381 static int acpi_device_remove(struct device * dev)
382 { 382 {
383 struct acpi_device *acpi_dev = to_acpi_device(dev); 383 struct acpi_device *acpi_dev = to_acpi_device(dev);
384 struct acpi_driver *acpi_drv = acpi_dev->driver; 384 struct acpi_driver *acpi_drv = acpi_dev->driver;
385 385
386 if (acpi_drv) { 386 if (acpi_drv) {
387 if (acpi_drv->ops.stop) 387 if (acpi_drv->ops.stop)
388 acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type); 388 acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
389 if (acpi_drv->ops.remove) 389 if (acpi_drv->ops.remove)
390 acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); 390 acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
391 } 391 }
392 acpi_dev->driver = NULL; 392 acpi_dev->driver = NULL;
393 acpi_dev->driver_data = NULL; 393 acpi_dev->driver_data = NULL;
394 394
395 put_device(dev); 395 put_device(dev);
396 return 0; 396 return 0;
397 } 397 }
398 398
399 static void acpi_device_shutdown(struct device *dev) 399 static void acpi_device_shutdown(struct device *dev)
400 { 400 {
401 struct acpi_device *acpi_dev = to_acpi_device(dev); 401 struct acpi_device *acpi_dev = to_acpi_device(dev);
402 struct acpi_driver *acpi_drv = acpi_dev->driver; 402 struct acpi_driver *acpi_drv = acpi_dev->driver;
403 403
404 if (acpi_drv && acpi_drv->ops.shutdown) 404 if (acpi_drv && acpi_drv->ops.shutdown)
405 acpi_drv->ops.shutdown(acpi_dev); 405 acpi_drv->ops.shutdown(acpi_dev);
406 406
407 return ; 407 return ;
408 } 408 }
409 409
410 struct bus_type acpi_bus_type = { 410 struct bus_type acpi_bus_type = {
411 .name = "acpi", 411 .name = "acpi",
412 .suspend = acpi_device_suspend, 412 .suspend = acpi_device_suspend,
413 .resume = acpi_device_resume, 413 .resume = acpi_device_resume,
414 .shutdown = acpi_device_shutdown, 414 .shutdown = acpi_device_shutdown,
415 .match = acpi_bus_match, 415 .match = acpi_bus_match,
416 .probe = acpi_device_probe, 416 .probe = acpi_device_probe,
417 .remove = acpi_device_remove, 417 .remove = acpi_device_remove,
418 .uevent = acpi_device_uevent, 418 .uevent = acpi_device_uevent,
419 }; 419 };
420 420
421 static int acpi_device_register(struct acpi_device *device, 421 static int acpi_device_register(struct acpi_device *device,
422 struct acpi_device *parent) 422 struct acpi_device *parent)
423 { 423 {
424 int result; 424 int result;
425 struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; 425 struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
426 int found = 0; 426 int found = 0;
427 /* 427 /*
428 * Linkage 428 * Linkage
429 * ------- 429 * -------
430 * Link this device to its parent and siblings. 430 * Link this device to its parent and siblings.
431 */ 431 */
432 INIT_LIST_HEAD(&device->children); 432 INIT_LIST_HEAD(&device->children);
433 INIT_LIST_HEAD(&device->node); 433 INIT_LIST_HEAD(&device->node);
434 INIT_LIST_HEAD(&device->g_list); 434 INIT_LIST_HEAD(&device->g_list);
435 INIT_LIST_HEAD(&device->wakeup_list); 435 INIT_LIST_HEAD(&device->wakeup_list);
436 436
437 new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); 437 new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
438 if (!new_bus_id) { 438 if (!new_bus_id) {
439 printk(KERN_ERR PREFIX "Memory allocation error\n"); 439 printk(KERN_ERR PREFIX "Memory allocation error\n");
440 return -ENOMEM; 440 return -ENOMEM;
441 } 441 }
442 442
443 spin_lock(&acpi_device_lock); 443 spin_lock(&acpi_device_lock);
444 /* 444 /*
445 * Find suitable bus_id and instance number in acpi_bus_id_list 445 * Find suitable bus_id and instance number in acpi_bus_id_list
446 * If failed, create one and link it into acpi_bus_id_list 446 * If failed, create one and link it into acpi_bus_id_list
447 */ 447 */
448 list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { 448 list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) {
449 if(!strcmp(acpi_device_bus_id->bus_id, device->flags.hardware_id? device->pnp.hardware_id : "device")) { 449 if(!strcmp(acpi_device_bus_id->bus_id, device->flags.hardware_id? device->pnp.hardware_id : "device")) {
450 acpi_device_bus_id->instance_no ++; 450 acpi_device_bus_id->instance_no ++;
451 found = 1; 451 found = 1;
452 kfree(new_bus_id); 452 kfree(new_bus_id);
453 break; 453 break;
454 } 454 }
455 } 455 }
456 if(!found) { 456 if(!found) {
457 acpi_device_bus_id = new_bus_id; 457 acpi_device_bus_id = new_bus_id;
458 strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device"); 458 strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device");
459 acpi_device_bus_id->instance_no = 0; 459 acpi_device_bus_id->instance_no = 0;
460 list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); 460 list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
461 } 461 }
462 dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); 462 dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
463 463
464 if (device->parent) { 464 if (device->parent) {
465 list_add_tail(&device->node, &device->parent->children); 465 list_add_tail(&device->node, &device->parent->children);
466 list_add_tail(&device->g_list, &device->parent->g_list); 466 list_add_tail(&device->g_list, &device->parent->g_list);
467 } else 467 } else
468 list_add_tail(&device->g_list, &acpi_device_list); 468 list_add_tail(&device->g_list, &acpi_device_list);
469 if (device->wakeup.flags.valid) 469 if (device->wakeup.flags.valid)
470 list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); 470 list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
471 spin_unlock(&acpi_device_lock); 471 spin_unlock(&acpi_device_lock);
472 472
473 if (device->parent) 473 if (device->parent)
474 device->dev.parent = &parent->dev; 474 device->dev.parent = &parent->dev;
475 device->dev.bus = &acpi_bus_type; 475 device->dev.bus = &acpi_bus_type;
476 device_initialize(&device->dev); 476 device_initialize(&device->dev);
477 device->dev.release = &acpi_device_release; 477 device->dev.release = &acpi_device_release;
478 result = device_add(&device->dev); 478 result = device_add(&device->dev);
479 if(result) { 479 if(result) {
480 dev_err(&device->dev, "Error adding device\n"); 480 dev_err(&device->dev, "Error adding device\n");
481 goto end; 481 goto end;
482 } 482 }
483 483
484 result = acpi_device_setup_files(device); 484 result = acpi_device_setup_files(device);
485 if(result) 485 if(result)
486 printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", 486 printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n",
487 dev_name(&device->dev)); 487 dev_name(&device->dev));
488 488
489 device->removal_type = ACPI_BUS_REMOVAL_NORMAL; 489 device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
490 return 0; 490 return 0;
491 end: 491 end:
492 spin_lock(&acpi_device_lock); 492 spin_lock(&acpi_device_lock);
493 if (device->parent) { 493 if (device->parent) {
494 list_del(&device->node); 494 list_del(&device->node);
495 list_del(&device->g_list); 495 list_del(&device->g_list);
496 } else 496 } else
497 list_del(&device->g_list); 497 list_del(&device->g_list);
498 list_del(&device->wakeup_list); 498 list_del(&device->wakeup_list);
499 spin_unlock(&acpi_device_lock); 499 spin_unlock(&acpi_device_lock);
500 return result; 500 return result;
501 } 501 }
502 502
503 static void acpi_device_unregister(struct acpi_device *device, int type) 503 static void acpi_device_unregister(struct acpi_device *device, int type)
504 { 504 {
505 spin_lock(&acpi_device_lock); 505 spin_lock(&acpi_device_lock);
506 if (device->parent) { 506 if (device->parent) {
507 list_del(&device->node); 507 list_del(&device->node);
508 list_del(&device->g_list); 508 list_del(&device->g_list);
509 } else 509 } else
510 list_del(&device->g_list); 510 list_del(&device->g_list);
511 511
512 list_del(&device->wakeup_list); 512 list_del(&device->wakeup_list);
513 spin_unlock(&acpi_device_lock); 513 spin_unlock(&acpi_device_lock);
514 514
515 acpi_detach_data(device->handle, acpi_bus_data_handler); 515 acpi_detach_data(device->handle, acpi_bus_data_handler);
516 516
517 acpi_device_remove_files(device); 517 acpi_device_remove_files(device);
518 device_unregister(&device->dev); 518 device_unregister(&device->dev);
519 } 519 }
520 520
521 /* -------------------------------------------------------------------------- 521 /* --------------------------------------------------------------------------
522 Driver Management 522 Driver Management
523 -------------------------------------------------------------------------- */ 523 -------------------------------------------------------------------------- */
524 /** 524 /**
525 * acpi_bus_driver_init - add a device to a driver 525 * acpi_bus_driver_init - add a device to a driver
526 * @device: the device to add and initialize 526 * @device: the device to add and initialize
527 * @driver: driver for the device 527 * @driver: driver for the device
528 * 528 *
529 * Used to initialize a device via its device driver. Called whenever a 529 * Used to initialize a device via its device driver. Called whenever a
530 * driver is bound to a device. Invokes the driver's add() ops. 530 * driver is bound to a device. Invokes the driver's add() ops.
531 */ 531 */
532 static int 532 static int
533 acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) 533 acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
534 { 534 {
535 int result = 0; 535 int result = 0;
536 536
537 537
538 if (!device || !driver) 538 if (!device || !driver)
539 return -EINVAL; 539 return -EINVAL;
540 540
541 if (!driver->ops.add) 541 if (!driver->ops.add)
542 return -ENOSYS; 542 return -ENOSYS;
543 543
544 result = driver->ops.add(device); 544 result = driver->ops.add(device);
545 if (result) { 545 if (result) {
546 device->driver = NULL; 546 device->driver = NULL;
547 device->driver_data = NULL; 547 device->driver_data = NULL;
548 return result; 548 return result;
549 } 549 }
550 550
551 device->driver = driver; 551 device->driver = driver;
552 552
553 /* 553 /*
554 * TBD - Configuration Management: Assign resources to device based 554 * TBD - Configuration Management: Assign resources to device based
555 * upon possible configuration and currently allocated resources. 555 * upon possible configuration and currently allocated resources.
556 */ 556 */
557 557
558 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 558 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
559 "Driver successfully bound to device\n")); 559 "Driver successfully bound to device\n"));
560 return 0; 560 return 0;
561 } 561 }
562 562
563 static int acpi_start_single_object(struct acpi_device *device) 563 static int acpi_start_single_object(struct acpi_device *device)
564 { 564 {
565 int result = 0; 565 int result = 0;
566 struct acpi_driver *driver; 566 struct acpi_driver *driver;
567 567
568 568
569 if (!(driver = device->driver)) 569 if (!(driver = device->driver))
570 return 0; 570 return 0;
571 571
572 if (driver->ops.start) { 572 if (driver->ops.start) {
573 result = driver->ops.start(device); 573 result = driver->ops.start(device);
574 if (result && driver->ops.remove) 574 if (result && driver->ops.remove)
575 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); 575 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
576 } 576 }
577 577
578 return result; 578 return result;
579 } 579 }
580 580
581 /** 581 /**
582 * acpi_bus_register_driver - register a driver with the ACPI bus 582 * acpi_bus_register_driver - register a driver with the ACPI bus
583 * @driver: driver being registered 583 * @driver: driver being registered
584 * 584 *
585 * Registers a driver with the ACPI bus. Searches the namespace for all 585 * Registers a driver with the ACPI bus. Searches the namespace for all
586 * devices that match the driver's criteria and binds. Returns zero for 586 * devices that match the driver's criteria and binds. Returns zero for
587 * success or a negative error status for failure. 587 * success or a negative error status for failure.
588 */ 588 */
589 int acpi_bus_register_driver(struct acpi_driver *driver) 589 int acpi_bus_register_driver(struct acpi_driver *driver)
590 { 590 {
591 int ret; 591 int ret;
592 592
593 if (acpi_disabled) 593 if (acpi_disabled)
594 return -ENODEV; 594 return -ENODEV;
595 driver->drv.name = driver->name; 595 driver->drv.name = driver->name;
596 driver->drv.bus = &acpi_bus_type; 596 driver->drv.bus = &acpi_bus_type;
597 driver->drv.owner = driver->owner; 597 driver->drv.owner = driver->owner;
598 598
599 ret = driver_register(&driver->drv); 599 ret = driver_register(&driver->drv);
600 return ret; 600 return ret;
601 } 601 }
602 602
603 EXPORT_SYMBOL(acpi_bus_register_driver); 603 EXPORT_SYMBOL(acpi_bus_register_driver);
604 604
605 /** 605 /**
606 * acpi_bus_unregister_driver - unregisters a driver with the APIC bus 606 * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
607 * @driver: driver to unregister 607 * @driver: driver to unregister
608 * 608 *
609 * Unregisters a driver with the ACPI bus. Searches the namespace for all 609 * Unregisters a driver with the ACPI bus. Searches the namespace for all
610 * devices that match the driver's criteria and unbinds. 610 * devices that match the driver's criteria and unbinds.
611 */ 611 */
612 void acpi_bus_unregister_driver(struct acpi_driver *driver) 612 void acpi_bus_unregister_driver(struct acpi_driver *driver)
613 { 613 {
614 driver_unregister(&driver->drv); 614 driver_unregister(&driver->drv);
615 } 615 }
616 616
617 EXPORT_SYMBOL(acpi_bus_unregister_driver); 617 EXPORT_SYMBOL(acpi_bus_unregister_driver);
618 618
619 /* -------------------------------------------------------------------------- 619 /* --------------------------------------------------------------------------
620 Device Enumeration 620 Device Enumeration
621 -------------------------------------------------------------------------- */ 621 -------------------------------------------------------------------------- */
622 acpi_status 622 acpi_status
623 acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) 623 acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
624 { 624 {
625 acpi_status status; 625 acpi_status status;
626 acpi_handle tmp; 626 acpi_handle tmp;
627 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; 627 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
628 union acpi_object *obj; 628 union acpi_object *obj;
629 629
630 status = acpi_get_handle(handle, "_EJD", &tmp); 630 status = acpi_get_handle(handle, "_EJD", &tmp);
631 if (ACPI_FAILURE(status)) 631 if (ACPI_FAILURE(status))
632 return status; 632 return status;
633 633
634 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); 634 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
635 if (ACPI_SUCCESS(status)) { 635 if (ACPI_SUCCESS(status)) {
636 obj = buffer.pointer; 636 obj = buffer.pointer;
637 status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer, 637 status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer,
638 ejd); 638 ejd);
639 kfree(buffer.pointer); 639 kfree(buffer.pointer);
640 } 640 }
641 return status; 641 return status;
642 } 642 }
643 EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); 643 EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
644 644
645 void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) 645 void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
646 { 646 {
647 647
648 /* TBD */ 648 /* TBD */
649 649
650 return; 650 return;
651 } 651 }
652 652
653 static int acpi_bus_get_perf_flags(struct acpi_device *device) 653 static int acpi_bus_get_perf_flags(struct acpi_device *device)
654 { 654 {
655 device->performance.state = ACPI_STATE_UNKNOWN; 655 device->performance.state = ACPI_STATE_UNKNOWN;
656 return 0; 656 return 0;
657 } 657 }
658 658
659 static acpi_status 659 static acpi_status
660 acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, 660 acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
661 union acpi_object *package) 661 union acpi_object *package)
662 { 662 {
663 int i = 0; 663 int i = 0;
664 union acpi_object *element = NULL; 664 union acpi_object *element = NULL;
665 665
666 if (!device || !package || (package->package.count < 2)) 666 if (!device || !package || (package->package.count < 2))
667 return AE_BAD_PARAMETER; 667 return AE_BAD_PARAMETER;
668 668
669 element = &(package->package.elements[0]); 669 element = &(package->package.elements[0]);
670 if (!element) 670 if (!element)
671 return AE_BAD_PARAMETER; 671 return AE_BAD_PARAMETER;
672 if (element->type == ACPI_TYPE_PACKAGE) { 672 if (element->type == ACPI_TYPE_PACKAGE) {
673 if ((element->package.count < 2) || 673 if ((element->package.count < 2) ||
674 (element->package.elements[0].type != 674 (element->package.elements[0].type !=
675 ACPI_TYPE_LOCAL_REFERENCE) 675 ACPI_TYPE_LOCAL_REFERENCE)
676 || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) 676 || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
677 return AE_BAD_DATA; 677 return AE_BAD_DATA;
678 device->wakeup.gpe_device = 678 device->wakeup.gpe_device =
679 element->package.elements[0].reference.handle; 679 element->package.elements[0].reference.handle;
680 device->wakeup.gpe_number = 680 device->wakeup.gpe_number =
681 (u32) element->package.elements[1].integer.value; 681 (u32) element->package.elements[1].integer.value;
682 } else if (element->type == ACPI_TYPE_INTEGER) { 682 } else if (element->type == ACPI_TYPE_INTEGER) {
683 device->wakeup.gpe_number = element->integer.value; 683 device->wakeup.gpe_number = element->integer.value;
684 } else 684 } else
685 return AE_BAD_DATA; 685 return AE_BAD_DATA;
686 686
687 element = &(package->package.elements[1]); 687 element = &(package->package.elements[1]);
688 if (element->type != ACPI_TYPE_INTEGER) { 688 if (element->type != ACPI_TYPE_INTEGER) {
689 return AE_BAD_DATA; 689 return AE_BAD_DATA;
690 } 690 }
691 device->wakeup.sleep_state = element->integer.value; 691 device->wakeup.sleep_state = element->integer.value;
692 692
693 if ((package->package.count - 2) > ACPI_MAX_HANDLES) { 693 if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
694 return AE_NO_MEMORY; 694 return AE_NO_MEMORY;
695 } 695 }
696 device->wakeup.resources.count = package->package.count - 2; 696 device->wakeup.resources.count = package->package.count - 2;
697 for (i = 0; i < device->wakeup.resources.count; i++) { 697 for (i = 0; i < device->wakeup.resources.count; i++) {
698 element = &(package->package.elements[i + 2]); 698 element = &(package->package.elements[i + 2]);
699 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) 699 if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
700 return AE_BAD_DATA; 700 return AE_BAD_DATA;
701 701
702 device->wakeup.resources.handles[i] = element->reference.handle; 702 device->wakeup.resources.handles[i] = element->reference.handle;
703 } 703 }
704 704
705 return AE_OK; 705 return AE_OK;
706 } 706 }
707 707
708 static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) 708 static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
709 { 709 {
710 acpi_status status = 0; 710 acpi_status status = 0;
711 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 711 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
712 union acpi_object *package = NULL; 712 union acpi_object *package = NULL;
713 int psw_error; 713 int psw_error;
714 714
715 struct acpi_device_id button_device_ids[] = { 715 struct acpi_device_id button_device_ids[] = {
716 {"PNP0C0D", 0}, 716 {"PNP0C0D", 0},
717 {"PNP0C0C", 0}, 717 {"PNP0C0C", 0},
718 {"PNP0C0E", 0}, 718 {"PNP0C0E", 0},
719 {"", 0}, 719 {"", 0},
720 }; 720 };
721 721
722 /* _PRW */ 722 /* _PRW */
723 status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); 723 status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
724 if (ACPI_FAILURE(status)) { 724 if (ACPI_FAILURE(status)) {
725 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); 725 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
726 goto end; 726 goto end;
727 } 727 }
728 728
729 package = (union acpi_object *)buffer.pointer; 729 package = (union acpi_object *)buffer.pointer;
730 status = acpi_bus_extract_wakeup_device_power_package(device, package); 730 status = acpi_bus_extract_wakeup_device_power_package(device, package);
731 if (ACPI_FAILURE(status)) { 731 if (ACPI_FAILURE(status)) {
732 ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); 732 ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
733 goto end; 733 goto end;
734 } 734 }
735 735
736 kfree(buffer.pointer); 736 kfree(buffer.pointer);
737 737
738 device->wakeup.flags.valid = 1; 738 device->wakeup.flags.valid = 1;
739 /* Call _PSW/_DSW object to disable its ability to wake the sleeping 739 /* Call _PSW/_DSW object to disable its ability to wake the sleeping
740 * system for the ACPI device with the _PRW object. 740 * system for the ACPI device with the _PRW object.
741 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. 741 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
742 * So it is necessary to call _DSW object first. Only when it is not 742 * So it is necessary to call _DSW object first. Only when it is not
743 * present will the _PSW object used. 743 * present will the _PSW object used.
744 */ 744 */
745 psw_error = acpi_device_sleep_wake(device, 0, 0, 0); 745 psw_error = acpi_device_sleep_wake(device, 0, 0, 0);
746 if (psw_error) 746 if (psw_error)
747 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 747 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
748 "error in _DSW or _PSW evaluation\n")); 748 "error in _DSW or _PSW evaluation\n"));
749 749
750 /* Power button, Lid switch always enable wakeup */ 750 /* Power button, Lid switch always enable wakeup */
751 if (!acpi_match_device_ids(device, button_device_ids)) 751 if (!acpi_match_device_ids(device, button_device_ids))
752 device->wakeup.flags.run_wake = 1; 752 device->wakeup.flags.run_wake = 1;
753 753
754 /* 754 /*
755 * Don't set Power button GPE as run_wake 755 * Don't set Power button GPE as run_wake
756 * if Fixed Power button is used 756 * if Fixed Power button is used
757 */ 757 */
758 if (!strcmp(device->pnp.hardware_id, "PNP0C0C") && 758 if (!strcmp(device->pnp.hardware_id, "PNP0C0C") &&
759 !(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { 759 !(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) {
760 device->wakeup.flags.run_wake = 0; 760 device->wakeup.flags.run_wake = 0;
761 device->wakeup.flags.valid = 0; 761 device->wakeup.flags.valid = 0;
762 } 762 }
763 763
764 end: 764 end:
765 if (ACPI_FAILURE(status)) 765 if (ACPI_FAILURE(status))
766 device->flags.wake_capable = 0; 766 device->flags.wake_capable = 0;
767 return 0; 767 return 0;
768 } 768 }
769 769
770 static int acpi_bus_get_power_flags(struct acpi_device *device) 770 static int acpi_bus_get_power_flags(struct acpi_device *device)
771 { 771 {
772 acpi_status status = 0; 772 acpi_status status = 0;
773 acpi_handle handle = NULL; 773 acpi_handle handle = NULL;
774 u32 i = 0; 774 u32 i = 0;
775 775
776 776
777 /* 777 /*
778 * Power Management Flags 778 * Power Management Flags
779 */ 779 */
780 status = acpi_get_handle(device->handle, "_PSC", &handle); 780 status = acpi_get_handle(device->handle, "_PSC", &handle);
781 if (ACPI_SUCCESS(status)) 781 if (ACPI_SUCCESS(status))
782 device->power.flags.explicit_get = 1; 782 device->power.flags.explicit_get = 1;
783 status = acpi_get_handle(device->handle, "_IRC", &handle); 783 status = acpi_get_handle(device->handle, "_IRC", &handle);
784 if (ACPI_SUCCESS(status)) 784 if (ACPI_SUCCESS(status))
785 device->power.flags.inrush_current = 1; 785 device->power.flags.inrush_current = 1;
786 786
787 /* 787 /*
788 * Enumerate supported power management states 788 * Enumerate supported power management states
789 */ 789 */
790 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { 790 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
791 struct acpi_device_power_state *ps = &device->power.states[i]; 791 struct acpi_device_power_state *ps = &device->power.states[i];
792 char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; 792 char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
793 793
794 /* Evaluate "_PRx" to se if power resources are referenced */ 794 /* Evaluate "_PRx" to se if power resources are referenced */
795 acpi_evaluate_reference(device->handle, object_name, NULL, 795 acpi_evaluate_reference(device->handle, object_name, NULL,
796 &ps->resources); 796 &ps->resources);
797 if (ps->resources.count) { 797 if (ps->resources.count) {
798 device->power.flags.power_resources = 1; 798 device->power.flags.power_resources = 1;
799 ps->flags.valid = 1; 799 ps->flags.valid = 1;
800 } 800 }
801 801
802 /* Evaluate "_PSx" to see if we can do explicit sets */ 802 /* Evaluate "_PSx" to see if we can do explicit sets */
803 object_name[2] = 'S'; 803 object_name[2] = 'S';
804 status = acpi_get_handle(device->handle, object_name, &handle); 804 status = acpi_get_handle(device->handle, object_name, &handle);
805 if (ACPI_SUCCESS(status)) { 805 if (ACPI_SUCCESS(status)) {
806 ps->flags.explicit_set = 1; 806 ps->flags.explicit_set = 1;
807 ps->flags.valid = 1; 807 ps->flags.valid = 1;
808 } 808 }
809 809
810 /* State is valid if we have some power control */ 810 /* State is valid if we have some power control */
811 if (ps->resources.count || ps->flags.explicit_set) 811 if (ps->resources.count || ps->flags.explicit_set)
812 ps->flags.valid = 1; 812 ps->flags.valid = 1;
813 813
814 ps->power = -1; /* Unknown - driver assigned */ 814 ps->power = -1; /* Unknown - driver assigned */
815 ps->latency = -1; /* Unknown - driver assigned */ 815 ps->latency = -1; /* Unknown - driver assigned */
816 } 816 }
817 817
818 /* Set defaults for D0 and D3 states (always valid) */ 818 /* Set defaults for D0 and D3 states (always valid) */
819 device->power.states[ACPI_STATE_D0].flags.valid = 1; 819 device->power.states[ACPI_STATE_D0].flags.valid = 1;
820 device->power.states[ACPI_STATE_D0].power = 100; 820 device->power.states[ACPI_STATE_D0].power = 100;
821 device->power.states[ACPI_STATE_D3].flags.valid = 1; 821 device->power.states[ACPI_STATE_D3].flags.valid = 1;
822 device->power.states[ACPI_STATE_D3].power = 0; 822 device->power.states[ACPI_STATE_D3].power = 0;
823 823
824 /* TBD: System wake support and resource requirements. */ 824 /* TBD: System wake support and resource requirements. */
825 825
826 device->power.state = ACPI_STATE_UNKNOWN; 826 device->power.state = ACPI_STATE_UNKNOWN;
827 acpi_bus_get_power(device->handle, &(device->power.state)); 827 acpi_bus_get_power(device->handle, &(device->power.state));
828 828
829 return 0; 829 return 0;
830 } 830 }
831 831
832 static int acpi_bus_get_flags(struct acpi_device *device) 832 static int acpi_bus_get_flags(struct acpi_device *device)
833 { 833 {
834 acpi_status status = AE_OK; 834 acpi_status status = AE_OK;
835 acpi_handle temp = NULL; 835 acpi_handle temp = NULL;
836 836
837 837
838 /* Presence of _STA indicates 'dynamic_status' */ 838 /* Presence of _STA indicates 'dynamic_status' */
839 status = acpi_get_handle(device->handle, "_STA", &temp); 839 status = acpi_get_handle(device->handle, "_STA", &temp);
840 if (ACPI_SUCCESS(status)) 840 if (ACPI_SUCCESS(status))
841 device->flags.dynamic_status = 1; 841 device->flags.dynamic_status = 1;
842 842
843 /* Presence of _CID indicates 'compatible_ids' */ 843 /* Presence of _CID indicates 'compatible_ids' */
844 status = acpi_get_handle(device->handle, "_CID", &temp); 844 status = acpi_get_handle(device->handle, "_CID", &temp);
845 if (ACPI_SUCCESS(status)) 845 if (ACPI_SUCCESS(status))
846 device->flags.compatible_ids = 1; 846 device->flags.compatible_ids = 1;
847 847
848 /* Presence of _RMV indicates 'removable' */ 848 /* Presence of _RMV indicates 'removable' */
849 status = acpi_get_handle(device->handle, "_RMV", &temp); 849 status = acpi_get_handle(device->handle, "_RMV", &temp);
850 if (ACPI_SUCCESS(status)) 850 if (ACPI_SUCCESS(status))
851 device->flags.removable = 1; 851 device->flags.removable = 1;
852 852
853 /* Presence of _EJD|_EJ0 indicates 'ejectable' */ 853 /* Presence of _EJD|_EJ0 indicates 'ejectable' */
854 status = acpi_get_handle(device->handle, "_EJD", &temp); 854 status = acpi_get_handle(device->handle, "_EJD", &temp);
855 if (ACPI_SUCCESS(status)) 855 if (ACPI_SUCCESS(status))
856 device->flags.ejectable = 1; 856 device->flags.ejectable = 1;
857 else { 857 else {
858 status = acpi_get_handle(device->handle, "_EJ0", &temp); 858 status = acpi_get_handle(device->handle, "_EJ0", &temp);
859 if (ACPI_SUCCESS(status)) 859 if (ACPI_SUCCESS(status))
860 device->flags.ejectable = 1; 860 device->flags.ejectable = 1;
861 } 861 }
862 862
863 /* Presence of _LCK indicates 'lockable' */ 863 /* Presence of _LCK indicates 'lockable' */
864 status = acpi_get_handle(device->handle, "_LCK", &temp); 864 status = acpi_get_handle(device->handle, "_LCK", &temp);
865 if (ACPI_SUCCESS(status)) 865 if (ACPI_SUCCESS(status))
866 device->flags.lockable = 1; 866 device->flags.lockable = 1;
867 867
868 /* Presence of _PS0|_PR0 indicates 'power manageable' */ 868 /* Presence of _PS0|_PR0 indicates 'power manageable' */
869 status = acpi_get_handle(device->handle, "_PS0", &temp); 869 status = acpi_get_handle(device->handle, "_PS0", &temp);
870 if (ACPI_FAILURE(status)) 870 if (ACPI_FAILURE(status))
871 status = acpi_get_handle(device->handle, "_PR0", &temp); 871 status = acpi_get_handle(device->handle, "_PR0", &temp);
872 if (ACPI_SUCCESS(status)) 872 if (ACPI_SUCCESS(status))
873 device->flags.power_manageable = 1; 873 device->flags.power_manageable = 1;
874 874
875 /* Presence of _PRW indicates wake capable */ 875 /* Presence of _PRW indicates wake capable */
876 status = acpi_get_handle(device->handle, "_PRW", &temp); 876 status = acpi_get_handle(device->handle, "_PRW", &temp);
877 if (ACPI_SUCCESS(status)) 877 if (ACPI_SUCCESS(status))
878 device->flags.wake_capable = 1; 878 device->flags.wake_capable = 1;
879 879
880 /* TBD: Performance management */ 880 /* TBD: Performance management */
881 881
882 return 0; 882 return 0;
883 } 883 }
884 884
885 static void acpi_device_get_busid(struct acpi_device *device, 885 static void acpi_device_get_busid(struct acpi_device *device,
886 acpi_handle handle, int type) 886 acpi_handle handle, int type)
887 { 887 {
888 char bus_id[5] = { '?', 0 }; 888 char bus_id[5] = { '?', 0 };
889 struct acpi_buffer buffer = { sizeof(bus_id), bus_id }; 889 struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
890 int i = 0; 890 int i = 0;
891 891
892 /* 892 /*
893 * Bus ID 893 * Bus ID
894 * ------ 894 * ------
895 * The device's Bus ID is simply the object name. 895 * The device's Bus ID is simply the object name.
896 * TBD: Shouldn't this value be unique (within the ACPI namespace)? 896 * TBD: Shouldn't this value be unique (within the ACPI namespace)?
897 */ 897 */
898 switch (type) { 898 switch (type) {
899 case ACPI_BUS_TYPE_SYSTEM: 899 case ACPI_BUS_TYPE_SYSTEM:
900 strcpy(device->pnp.bus_id, "ACPI"); 900 strcpy(device->pnp.bus_id, "ACPI");
901 break; 901 break;
902 case ACPI_BUS_TYPE_POWER_BUTTON: 902 case ACPI_BUS_TYPE_POWER_BUTTON:
903 strcpy(device->pnp.bus_id, "PWRF"); 903 strcpy(device->pnp.bus_id, "PWRF");
904 break; 904 break;
905 case ACPI_BUS_TYPE_SLEEP_BUTTON: 905 case ACPI_BUS_TYPE_SLEEP_BUTTON:
906 strcpy(device->pnp.bus_id, "SLPF"); 906 strcpy(device->pnp.bus_id, "SLPF");
907 break; 907 break;
908 default: 908 default:
909 acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); 909 acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
910 /* Clean up trailing underscores (if any) */ 910 /* Clean up trailing underscores (if any) */
911 for (i = 3; i > 1; i--) { 911 for (i = 3; i > 1; i--) {
912 if (bus_id[i] == '_') 912 if (bus_id[i] == '_')
913 bus_id[i] = '\0'; 913 bus_id[i] = '\0';
914 else 914 else
915 break; 915 break;
916 } 916 }
917 strcpy(device->pnp.bus_id, bus_id); 917 strcpy(device->pnp.bus_id, bus_id);
918 break; 918 break;
919 } 919 }
920 } 920 }
921 921
922 static int
923 acpi_video_bus_match(struct acpi_device *device)
924 {
925 acpi_handle h_dummy;
926
927 if (!device)
928 return -EINVAL;
929
930 /* Since there is no HID, CID for ACPI Video drivers, we have
931 * to check well known required nodes for each feature we support.
932 */
933
934 /* Does this device able to support video switching ? */
935 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
936 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
937 return 0;
938
939 /* Does this device able to retrieve a video ROM ? */
940 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
941 return 0;
942
943 /* Does this device able to configure which video head to be POSTed ? */
944 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
945 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
946 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
947 return 0;
948
949 return -ENODEV;
950 }
951
952 /* 922 /*
953 * acpi_bay_match - see if a device is an ejectable driver bay 923 * acpi_bay_match - see if a device is an ejectable driver bay
954 * 924 *
955 * If an acpi object is ejectable and has one of the ACPI ATA methods defined, 925 * If an acpi object is ejectable and has one of the ACPI ATA methods defined,
956 * then we can safely call it an ejectable drive bay 926 * then we can safely call it an ejectable drive bay
957 */ 927 */
958 static int acpi_bay_match(struct acpi_device *device){ 928 static int acpi_bay_match(struct acpi_device *device){
959 acpi_status status; 929 acpi_status status;
960 acpi_handle handle; 930 acpi_handle handle;
961 acpi_handle tmp; 931 acpi_handle tmp;
962 acpi_handle phandle; 932 acpi_handle phandle;
963 933
964 handle = device->handle; 934 handle = device->handle;
965 935
966 status = acpi_get_handle(handle, "_EJ0", &tmp); 936 status = acpi_get_handle(handle, "_EJ0", &tmp);
967 if (ACPI_FAILURE(status)) 937 if (ACPI_FAILURE(status))
968 return -ENODEV; 938 return -ENODEV;
969 939
970 if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || 940 if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) ||
971 (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || 941 (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) ||
972 (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || 942 (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) ||
973 (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) 943 (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp))))
974 return 0; 944 return 0;
975 945
976 if (acpi_get_parent(handle, &phandle)) 946 if (acpi_get_parent(handle, &phandle))
977 return -ENODEV; 947 return -ENODEV;
978 948
979 if ((ACPI_SUCCESS(acpi_get_handle(phandle, "_GTF", &tmp))) || 949 if ((ACPI_SUCCESS(acpi_get_handle(phandle, "_GTF", &tmp))) ||
980 (ACPI_SUCCESS(acpi_get_handle(phandle, "_GTM", &tmp))) || 950 (ACPI_SUCCESS(acpi_get_handle(phandle, "_GTM", &tmp))) ||
981 (ACPI_SUCCESS(acpi_get_handle(phandle, "_STM", &tmp))) || 951 (ACPI_SUCCESS(acpi_get_handle(phandle, "_STM", &tmp))) ||
982 (ACPI_SUCCESS(acpi_get_handle(phandle, "_SDD", &tmp)))) 952 (ACPI_SUCCESS(acpi_get_handle(phandle, "_SDD", &tmp))))
983 return 0; 953 return 0;
984 954
985 return -ENODEV; 955 return -ENODEV;
986 } 956 }
987 957
988 /* 958 /*
989 * acpi_dock_match - see if a device has a _DCK method 959 * acpi_dock_match - see if a device has a _DCK method
990 */ 960 */
991 static int acpi_dock_match(struct acpi_device *device) 961 static int acpi_dock_match(struct acpi_device *device)
992 { 962 {
993 acpi_handle tmp; 963 acpi_handle tmp;
994 return acpi_get_handle(device->handle, "_DCK", &tmp); 964 return acpi_get_handle(device->handle, "_DCK", &tmp);
995 } 965 }
996 966
997 static void acpi_device_set_id(struct acpi_device *device, 967 static void acpi_device_set_id(struct acpi_device *device,
998 struct acpi_device *parent, acpi_handle handle, 968 struct acpi_device *parent, acpi_handle handle,
999 int type) 969 int type)
1000 { 970 {
1001 struct acpi_device_info *info; 971 struct acpi_device_info *info;
1002 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 972 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1003 char *hid = NULL; 973 char *hid = NULL;
1004 char *uid = NULL; 974 char *uid = NULL;
1005 struct acpi_compatible_id_list *cid_list = NULL; 975 struct acpi_compatible_id_list *cid_list = NULL;
1006 const char *cid_add = NULL; 976 const char *cid_add = NULL;
1007 acpi_status status; 977 acpi_status status;
1008 978
1009 switch (type) { 979 switch (type) {
1010 case ACPI_BUS_TYPE_DEVICE: 980 case ACPI_BUS_TYPE_DEVICE:
1011 status = acpi_get_object_info(handle, &buffer); 981 status = acpi_get_object_info(handle, &buffer);
1012 if (ACPI_FAILURE(status)) { 982 if (ACPI_FAILURE(status)) {
1013 printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); 983 printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
1014 return; 984 return;
1015 } 985 }
1016 986
1017 info = buffer.pointer; 987 info = buffer.pointer;
1018 if (info->valid & ACPI_VALID_HID) 988 if (info->valid & ACPI_VALID_HID)
1019 hid = info->hardware_id.value; 989 hid = info->hardware_id.value;
1020 if (info->valid & ACPI_VALID_UID) 990 if (info->valid & ACPI_VALID_UID)
1021 uid = info->unique_id.value; 991 uid = info->unique_id.value;
1022 if (info->valid & ACPI_VALID_CID) 992 if (info->valid & ACPI_VALID_CID)
1023 cid_list = &info->compatibility_id; 993 cid_list = &info->compatibility_id;
1024 if (info->valid & ACPI_VALID_ADR) { 994 if (info->valid & ACPI_VALID_ADR) {
1025 device->pnp.bus_address = info->address; 995 device->pnp.bus_address = info->address;
1026 device->flags.bus_address = 1; 996 device->flags.bus_address = 1;
1027 } 997 }
1028 998
1029 /* If we have a video/bay/dock device, add our selfdefined 999 /* If we have a video/bay/dock device, add our selfdefined
1030 HID to the CID list. Like that the video/bay/dock drivers 1000 HID to the CID list. Like that the video/bay/dock drivers
1031 will get autoloaded and the device might still match 1001 will get autoloaded and the device might still match
1032 against another driver. 1002 against another driver.
1033 */ 1003 */
1034 if (ACPI_SUCCESS(acpi_video_bus_match(device))) 1004 if (acpi_is_video_device(device))
1035 cid_add = ACPI_VIDEO_HID; 1005 cid_add = ACPI_VIDEO_HID;
1036 else if (ACPI_SUCCESS(acpi_bay_match(device))) 1006 else if (ACPI_SUCCESS(acpi_bay_match(device)))
1037 cid_add = ACPI_BAY_HID; 1007 cid_add = ACPI_BAY_HID;
1038 else if (ACPI_SUCCESS(acpi_dock_match(device))) 1008 else if (ACPI_SUCCESS(acpi_dock_match(device)))
1039 cid_add = ACPI_DOCK_HID; 1009 cid_add = ACPI_DOCK_HID;
1040 1010
1041 break; 1011 break;
1042 case ACPI_BUS_TYPE_POWER: 1012 case ACPI_BUS_TYPE_POWER:
1043 hid = ACPI_POWER_HID; 1013 hid = ACPI_POWER_HID;
1044 break; 1014 break;
1045 case ACPI_BUS_TYPE_PROCESSOR: 1015 case ACPI_BUS_TYPE_PROCESSOR:
1046 hid = ACPI_PROCESSOR_HID; 1016 hid = ACPI_PROCESSOR_HID;
1047 break; 1017 break;
1048 case ACPI_BUS_TYPE_SYSTEM: 1018 case ACPI_BUS_TYPE_SYSTEM:
1049 hid = ACPI_SYSTEM_HID; 1019 hid = ACPI_SYSTEM_HID;
1050 break; 1020 break;
1051 case ACPI_BUS_TYPE_THERMAL: 1021 case ACPI_BUS_TYPE_THERMAL:
1052 hid = ACPI_THERMAL_HID; 1022 hid = ACPI_THERMAL_HID;
1053 break; 1023 break;
1054 case ACPI_BUS_TYPE_POWER_BUTTON: 1024 case ACPI_BUS_TYPE_POWER_BUTTON:
1055 hid = ACPI_BUTTON_HID_POWERF; 1025 hid = ACPI_BUTTON_HID_POWERF;
1056 break; 1026 break;
1057 case ACPI_BUS_TYPE_SLEEP_BUTTON: 1027 case ACPI_BUS_TYPE_SLEEP_BUTTON:
1058 hid = ACPI_BUTTON_HID_SLEEPF; 1028 hid = ACPI_BUTTON_HID_SLEEPF;
1059 break; 1029 break;
1060 } 1030 }
1061 1031
1062 /* 1032 /*
1063 * \_SB 1033 * \_SB
1064 * ---- 1034 * ----
1065 * Fix for the system root bus device -- the only root-level device. 1035 * Fix for the system root bus device -- the only root-level device.
1066 */ 1036 */
1067 if (((acpi_handle)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) { 1037 if (((acpi_handle)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) {
1068 hid = ACPI_BUS_HID; 1038 hid = ACPI_BUS_HID;
1069 strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); 1039 strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
1070 strcpy(device->pnp.device_class, ACPI_BUS_CLASS); 1040 strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
1071 } 1041 }
1072 1042
1073 if (hid) { 1043 if (hid) {
1074 strcpy(device->pnp.hardware_id, hid); 1044 strcpy(device->pnp.hardware_id, hid);
1075 device->flags.hardware_id = 1; 1045 device->flags.hardware_id = 1;
1076 } 1046 }
1077 if (uid) { 1047 if (uid) {
1078 strcpy(device->pnp.unique_id, uid); 1048 strcpy(device->pnp.unique_id, uid);
1079 device->flags.unique_id = 1; 1049 device->flags.unique_id = 1;
1080 } 1050 }
1081 if (cid_list || cid_add) { 1051 if (cid_list || cid_add) {
1082 struct acpi_compatible_id_list *list; 1052 struct acpi_compatible_id_list *list;
1083 int size = 0; 1053 int size = 0;
1084 int count = 0; 1054 int count = 0;
1085 1055
1086 if (cid_list) { 1056 if (cid_list) {
1087 size = cid_list->size; 1057 size = cid_list->size;
1088 } else if (cid_add) { 1058 } else if (cid_add) {
1089 size = sizeof(struct acpi_compatible_id_list); 1059 size = sizeof(struct acpi_compatible_id_list);
1090 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); 1060 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
1091 if (!cid_list) { 1061 if (!cid_list) {
1092 printk(KERN_ERR "Memory allocation error\n"); 1062 printk(KERN_ERR "Memory allocation error\n");
1093 kfree(buffer.pointer); 1063 kfree(buffer.pointer);
1094 return; 1064 return;
1095 } else { 1065 } else {
1096 cid_list->count = 0; 1066 cid_list->count = 0;
1097 cid_list->size = size; 1067 cid_list->size = size;
1098 } 1068 }
1099 } 1069 }
1100 if (cid_add) 1070 if (cid_add)
1101 size += sizeof(struct acpi_compatible_id); 1071 size += sizeof(struct acpi_compatible_id);
1102 list = kmalloc(size, GFP_KERNEL); 1072 list = kmalloc(size, GFP_KERNEL);
1103 1073
1104 if (list) { 1074 if (list) {
1105 if (cid_list) { 1075 if (cid_list) {
1106 memcpy(list, cid_list, cid_list->size); 1076 memcpy(list, cid_list, cid_list->size);
1107 count = cid_list->count; 1077 count = cid_list->count;
1108 } 1078 }
1109 if (cid_add) { 1079 if (cid_add) {
1110 strncpy(list->id[count].value, cid_add, 1080 strncpy(list->id[count].value, cid_add,
1111 ACPI_MAX_CID_LENGTH); 1081 ACPI_MAX_CID_LENGTH);
1112 count++; 1082 count++;
1113 device->flags.compatible_ids = 1; 1083 device->flags.compatible_ids = 1;
1114 } 1084 }
1115 list->size = size; 1085 list->size = size;
1116 list->count = count; 1086 list->count = count;
1117 device->pnp.cid_list = list; 1087 device->pnp.cid_list = list;
1118 } else 1088 } else
1119 printk(KERN_ERR PREFIX "Memory allocation error\n"); 1089 printk(KERN_ERR PREFIX "Memory allocation error\n");
1120 } 1090 }
1121 1091
1122 kfree(buffer.pointer); 1092 kfree(buffer.pointer);
1123 } 1093 }
1124 1094
1125 static int acpi_device_set_context(struct acpi_device *device, int type) 1095 static int acpi_device_set_context(struct acpi_device *device, int type)
1126 { 1096 {
1127 acpi_status status = AE_OK; 1097 acpi_status status = AE_OK;
1128 int result = 0; 1098 int result = 0;
1129 /* 1099 /*
1130 * Context 1100 * Context
1131 * ------- 1101 * -------
1132 * Attach this 'struct acpi_device' to the ACPI object. This makes 1102 * Attach this 'struct acpi_device' to the ACPI object. This makes
1133 * resolutions from handle->device very efficient. Note that we need 1103 * resolutions from handle->device very efficient. Note that we need
1134 * to be careful with fixed-feature devices as they all attach to the 1104 * to be careful with fixed-feature devices as they all attach to the
1135 * root object. 1105 * root object.
1136 */ 1106 */
1137 if (type != ACPI_BUS_TYPE_POWER_BUTTON && 1107 if (type != ACPI_BUS_TYPE_POWER_BUTTON &&
1138 type != ACPI_BUS_TYPE_SLEEP_BUTTON) { 1108 type != ACPI_BUS_TYPE_SLEEP_BUTTON) {
1139 status = acpi_attach_data(device->handle, 1109 status = acpi_attach_data(device->handle,
1140 acpi_bus_data_handler, device); 1110 acpi_bus_data_handler, device);
1141 1111
1142 if (ACPI_FAILURE(status)) { 1112 if (ACPI_FAILURE(status)) {
1143 printk(KERN_ERR PREFIX "Error attaching device data\n"); 1113 printk(KERN_ERR PREFIX "Error attaching device data\n");
1144 result = -ENODEV; 1114 result = -ENODEV;
1145 } 1115 }
1146 } 1116 }
1147 return result; 1117 return result;
1148 } 1118 }
1149 1119
1150 static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) 1120 static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
1151 { 1121 {
1152 if (!dev) 1122 if (!dev)
1153 return -EINVAL; 1123 return -EINVAL;
1154 1124
1155 dev->removal_type = ACPI_BUS_REMOVAL_EJECT; 1125 dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
1156 device_release_driver(&dev->dev); 1126 device_release_driver(&dev->dev);
1157 1127
1158 if (!rmdevice) 1128 if (!rmdevice)
1159 return 0; 1129 return 0;
1160 1130
1161 /* 1131 /*
1162 * unbind _ADR-Based Devices when hot removal 1132 * unbind _ADR-Based Devices when hot removal
1163 */ 1133 */
1164 if (dev->flags.bus_address) { 1134 if (dev->flags.bus_address) {
1165 if ((dev->parent) && (dev->parent->ops.unbind)) 1135 if ((dev->parent) && (dev->parent->ops.unbind))
1166 dev->parent->ops.unbind(dev); 1136 dev->parent->ops.unbind(dev);
1167 } 1137 }
1168 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); 1138 acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
1169 1139
1170 return 0; 1140 return 0;
1171 } 1141 }
1172 1142
1173 static int 1143 static int
1174 acpi_add_single_object(struct acpi_device **child, 1144 acpi_add_single_object(struct acpi_device **child,
1175 struct acpi_device *parent, acpi_handle handle, int type, 1145 struct acpi_device *parent, acpi_handle handle, int type,
1176 struct acpi_bus_ops *ops) 1146 struct acpi_bus_ops *ops)
1177 { 1147 {
1178 int result = 0; 1148 int result = 0;
1179 struct acpi_device *device = NULL; 1149 struct acpi_device *device = NULL;
1180 1150
1181 1151
1182 if (!child) 1152 if (!child)
1183 return -EINVAL; 1153 return -EINVAL;
1184 1154
1185 device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); 1155 device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
1186 if (!device) { 1156 if (!device) {
1187 printk(KERN_ERR PREFIX "Memory allocation error\n"); 1157 printk(KERN_ERR PREFIX "Memory allocation error\n");
1188 return -ENOMEM; 1158 return -ENOMEM;
1189 } 1159 }
1190 1160
1191 device->handle = handle; 1161 device->handle = handle;
1192 device->parent = parent; 1162 device->parent = parent;
1193 device->bus_ops = *ops; /* workround for not call .start */ 1163 device->bus_ops = *ops; /* workround for not call .start */
1194 1164
1195 1165
1196 acpi_device_get_busid(device, handle, type); 1166 acpi_device_get_busid(device, handle, type);
1197 1167
1198 /* 1168 /*
1199 * Flags 1169 * Flags
1200 * ----- 1170 * -----
1201 * Get prior to calling acpi_bus_get_status() so we know whether 1171 * Get prior to calling acpi_bus_get_status() so we know whether
1202 * or not _STA is present. Note that we only look for object 1172 * or not _STA is present. Note that we only look for object
1203 * handles -- cannot evaluate objects until we know the device is 1173 * handles -- cannot evaluate objects until we know the device is
1204 * present and properly initialized. 1174 * present and properly initialized.
1205 */ 1175 */
1206 result = acpi_bus_get_flags(device); 1176 result = acpi_bus_get_flags(device);
1207 if (result) 1177 if (result)
1208 goto end; 1178 goto end;
1209 1179
1210 /* 1180 /*
1211 * Status 1181 * Status
1212 * ------ 1182 * ------
1213 * See if the device is present. We always assume that non-Device 1183 * See if the device is present. We always assume that non-Device
1214 * and non-Processor objects (e.g. thermal zones, power resources, 1184 * and non-Processor objects (e.g. thermal zones, power resources,
1215 * etc.) are present, functioning, etc. (at least when parent object 1185 * etc.) are present, functioning, etc. (at least when parent object
1216 * is present). Note that _STA has a different meaning for some 1186 * is present). Note that _STA has a different meaning for some
1217 * objects (e.g. power resources) so we need to be careful how we use 1187 * objects (e.g. power resources) so we need to be careful how we use
1218 * it. 1188 * it.
1219 */ 1189 */
1220 switch (type) { 1190 switch (type) {
1221 case ACPI_BUS_TYPE_PROCESSOR: 1191 case ACPI_BUS_TYPE_PROCESSOR:
1222 case ACPI_BUS_TYPE_DEVICE: 1192 case ACPI_BUS_TYPE_DEVICE:
1223 result = acpi_bus_get_status(device); 1193 result = acpi_bus_get_status(device);
1224 if (ACPI_FAILURE(result)) { 1194 if (ACPI_FAILURE(result)) {
1225 result = -ENODEV; 1195 result = -ENODEV;
1226 goto end; 1196 goto end;
1227 } 1197 }
1228 /* 1198 /*
1229 * When the device is neither present nor functional, the 1199 * When the device is neither present nor functional, the
1230 * device should not be added to Linux ACPI device tree. 1200 * device should not be added to Linux ACPI device tree.
1231 * When the status of the device is not present but functinal, 1201 * When the status of the device is not present but functinal,
1232 * it should be added to Linux ACPI tree. For example : bay 1202 * it should be added to Linux ACPI tree. For example : bay
1233 * device , dock device. 1203 * device , dock device.
1234 * In such conditions it is unncessary to check whether it is 1204 * In such conditions it is unncessary to check whether it is
1235 * bay device or dock device. 1205 * bay device or dock device.
1236 */ 1206 */
1237 if (!device->status.present && !device->status.functional) { 1207 if (!device->status.present && !device->status.functional) {
1238 result = -ENODEV; 1208 result = -ENODEV;
1239 goto end; 1209 goto end;
1240 } 1210 }
1241 break; 1211 break;
1242 default: 1212 default:
1243 STRUCT_TO_INT(device->status) = 1213 STRUCT_TO_INT(device->status) =
1244 ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | 1214 ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
1245 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; 1215 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING;
1246 break; 1216 break;
1247 } 1217 }
1248 1218
1249 /* 1219 /*
1250 * Initialize Device 1220 * Initialize Device
1251 * ----------------- 1221 * -----------------
1252 * TBD: Synch with Core's enumeration/initialization process. 1222 * TBD: Synch with Core's enumeration/initialization process.
1253 */ 1223 */
1254 1224
1255 /* 1225 /*
1256 * Hardware ID, Unique ID, & Bus Address 1226 * Hardware ID, Unique ID, & Bus Address
1257 * ------------------------------------- 1227 * -------------------------------------
1258 */ 1228 */
1259 acpi_device_set_id(device, parent, handle, type); 1229 acpi_device_set_id(device, parent, handle, type);
1260 1230
1261 /* 1231 /*
1262 * The ACPI device is attached to acpi handle before getting 1232 * The ACPI device is attached to acpi handle before getting
1263 * the power/wakeup/peformance flags. Otherwise OS can't get 1233 * the power/wakeup/peformance flags. Otherwise OS can't get
1264 * the corresponding ACPI device by the acpi handle in the course 1234 * the corresponding ACPI device by the acpi handle in the course
1265 * of getting the power/wakeup/performance flags. 1235 * of getting the power/wakeup/performance flags.
1266 */ 1236 */
1267 result = acpi_device_set_context(device, type); 1237 result = acpi_device_set_context(device, type);
1268 if (result) 1238 if (result)
1269 goto end; 1239 goto end;
1270 1240
1271 /* 1241 /*
1272 * Power Management 1242 * Power Management
1273 * ---------------- 1243 * ----------------
1274 */ 1244 */
1275 if (device->flags.power_manageable) { 1245 if (device->flags.power_manageable) {
1276 result = acpi_bus_get_power_flags(device); 1246 result = acpi_bus_get_power_flags(device);
1277 if (result) 1247 if (result)
1278 goto end; 1248 goto end;
1279 } 1249 }
1280 1250
1281 /* 1251 /*
1282 * Wakeup device management 1252 * Wakeup device management
1283 *----------------------- 1253 *-----------------------
1284 */ 1254 */
1285 if (device->flags.wake_capable) { 1255 if (device->flags.wake_capable) {
1286 result = acpi_bus_get_wakeup_device_flags(device); 1256 result = acpi_bus_get_wakeup_device_flags(device);
1287 if (result) 1257 if (result)
1288 goto end; 1258 goto end;
1289 } 1259 }
1290 1260
1291 /* 1261 /*
1292 * Performance Management 1262 * Performance Management
1293 * ---------------------- 1263 * ----------------------
1294 */ 1264 */
1295 if (device->flags.performance_manageable) { 1265 if (device->flags.performance_manageable) {
1296 result = acpi_bus_get_perf_flags(device); 1266 result = acpi_bus_get_perf_flags(device);
1297 if (result) 1267 if (result)
1298 goto end; 1268 goto end;
1299 } 1269 }
1300 1270
1301 1271
1302 result = acpi_device_register(device, parent); 1272 result = acpi_device_register(device, parent);
1303 1273
1304 /* 1274 /*
1305 * Bind _ADR-Based Devices when hot add 1275 * Bind _ADR-Based Devices when hot add
1306 */ 1276 */
1307 if (device->flags.bus_address) { 1277 if (device->flags.bus_address) {
1308 if (device->parent && device->parent->ops.bind) 1278 if (device->parent && device->parent->ops.bind)
1309 device->parent->ops.bind(device); 1279 device->parent->ops.bind(device);
1310 } 1280 }
1311 1281
1312 end: 1282 end:
1313 if (!result) 1283 if (!result)
1314 *child = device; 1284 *child = device;
1315 else { 1285 else {
1316 kfree(device->pnp.cid_list); 1286 kfree(device->pnp.cid_list);
1317 kfree(device); 1287 kfree(device);
1318 } 1288 }
1319 1289
1320 return result; 1290 return result;
1321 } 1291 }
1322 1292
1323 static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) 1293 static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
1324 { 1294 {
1325 acpi_status status = AE_OK; 1295 acpi_status status = AE_OK;
1326 struct acpi_device *parent = NULL; 1296 struct acpi_device *parent = NULL;
1327 struct acpi_device *child = NULL; 1297 struct acpi_device *child = NULL;
1328 acpi_handle phandle = NULL; 1298 acpi_handle phandle = NULL;
1329 acpi_handle chandle = NULL; 1299 acpi_handle chandle = NULL;
1330 acpi_object_type type = 0; 1300 acpi_object_type type = 0;
1331 u32 level = 1; 1301 u32 level = 1;
1332 1302
1333 1303
1334 if (!start) 1304 if (!start)
1335 return -EINVAL; 1305 return -EINVAL;
1336 1306
1337 parent = start; 1307 parent = start;
1338 phandle = start->handle; 1308 phandle = start->handle;
1339 1309
1340 /* 1310 /*
1341 * Parse through the ACPI namespace, identify all 'devices', and 1311 * Parse through the ACPI namespace, identify all 'devices', and
1342 * create a new 'struct acpi_device' for each. 1312 * create a new 'struct acpi_device' for each.
1343 */ 1313 */
1344 while ((level > 0) && parent) { 1314 while ((level > 0) && parent) {
1345 1315
1346 status = acpi_get_next_object(ACPI_TYPE_ANY, phandle, 1316 status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
1347 chandle, &chandle); 1317 chandle, &chandle);
1348 1318
1349 /* 1319 /*
1350 * If this scope is exhausted then move our way back up. 1320 * If this scope is exhausted then move our way back up.
1351 */ 1321 */
1352 if (ACPI_FAILURE(status)) { 1322 if (ACPI_FAILURE(status)) {
1353 level--; 1323 level--;
1354 chandle = phandle; 1324 chandle = phandle;
1355 acpi_get_parent(phandle, &phandle); 1325 acpi_get_parent(phandle, &phandle);
1356 if (parent->parent) 1326 if (parent->parent)
1357 parent = parent->parent; 1327 parent = parent->parent;
1358 continue; 1328 continue;
1359 } 1329 }
1360 1330
1361 status = acpi_get_type(chandle, &type); 1331 status = acpi_get_type(chandle, &type);
1362 if (ACPI_FAILURE(status)) 1332 if (ACPI_FAILURE(status))
1363 continue; 1333 continue;
1364 1334
1365 /* 1335 /*
1366 * If this is a scope object then parse it (depth-first). 1336 * If this is a scope object then parse it (depth-first).
1367 */ 1337 */
1368 if (type == ACPI_TYPE_LOCAL_SCOPE) { 1338 if (type == ACPI_TYPE_LOCAL_SCOPE) {
1369 level++; 1339 level++;
1370 phandle = chandle; 1340 phandle = chandle;
1371 chandle = NULL; 1341 chandle = NULL;
1372 continue; 1342 continue;
1373 } 1343 }
1374 1344
1375 /* 1345 /*
1376 * We're only interested in objects that we consider 'devices'. 1346 * We're only interested in objects that we consider 'devices'.
1377 */ 1347 */
1378 switch (type) { 1348 switch (type) {
1379 case ACPI_TYPE_DEVICE: 1349 case ACPI_TYPE_DEVICE:
1380 type = ACPI_BUS_TYPE_DEVICE; 1350 type = ACPI_BUS_TYPE_DEVICE;
1381 break; 1351 break;
1382 case ACPI_TYPE_PROCESSOR: 1352 case ACPI_TYPE_PROCESSOR:
1383 type = ACPI_BUS_TYPE_PROCESSOR; 1353 type = ACPI_BUS_TYPE_PROCESSOR;
1384 break; 1354 break;
1385 case ACPI_TYPE_THERMAL: 1355 case ACPI_TYPE_THERMAL:
1386 type = ACPI_BUS_TYPE_THERMAL; 1356 type = ACPI_BUS_TYPE_THERMAL;
1387 break; 1357 break;
1388 case ACPI_TYPE_POWER: 1358 case ACPI_TYPE_POWER:
1389 type = ACPI_BUS_TYPE_POWER; 1359 type = ACPI_BUS_TYPE_POWER;
1390 break; 1360 break;
1391 default: 1361 default:
1392 continue; 1362 continue;
1393 } 1363 }
1394 1364
1395 if (ops->acpi_op_add) 1365 if (ops->acpi_op_add)
1396 status = acpi_add_single_object(&child, parent, 1366 status = acpi_add_single_object(&child, parent,
1397 chandle, type, ops); 1367 chandle, type, ops);
1398 else 1368 else
1399 status = acpi_bus_get_device(chandle, &child); 1369 status = acpi_bus_get_device(chandle, &child);
1400 1370
1401 if (ACPI_FAILURE(status)) 1371 if (ACPI_FAILURE(status))
1402 continue; 1372 continue;
1403 1373
1404 if (ops->acpi_op_start && !(ops->acpi_op_add)) { 1374 if (ops->acpi_op_start && !(ops->acpi_op_add)) {
1405 status = acpi_start_single_object(child); 1375 status = acpi_start_single_object(child);
1406 if (ACPI_FAILURE(status)) 1376 if (ACPI_FAILURE(status))
1407 continue; 1377 continue;
1408 } 1378 }
1409 1379
1410 /* 1380 /*
1411 * If the device is present, enabled, and functioning then 1381 * If the device is present, enabled, and functioning then
1412 * parse its scope (depth-first). Note that we need to 1382 * parse its scope (depth-first). Note that we need to
1413 * represent absent devices to facilitate PnP notifications 1383 * represent absent devices to facilitate PnP notifications
1414 * -- but only the subtree head (not all of its children, 1384 * -- but only the subtree head (not all of its children,
1415 * which will be enumerated when the parent is inserted). 1385 * which will be enumerated when the parent is inserted).
1416 * 1386 *
1417 * TBD: Need notifications and other detection mechanisms 1387 * TBD: Need notifications and other detection mechanisms
1418 * in place before we can fully implement this. 1388 * in place before we can fully implement this.
1419 */ 1389 */
1420 /* 1390 /*
1421 * When the device is not present but functional, it is also 1391 * When the device is not present but functional, it is also
1422 * necessary to scan the children of this device. 1392 * necessary to scan the children of this device.
1423 */ 1393 */
1424 if (child->status.present || (!child->status.present && 1394 if (child->status.present || (!child->status.present &&
1425 child->status.functional)) { 1395 child->status.functional)) {
1426 status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, 1396 status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
1427 NULL, NULL); 1397 NULL, NULL);
1428 if (ACPI_SUCCESS(status)) { 1398 if (ACPI_SUCCESS(status)) {
1429 level++; 1399 level++;
1430 phandle = chandle; 1400 phandle = chandle;
1431 chandle = NULL; 1401 chandle = NULL;
1432 parent = child; 1402 parent = child;
1433 } 1403 }
1434 } 1404 }
1435 } 1405 }
1436 1406
1437 return 0; 1407 return 0;
1438 } 1408 }
1439 1409
1440 int 1410 int
1441 acpi_bus_add(struct acpi_device **child, 1411 acpi_bus_add(struct acpi_device **child,
1442 struct acpi_device *parent, acpi_handle handle, int type) 1412 struct acpi_device *parent, acpi_handle handle, int type)
1443 { 1413 {
1444 int result; 1414 int result;
1445 struct acpi_bus_ops ops; 1415 struct acpi_bus_ops ops;
1446 1416
1447 memset(&ops, 0, sizeof(ops)); 1417 memset(&ops, 0, sizeof(ops));
1448 ops.acpi_op_add = 1; 1418 ops.acpi_op_add = 1;
1449 1419
1450 result = acpi_add_single_object(child, parent, handle, type, &ops); 1420 result = acpi_add_single_object(child, parent, handle, type, &ops);
1451 if (!result) 1421 if (!result)
1452 result = acpi_bus_scan(*child, &ops); 1422 result = acpi_bus_scan(*child, &ops);
1453 1423
1454 return result; 1424 return result;
1455 } 1425 }
1456 1426
1457 EXPORT_SYMBOL(acpi_bus_add); 1427 EXPORT_SYMBOL(acpi_bus_add);
1458 1428
1459 int acpi_bus_start(struct acpi_device *device) 1429 int acpi_bus_start(struct acpi_device *device)
1460 { 1430 {
1461 int result; 1431 int result;
1462 struct acpi_bus_ops ops; 1432 struct acpi_bus_ops ops;
1463 1433
1464 1434
1465 if (!device) 1435 if (!device)
1466 return -EINVAL; 1436 return -EINVAL;
1467 1437
1468 result = acpi_start_single_object(device); 1438 result = acpi_start_single_object(device);
1469 if (!result) { 1439 if (!result) {
1470 memset(&ops, 0, sizeof(ops)); 1440 memset(&ops, 0, sizeof(ops));
1471 ops.acpi_op_start = 1; 1441 ops.acpi_op_start = 1;
1472 result = acpi_bus_scan(device, &ops); 1442 result = acpi_bus_scan(device, &ops);
1473 } 1443 }
1474 return result; 1444 return result;
1475 } 1445 }
1476 1446
1477 EXPORT_SYMBOL(acpi_bus_start); 1447 EXPORT_SYMBOL(acpi_bus_start);
1478 1448
1479 int acpi_bus_trim(struct acpi_device *start, int rmdevice) 1449 int acpi_bus_trim(struct acpi_device *start, int rmdevice)
1480 { 1450 {
1481 acpi_status status; 1451 acpi_status status;
1482 struct acpi_device *parent, *child; 1452 struct acpi_device *parent, *child;
1483 acpi_handle phandle, chandle; 1453 acpi_handle phandle, chandle;
1484 acpi_object_type type; 1454 acpi_object_type type;
1485 u32 level = 1; 1455 u32 level = 1;
1486 int err = 0; 1456 int err = 0;
1487 1457
1488 parent = start; 1458 parent = start;
1489 phandle = start->handle; 1459 phandle = start->handle;
1490 child = chandle = NULL; 1460 child = chandle = NULL;
1491 1461
1492 while ((level > 0) && parent && (!err)) { 1462 while ((level > 0) && parent && (!err)) {
1493 status = acpi_get_next_object(ACPI_TYPE_ANY, phandle, 1463 status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
1494 chandle, &chandle); 1464 chandle, &chandle);
1495 1465
1496 /* 1466 /*
1497 * If this scope is exhausted then move our way back up. 1467 * If this scope is exhausted then move our way back up.
1498 */ 1468 */
1499 if (ACPI_FAILURE(status)) { 1469 if (ACPI_FAILURE(status)) {
1500 level--; 1470 level--;
1501 chandle = phandle; 1471 chandle = phandle;
1502 acpi_get_parent(phandle, &phandle); 1472 acpi_get_parent(phandle, &phandle);
1503 child = parent; 1473 child = parent;
1504 parent = parent->parent; 1474 parent = parent->parent;
1505 1475
1506 if (level == 0) 1476 if (level == 0)
1507 err = acpi_bus_remove(child, rmdevice); 1477 err = acpi_bus_remove(child, rmdevice);
1508 else 1478 else
1509 err = acpi_bus_remove(child, 1); 1479 err = acpi_bus_remove(child, 1);
1510 1480
1511 continue; 1481 continue;
1512 } 1482 }
1513 1483
1514 status = acpi_get_type(chandle, &type); 1484 status = acpi_get_type(chandle, &type);
1515 if (ACPI_FAILURE(status)) { 1485 if (ACPI_FAILURE(status)) {
1516 continue; 1486 continue;
1517 } 1487 }
1518 /* 1488 /*
1519 * If there is a device corresponding to chandle then 1489 * If there is a device corresponding to chandle then
1520 * parse it (depth-first). 1490 * parse it (depth-first).
1521 */ 1491 */
1522 if (acpi_bus_get_device(chandle, &child) == 0) { 1492 if (acpi_bus_get_device(chandle, &child) == 0) {
1523 level++; 1493 level++;
1524 phandle = chandle; 1494 phandle = chandle;
1525 chandle = NULL; 1495 chandle = NULL;
1526 parent = child; 1496 parent = child;
1527 } 1497 }
1528 continue; 1498 continue;
1529 } 1499 }
1530 return err; 1500 return err;
1531 } 1501 }
1532 EXPORT_SYMBOL_GPL(acpi_bus_trim); 1502 EXPORT_SYMBOL_GPL(acpi_bus_trim);
1533 1503
1534 1504
1535 static int acpi_bus_scan_fixed(struct acpi_device *root) 1505 static int acpi_bus_scan_fixed(struct acpi_device *root)
1536 { 1506 {
1537 int result = 0; 1507 int result = 0;
1538 struct acpi_device *device = NULL; 1508 struct acpi_device *device = NULL;
1539 struct acpi_bus_ops ops; 1509 struct acpi_bus_ops ops;
1540 1510
1541 if (!root) 1511 if (!root)
1542 return -ENODEV; 1512 return -ENODEV;
1543 1513
1544 memset(&ops, 0, sizeof(ops)); 1514 memset(&ops, 0, sizeof(ops));
1545 ops.acpi_op_add = 1; 1515 ops.acpi_op_add = 1;
1546 ops.acpi_op_start = 1; 1516 ops.acpi_op_start = 1;
1547 1517
1548 /* 1518 /*
1549 * Enumerate all fixed-feature devices. 1519 * Enumerate all fixed-feature devices.
1550 */ 1520 */
1551 if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { 1521 if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
1552 result = acpi_add_single_object(&device, acpi_root, 1522 result = acpi_add_single_object(&device, acpi_root,
1553 NULL, 1523 NULL,
1554 ACPI_BUS_TYPE_POWER_BUTTON, 1524 ACPI_BUS_TYPE_POWER_BUTTON,
1555 &ops); 1525 &ops);
1556 } 1526 }
1557 1527
1558 if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { 1528 if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
1559 result = acpi_add_single_object(&device, acpi_root, 1529 result = acpi_add_single_object(&device, acpi_root,
1560 NULL, 1530 NULL,
1561 ACPI_BUS_TYPE_SLEEP_BUTTON, 1531 ACPI_BUS_TYPE_SLEEP_BUTTON,
1562 &ops); 1532 &ops);
1563 } 1533 }
1564 1534
1565 return result; 1535 return result;
1566 } 1536 }
1567 1537
1568 1538
1569 static int __init acpi_scan_init(void) 1539 static int __init acpi_scan_init(void)
1570 { 1540 {
1571 int result; 1541 int result;
1572 struct acpi_bus_ops ops; 1542 struct acpi_bus_ops ops;
1573 1543
1574 1544
1575 if (acpi_disabled) 1545 if (acpi_disabled)
1576 return 0; 1546 return 0;
1577 1547
1578 memset(&ops, 0, sizeof(ops)); 1548 memset(&ops, 0, sizeof(ops));
1579 ops.acpi_op_add = 1; 1549 ops.acpi_op_add = 1;
1580 ops.acpi_op_start = 1; 1550 ops.acpi_op_start = 1;
1581 1551
1582 result = bus_register(&acpi_bus_type); 1552 result = bus_register(&acpi_bus_type);
1583 if (result) { 1553 if (result) {
1584 /* We don't want to quit even if we failed to add suspend/resume */ 1554 /* We don't want to quit even if we failed to add suspend/resume */
1585 printk(KERN_ERR PREFIX "Could not register bus type\n"); 1555 printk(KERN_ERR PREFIX "Could not register bus type\n");
1586 } 1556 }
1587 1557
1588 /* 1558 /*
1589 * Create the root device in the bus's device tree 1559 * Create the root device in the bus's device tree
1590 */ 1560 */
1591 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, 1561 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
1592 ACPI_BUS_TYPE_SYSTEM, &ops); 1562 ACPI_BUS_TYPE_SYSTEM, &ops);
1593 if (result) 1563 if (result)
1594 goto Done; 1564 goto Done;
1595 1565
1596 /* 1566 /*
1597 * Enumerate devices in the ACPI namespace. 1567 * Enumerate devices in the ACPI namespace.
1598 */ 1568 */
1599 result = acpi_bus_scan_fixed(acpi_root); 1569 result = acpi_bus_scan_fixed(acpi_root);
1600 1570
1601 if (!result) 1571 if (!result)
1602 result = acpi_bus_scan(acpi_root, &ops); 1572 result = acpi_bus_scan(acpi_root, &ops);
1603 1573
1604 if (result) 1574 if (result)
1605 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1575 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
1606 1576
1607 Done: 1577 Done:
1608 return result; 1578 return result;
1609 } 1579 }
1610 1580
1611 subsys_initcall(acpi_scan_init); 1581 subsys_initcall(acpi_scan_init);
1612 1582
drivers/acpi/video.c
1 /* 1 /*
2 * video.c - ACPI Video Driver ($Revision:$) 2 * video.c - ACPI Video Driver ($Revision:$)
3 * 3 *
4 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> 4 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
5 * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> 5 * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
6 * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net> 6 * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net>
7 * 7 *
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at 12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version. 13 * your option) any later version.
14 * 14 *
15 * This program is distributed in the hope that it will be useful, but 15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details. 18 * General Public License for more details.
19 * 19 *
20 * You should have received a copy of the GNU General Public License along 20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc., 21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 * 23 *
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 */ 25 */
26 26
27 #include <linux/kernel.h> 27 #include <linux/kernel.h>
28 #include <linux/module.h> 28 #include <linux/module.h>
29 #include <linux/init.h> 29 #include <linux/init.h>
30 #include <linux/types.h> 30 #include <linux/types.h>
31 #include <linux/list.h> 31 #include <linux/list.h>
32 #include <linux/mutex.h> 32 #include <linux/mutex.h>
33 #include <linux/proc_fs.h> 33 #include <linux/proc_fs.h>
34 #include <linux/seq_file.h> 34 #include <linux/seq_file.h>
35 #include <linux/input.h> 35 #include <linux/input.h>
36 #include <linux/backlight.h> 36 #include <linux/backlight.h>
37 #include <linux/thermal.h> 37 #include <linux/thermal.h>
38 #include <linux/video_output.h> 38 #include <linux/video_output.h>
39 #include <asm/uaccess.h> 39 #include <asm/uaccess.h>
40 40
41 #include <acpi/acpi_bus.h> 41 #include <acpi/acpi_bus.h>
42 #include <acpi/acpi_drivers.h> 42 #include <acpi/acpi_drivers.h>
43 43
44 #define ACPI_VIDEO_CLASS "video" 44 #define ACPI_VIDEO_CLASS "video"
45 #define ACPI_VIDEO_BUS_NAME "Video Bus" 45 #define ACPI_VIDEO_BUS_NAME "Video Bus"
46 #define ACPI_VIDEO_DEVICE_NAME "Video Device" 46 #define ACPI_VIDEO_DEVICE_NAME "Video Device"
47 #define ACPI_VIDEO_NOTIFY_SWITCH 0x80 47 #define ACPI_VIDEO_NOTIFY_SWITCH 0x80
48 #define ACPI_VIDEO_NOTIFY_PROBE 0x81 48 #define ACPI_VIDEO_NOTIFY_PROBE 0x81
49 #define ACPI_VIDEO_NOTIFY_CYCLE 0x82 49 #define ACPI_VIDEO_NOTIFY_CYCLE 0x82
50 #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 50 #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
51 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 51 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
52 52
53 #define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85 53 #define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85
54 #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 54 #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
55 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 55 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
56 #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 56 #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
57 #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 57 #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
58 58
59 #define MAX_NAME_LEN 20 59 #define MAX_NAME_LEN 20
60 60
61 #define ACPI_VIDEO_DISPLAY_CRT 1 61 #define ACPI_VIDEO_DISPLAY_CRT 1
62 #define ACPI_VIDEO_DISPLAY_TV 2 62 #define ACPI_VIDEO_DISPLAY_TV 2
63 #define ACPI_VIDEO_DISPLAY_DVI 3 63 #define ACPI_VIDEO_DISPLAY_DVI 3
64 #define ACPI_VIDEO_DISPLAY_LCD 4 64 #define ACPI_VIDEO_DISPLAY_LCD 4
65 65
66 #define _COMPONENT ACPI_VIDEO_COMPONENT 66 #define _COMPONENT ACPI_VIDEO_COMPONENT
67 ACPI_MODULE_NAME("video"); 67 ACPI_MODULE_NAME("video");
68 68
69 MODULE_AUTHOR("Bruno Ducrot"); 69 MODULE_AUTHOR("Bruno Ducrot");
70 MODULE_DESCRIPTION("ACPI Video Driver"); 70 MODULE_DESCRIPTION("ACPI Video Driver");
71 MODULE_LICENSE("GPL"); 71 MODULE_LICENSE("GPL");
72 72
73 static int brightness_switch_enabled = 1; 73 static int brightness_switch_enabled = 1;
74 module_param(brightness_switch_enabled, bool, 0644); 74 module_param(brightness_switch_enabled, bool, 0644);
75 75
76 static int acpi_video_bus_add(struct acpi_device *device); 76 static int acpi_video_bus_add(struct acpi_device *device);
77 static int acpi_video_bus_remove(struct acpi_device *device, int type); 77 static int acpi_video_bus_remove(struct acpi_device *device, int type);
78 static int acpi_video_resume(struct acpi_device *device); 78 static int acpi_video_resume(struct acpi_device *device);
79 79
80 static const struct acpi_device_id video_device_ids[] = { 80 static const struct acpi_device_id video_device_ids[] = {
81 {ACPI_VIDEO_HID, 0}, 81 {ACPI_VIDEO_HID, 0},
82 {"", 0}, 82 {"", 0},
83 }; 83 };
84 MODULE_DEVICE_TABLE(acpi, video_device_ids); 84 MODULE_DEVICE_TABLE(acpi, video_device_ids);
85 85
86 static struct acpi_driver acpi_video_bus = { 86 static struct acpi_driver acpi_video_bus = {
87 .name = "video", 87 .name = "video",
88 .class = ACPI_VIDEO_CLASS, 88 .class = ACPI_VIDEO_CLASS,
89 .ids = video_device_ids, 89 .ids = video_device_ids,
90 .ops = { 90 .ops = {
91 .add = acpi_video_bus_add, 91 .add = acpi_video_bus_add,
92 .remove = acpi_video_bus_remove, 92 .remove = acpi_video_bus_remove,
93 .resume = acpi_video_resume, 93 .resume = acpi_video_resume,
94 }, 94 },
95 }; 95 };
96 96
97 struct acpi_video_bus_flags { 97 struct acpi_video_bus_flags {
98 u8 multihead:1; /* can switch video heads */ 98 u8 multihead:1; /* can switch video heads */
99 u8 rom:1; /* can retrieve a video rom */ 99 u8 rom:1; /* can retrieve a video rom */
100 u8 post:1; /* can configure the head to */ 100 u8 post:1; /* can configure the head to */
101 u8 reserved:5; 101 u8 reserved:5;
102 }; 102 };
103 103
104 struct acpi_video_bus_cap { 104 struct acpi_video_bus_cap {
105 u8 _DOS:1; /*Enable/Disable output switching */ 105 u8 _DOS:1; /*Enable/Disable output switching */
106 u8 _DOD:1; /*Enumerate all devices attached to display adapter */ 106 u8 _DOD:1; /*Enumerate all devices attached to display adapter */
107 u8 _ROM:1; /*Get ROM Data */ 107 u8 _ROM:1; /*Get ROM Data */
108 u8 _GPD:1; /*Get POST Device */ 108 u8 _GPD:1; /*Get POST Device */
109 u8 _SPD:1; /*Set POST Device */ 109 u8 _SPD:1; /*Set POST Device */
110 u8 _VPO:1; /*Video POST Options */ 110 u8 _VPO:1; /*Video POST Options */
111 u8 reserved:2; 111 u8 reserved:2;
112 }; 112 };
113 113
114 struct acpi_video_device_attrib { 114 struct acpi_video_device_attrib {
115 u32 display_index:4; /* A zero-based instance of the Display */ 115 u32 display_index:4; /* A zero-based instance of the Display */
116 u32 display_port_attachment:4; /*This field differentiates the display type */ 116 u32 display_port_attachment:4; /*This field differentiates the display type */
117 u32 display_type:4; /*Describe the specific type in use */ 117 u32 display_type:4; /*Describe the specific type in use */
118 u32 vendor_specific:4; /*Chipset Vendor Specific */ 118 u32 vendor_specific:4; /*Chipset Vendor Specific */
119 u32 bios_can_detect:1; /*BIOS can detect the device */ 119 u32 bios_can_detect:1; /*BIOS can detect the device */
120 u32 depend_on_vga:1; /*Non-VGA output device whose power is related to 120 u32 depend_on_vga:1; /*Non-VGA output device whose power is related to
121 the VGA device. */ 121 the VGA device. */
122 u32 pipe_id:3; /*For VGA multiple-head devices. */ 122 u32 pipe_id:3; /*For VGA multiple-head devices. */
123 u32 reserved:10; /*Must be 0 */ 123 u32 reserved:10; /*Must be 0 */
124 u32 device_id_scheme:1; /*Device ID Scheme */ 124 u32 device_id_scheme:1; /*Device ID Scheme */
125 }; 125 };
126 126
127 struct acpi_video_enumerated_device { 127 struct acpi_video_enumerated_device {
128 union { 128 union {
129 u32 int_val; 129 u32 int_val;
130 struct acpi_video_device_attrib attrib; 130 struct acpi_video_device_attrib attrib;
131 } value; 131 } value;
132 struct acpi_video_device *bind_info; 132 struct acpi_video_device *bind_info;
133 }; 133 };
134 134
135 struct acpi_video_bus { 135 struct acpi_video_bus {
136 struct acpi_device *device; 136 struct acpi_device *device;
137 u8 dos_setting; 137 u8 dos_setting;
138 struct acpi_video_enumerated_device *attached_array; 138 struct acpi_video_enumerated_device *attached_array;
139 u8 attached_count; 139 u8 attached_count;
140 struct acpi_video_bus_cap cap; 140 struct acpi_video_bus_cap cap;
141 struct acpi_video_bus_flags flags; 141 struct acpi_video_bus_flags flags;
142 struct list_head video_device_list; 142 struct list_head video_device_list;
143 struct mutex device_list_lock; /* protects video_device_list */ 143 struct mutex device_list_lock; /* protects video_device_list */
144 struct proc_dir_entry *dir; 144 struct proc_dir_entry *dir;
145 struct input_dev *input; 145 struct input_dev *input;
146 char phys[32]; /* for input device */ 146 char phys[32]; /* for input device */
147 }; 147 };
148 148
149 struct acpi_video_device_flags { 149 struct acpi_video_device_flags {
150 u8 crt:1; 150 u8 crt:1;
151 u8 lcd:1; 151 u8 lcd:1;
152 u8 tvout:1; 152 u8 tvout:1;
153 u8 dvi:1; 153 u8 dvi:1;
154 u8 bios:1; 154 u8 bios:1;
155 u8 unknown:1; 155 u8 unknown:1;
156 u8 reserved:2; 156 u8 reserved:2;
157 }; 157 };
158 158
159 struct acpi_video_device_cap { 159 struct acpi_video_device_cap {
160 u8 _ADR:1; /*Return the unique ID */ 160 u8 _ADR:1; /*Return the unique ID */
161 u8 _BCL:1; /*Query list of brightness control levels supported */ 161 u8 _BCL:1; /*Query list of brightness control levels supported */
162 u8 _BCM:1; /*Set the brightness level */ 162 u8 _BCM:1; /*Set the brightness level */
163 u8 _BQC:1; /* Get current brightness level */ 163 u8 _BQC:1; /* Get current brightness level */
164 u8 _DDC:1; /*Return the EDID for this device */ 164 u8 _DDC:1; /*Return the EDID for this device */
165 u8 _DCS:1; /*Return status of output device */ 165 u8 _DCS:1; /*Return status of output device */
166 u8 _DGS:1; /*Query graphics state */ 166 u8 _DGS:1; /*Query graphics state */
167 u8 _DSS:1; /*Device state set */ 167 u8 _DSS:1; /*Device state set */
168 }; 168 };
169 169
170 struct acpi_video_device_brightness { 170 struct acpi_video_device_brightness {
171 int curr; 171 int curr;
172 int count; 172 int count;
173 int *levels; 173 int *levels;
174 }; 174 };
175 175
176 struct acpi_video_device { 176 struct acpi_video_device {
177 unsigned long device_id; 177 unsigned long device_id;
178 struct acpi_video_device_flags flags; 178 struct acpi_video_device_flags flags;
179 struct acpi_video_device_cap cap; 179 struct acpi_video_device_cap cap;
180 struct list_head entry; 180 struct list_head entry;
181 struct acpi_video_bus *video; 181 struct acpi_video_bus *video;
182 struct acpi_device *dev; 182 struct acpi_device *dev;
183 struct acpi_video_device_brightness *brightness; 183 struct acpi_video_device_brightness *brightness;
184 struct backlight_device *backlight; 184 struct backlight_device *backlight;
185 struct thermal_cooling_device *cdev; 185 struct thermal_cooling_device *cdev;
186 struct output_device *output_dev; 186 struct output_device *output_dev;
187 }; 187 };
188 188
189 /* bus */ 189 /* bus */
190 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); 190 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
191 static struct file_operations acpi_video_bus_info_fops = { 191 static struct file_operations acpi_video_bus_info_fops = {
192 .owner = THIS_MODULE, 192 .owner = THIS_MODULE,
193 .open = acpi_video_bus_info_open_fs, 193 .open = acpi_video_bus_info_open_fs,
194 .read = seq_read, 194 .read = seq_read,
195 .llseek = seq_lseek, 195 .llseek = seq_lseek,
196 .release = single_release, 196 .release = single_release,
197 }; 197 };
198 198
199 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file); 199 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
200 static struct file_operations acpi_video_bus_ROM_fops = { 200 static struct file_operations acpi_video_bus_ROM_fops = {
201 .owner = THIS_MODULE, 201 .owner = THIS_MODULE,
202 .open = acpi_video_bus_ROM_open_fs, 202 .open = acpi_video_bus_ROM_open_fs,
203 .read = seq_read, 203 .read = seq_read,
204 .llseek = seq_lseek, 204 .llseek = seq_lseek,
205 .release = single_release, 205 .release = single_release,
206 }; 206 };
207 207
208 static int acpi_video_bus_POST_info_open_fs(struct inode *inode, 208 static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
209 struct file *file); 209 struct file *file);
210 static struct file_operations acpi_video_bus_POST_info_fops = { 210 static struct file_operations acpi_video_bus_POST_info_fops = {
211 .owner = THIS_MODULE, 211 .owner = THIS_MODULE,
212 .open = acpi_video_bus_POST_info_open_fs, 212 .open = acpi_video_bus_POST_info_open_fs,
213 .read = seq_read, 213 .read = seq_read,
214 .llseek = seq_lseek, 214 .llseek = seq_lseek,
215 .release = single_release, 215 .release = single_release,
216 }; 216 };
217 217
218 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file); 218 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
219 static struct file_operations acpi_video_bus_POST_fops = { 219 static struct file_operations acpi_video_bus_POST_fops = {
220 .owner = THIS_MODULE, 220 .owner = THIS_MODULE,
221 .open = acpi_video_bus_POST_open_fs, 221 .open = acpi_video_bus_POST_open_fs,
222 .read = seq_read, 222 .read = seq_read,
223 .llseek = seq_lseek, 223 .llseek = seq_lseek,
224 .release = single_release, 224 .release = single_release,
225 }; 225 };
226 226
227 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file); 227 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
228 static struct file_operations acpi_video_bus_DOS_fops = { 228 static struct file_operations acpi_video_bus_DOS_fops = {
229 .owner = THIS_MODULE, 229 .owner = THIS_MODULE,
230 .open = acpi_video_bus_DOS_open_fs, 230 .open = acpi_video_bus_DOS_open_fs,
231 .read = seq_read, 231 .read = seq_read,
232 .llseek = seq_lseek, 232 .llseek = seq_lseek,
233 .release = single_release, 233 .release = single_release,
234 }; 234 };
235 235
236 /* device */ 236 /* device */
237 static int acpi_video_device_info_open_fs(struct inode *inode, 237 static int acpi_video_device_info_open_fs(struct inode *inode,
238 struct file *file); 238 struct file *file);
239 static struct file_operations acpi_video_device_info_fops = { 239 static struct file_operations acpi_video_device_info_fops = {
240 .owner = THIS_MODULE, 240 .owner = THIS_MODULE,
241 .open = acpi_video_device_info_open_fs, 241 .open = acpi_video_device_info_open_fs,
242 .read = seq_read, 242 .read = seq_read,
243 .llseek = seq_lseek, 243 .llseek = seq_lseek,
244 .release = single_release, 244 .release = single_release,
245 }; 245 };
246 246
247 static int acpi_video_device_state_open_fs(struct inode *inode, 247 static int acpi_video_device_state_open_fs(struct inode *inode,
248 struct file *file); 248 struct file *file);
249 static struct file_operations acpi_video_device_state_fops = { 249 static struct file_operations acpi_video_device_state_fops = {
250 .owner = THIS_MODULE, 250 .owner = THIS_MODULE,
251 .open = acpi_video_device_state_open_fs, 251 .open = acpi_video_device_state_open_fs,
252 .read = seq_read, 252 .read = seq_read,
253 .llseek = seq_lseek, 253 .llseek = seq_lseek,
254 .release = single_release, 254 .release = single_release,
255 }; 255 };
256 256
257 static int acpi_video_device_brightness_open_fs(struct inode *inode, 257 static int acpi_video_device_brightness_open_fs(struct inode *inode,
258 struct file *file); 258 struct file *file);
259 static struct file_operations acpi_video_device_brightness_fops = { 259 static struct file_operations acpi_video_device_brightness_fops = {
260 .owner = THIS_MODULE, 260 .owner = THIS_MODULE,
261 .open = acpi_video_device_brightness_open_fs, 261 .open = acpi_video_device_brightness_open_fs,
262 .read = seq_read, 262 .read = seq_read,
263 .llseek = seq_lseek, 263 .llseek = seq_lseek,
264 .release = single_release, 264 .release = single_release,
265 }; 265 };
266 266
267 static int acpi_video_device_EDID_open_fs(struct inode *inode, 267 static int acpi_video_device_EDID_open_fs(struct inode *inode,
268 struct file *file); 268 struct file *file);
269 static struct file_operations acpi_video_device_EDID_fops = { 269 static struct file_operations acpi_video_device_EDID_fops = {
270 .owner = THIS_MODULE, 270 .owner = THIS_MODULE,
271 .open = acpi_video_device_EDID_open_fs, 271 .open = acpi_video_device_EDID_open_fs,
272 .read = seq_read, 272 .read = seq_read,
273 .llseek = seq_lseek, 273 .llseek = seq_lseek,
274 .release = single_release, 274 .release = single_release,
275 }; 275 };
276 276
277 static char device_decode[][30] = { 277 static char device_decode[][30] = {
278 "motherboard VGA device", 278 "motherboard VGA device",
279 "PCI VGA device", 279 "PCI VGA device",
280 "AGP VGA device", 280 "AGP VGA device",
281 "UNKNOWN", 281 "UNKNOWN",
282 }; 282 };
283 283
284 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data); 284 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data);
285 static void acpi_video_device_rebind(struct acpi_video_bus *video); 285 static void acpi_video_device_rebind(struct acpi_video_bus *video);
286 static void acpi_video_device_bind(struct acpi_video_bus *video, 286 static void acpi_video_device_bind(struct acpi_video_bus *video,
287 struct acpi_video_device *device); 287 struct acpi_video_device *device);
288 static int acpi_video_device_enumerate(struct acpi_video_bus *video); 288 static int acpi_video_device_enumerate(struct acpi_video_bus *video);
289 static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, 289 static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
290 int level); 290 int level);
291 static int acpi_video_device_lcd_get_level_current( 291 static int acpi_video_device_lcd_get_level_current(
292 struct acpi_video_device *device, 292 struct acpi_video_device *device,
293 unsigned long long *level); 293 unsigned long long *level);
294 static int acpi_video_get_next_level(struct acpi_video_device *device, 294 static int acpi_video_get_next_level(struct acpi_video_device *device,
295 u32 level_current, u32 event); 295 u32 level_current, u32 event);
296 static void acpi_video_switch_brightness(struct acpi_video_device *device, 296 static void acpi_video_switch_brightness(struct acpi_video_device *device,
297 int event); 297 int event);
298 static int acpi_video_device_get_state(struct acpi_video_device *device, 298 static int acpi_video_device_get_state(struct acpi_video_device *device,
299 unsigned long long *state); 299 unsigned long long *state);
300 static int acpi_video_output_get(struct output_device *od); 300 static int acpi_video_output_get(struct output_device *od);
301 static int acpi_video_device_set_state(struct acpi_video_device *device, int state); 301 static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
302 302
303 /*backlight device sysfs support*/ 303 /*backlight device sysfs support*/
304 static int acpi_video_get_brightness(struct backlight_device *bd) 304 static int acpi_video_get_brightness(struct backlight_device *bd)
305 { 305 {
306 unsigned long long cur_level; 306 unsigned long long cur_level;
307 int i; 307 int i;
308 struct acpi_video_device *vd = 308 struct acpi_video_device *vd =
309 (struct acpi_video_device *)bl_get_data(bd); 309 (struct acpi_video_device *)bl_get_data(bd);
310 acpi_video_device_lcd_get_level_current(vd, &cur_level); 310 acpi_video_device_lcd_get_level_current(vd, &cur_level);
311 for (i = 2; i < vd->brightness->count; i++) { 311 for (i = 2; i < vd->brightness->count; i++) {
312 if (vd->brightness->levels[i] == cur_level) 312 if (vd->brightness->levels[i] == cur_level)
313 /* The first two entries are special - see page 575 313 /* The first two entries are special - see page 575
314 of the ACPI spec 3.0 */ 314 of the ACPI spec 3.0 */
315 return i-2; 315 return i-2;
316 } 316 }
317 return 0; 317 return 0;
318 } 318 }
319 319
320 static int acpi_video_set_brightness(struct backlight_device *bd) 320 static int acpi_video_set_brightness(struct backlight_device *bd)
321 { 321 {
322 int request_level = bd->props.brightness+2; 322 int request_level = bd->props.brightness+2;
323 struct acpi_video_device *vd = 323 struct acpi_video_device *vd =
324 (struct acpi_video_device *)bl_get_data(bd); 324 (struct acpi_video_device *)bl_get_data(bd);
325 acpi_video_device_lcd_set_level(vd, 325 acpi_video_device_lcd_set_level(vd,
326 vd->brightness->levels[request_level]); 326 vd->brightness->levels[request_level]);
327 return 0; 327 return 0;
328 } 328 }
329 329
330 static struct backlight_ops acpi_backlight_ops = { 330 static struct backlight_ops acpi_backlight_ops = {
331 .get_brightness = acpi_video_get_brightness, 331 .get_brightness = acpi_video_get_brightness,
332 .update_status = acpi_video_set_brightness, 332 .update_status = acpi_video_set_brightness,
333 }; 333 };
334 334
335 /*video output device sysfs support*/ 335 /*video output device sysfs support*/
336 static int acpi_video_output_get(struct output_device *od) 336 static int acpi_video_output_get(struct output_device *od)
337 { 337 {
338 unsigned long long state; 338 unsigned long long state;
339 struct acpi_video_device *vd = 339 struct acpi_video_device *vd =
340 (struct acpi_video_device *)dev_get_drvdata(&od->dev); 340 (struct acpi_video_device *)dev_get_drvdata(&od->dev);
341 acpi_video_device_get_state(vd, &state); 341 acpi_video_device_get_state(vd, &state);
342 return (int)state; 342 return (int)state;
343 } 343 }
344 344
345 static int acpi_video_output_set(struct output_device *od) 345 static int acpi_video_output_set(struct output_device *od)
346 { 346 {
347 unsigned long state = od->request_state; 347 unsigned long state = od->request_state;
348 struct acpi_video_device *vd= 348 struct acpi_video_device *vd=
349 (struct acpi_video_device *)dev_get_drvdata(&od->dev); 349 (struct acpi_video_device *)dev_get_drvdata(&od->dev);
350 return acpi_video_device_set_state(vd, state); 350 return acpi_video_device_set_state(vd, state);
351 } 351 }
352 352
353 static struct output_properties acpi_output_properties = { 353 static struct output_properties acpi_output_properties = {
354 .set_state = acpi_video_output_set, 354 .set_state = acpi_video_output_set,
355 .get_status = acpi_video_output_get, 355 .get_status = acpi_video_output_get,
356 }; 356 };
357 357
358 358
359 /* thermal cooling device callbacks */ 359 /* thermal cooling device callbacks */
360 static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf) 360 static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
361 { 361 {
362 struct acpi_device *device = cdev->devdata; 362 struct acpi_device *device = cdev->devdata;
363 struct acpi_video_device *video = acpi_driver_data(device); 363 struct acpi_video_device *video = acpi_driver_data(device);
364 364
365 return sprintf(buf, "%d\n", video->brightness->count - 3); 365 return sprintf(buf, "%d\n", video->brightness->count - 3);
366 } 366 }
367 367
368 static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf) 368 static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
369 { 369 {
370 struct acpi_device *device = cdev->devdata; 370 struct acpi_device *device = cdev->devdata;
371 struct acpi_video_device *video = acpi_driver_data(device); 371 struct acpi_video_device *video = acpi_driver_data(device);
372 unsigned long long level; 372 unsigned long long level;
373 int state; 373 int state;
374 374
375 acpi_video_device_lcd_get_level_current(video, &level); 375 acpi_video_device_lcd_get_level_current(video, &level);
376 for (state = 2; state < video->brightness->count; state++) 376 for (state = 2; state < video->brightness->count; state++)
377 if (level == video->brightness->levels[state]) 377 if (level == video->brightness->levels[state])
378 return sprintf(buf, "%d\n", 378 return sprintf(buf, "%d\n",
379 video->brightness->count - state - 1); 379 video->brightness->count - state - 1);
380 380
381 return -EINVAL; 381 return -EINVAL;
382 } 382 }
383 383
384 static int 384 static int
385 video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) 385 video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
386 { 386 {
387 struct acpi_device *device = cdev->devdata; 387 struct acpi_device *device = cdev->devdata;
388 struct acpi_video_device *video = acpi_driver_data(device); 388 struct acpi_video_device *video = acpi_driver_data(device);
389 int level; 389 int level;
390 390
391 if ( state >= video->brightness->count - 2) 391 if ( state >= video->brightness->count - 2)
392 return -EINVAL; 392 return -EINVAL;
393 393
394 state = video->brightness->count - state; 394 state = video->brightness->count - state;
395 level = video->brightness->levels[state -1]; 395 level = video->brightness->levels[state -1];
396 return acpi_video_device_lcd_set_level(video, level); 396 return acpi_video_device_lcd_set_level(video, level);
397 } 397 }
398 398
399 static struct thermal_cooling_device_ops video_cooling_ops = { 399 static struct thermal_cooling_device_ops video_cooling_ops = {
400 .get_max_state = video_get_max_state, 400 .get_max_state = video_get_max_state,
401 .get_cur_state = video_get_cur_state, 401 .get_cur_state = video_get_cur_state,
402 .set_cur_state = video_set_cur_state, 402 .set_cur_state = video_set_cur_state,
403 }; 403 };
404 404
405 /* -------------------------------------------------------------------------- 405 /* --------------------------------------------------------------------------
406 Video Management 406 Video Management
407 -------------------------------------------------------------------------- */ 407 -------------------------------------------------------------------------- */
408 408
409 /* device */ 409 /* device */
410 410
411 static int 411 static int
412 acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state) 412 acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state)
413 { 413 {
414 int status; 414 int status;
415 415
416 status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state); 416 status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state);
417 417
418 return status; 418 return status;
419 } 419 }
420 420
421 static int 421 static int
422 acpi_video_device_get_state(struct acpi_video_device *device, 422 acpi_video_device_get_state(struct acpi_video_device *device,
423 unsigned long long *state) 423 unsigned long long *state)
424 { 424 {
425 int status; 425 int status;
426 426
427 status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state); 427 status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state);
428 428
429 return status; 429 return status;
430 } 430 }
431 431
432 static int 432 static int
433 acpi_video_device_set_state(struct acpi_video_device *device, int state) 433 acpi_video_device_set_state(struct acpi_video_device *device, int state)
434 { 434 {
435 int status; 435 int status;
436 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 436 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
437 struct acpi_object_list args = { 1, &arg0 }; 437 struct acpi_object_list args = { 1, &arg0 };
438 unsigned long long ret; 438 unsigned long long ret;
439 439
440 440
441 arg0.integer.value = state; 441 arg0.integer.value = state;
442 status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret); 442 status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret);
443 443
444 return status; 444 return status;
445 } 445 }
446 446
447 static int 447 static int
448 acpi_video_device_lcd_query_levels(struct acpi_video_device *device, 448 acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
449 union acpi_object **levels) 449 union acpi_object **levels)
450 { 450 {
451 int status; 451 int status;
452 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 452 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
453 union acpi_object *obj; 453 union acpi_object *obj;
454 454
455 455
456 *levels = NULL; 456 *levels = NULL;
457 457
458 status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer); 458 status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer);
459 if (!ACPI_SUCCESS(status)) 459 if (!ACPI_SUCCESS(status))
460 return status; 460 return status;
461 obj = (union acpi_object *)buffer.pointer; 461 obj = (union acpi_object *)buffer.pointer;
462 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { 462 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
463 printk(KERN_ERR PREFIX "Invalid _BCL data\n"); 463 printk(KERN_ERR PREFIX "Invalid _BCL data\n");
464 status = -EFAULT; 464 status = -EFAULT;
465 goto err; 465 goto err;
466 } 466 }
467 467
468 *levels = obj; 468 *levels = obj;
469 469
470 return 0; 470 return 0;
471 471
472 err: 472 err:
473 kfree(buffer.pointer); 473 kfree(buffer.pointer);
474 474
475 return status; 475 return status;
476 } 476 }
477 477
478 static int 478 static int
479 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) 479 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
480 { 480 {
481 int status = AE_OK; 481 int status = AE_OK;
482 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 482 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
483 struct acpi_object_list args = { 1, &arg0 }; 483 struct acpi_object_list args = { 1, &arg0 };
484 484
485 485
486 arg0.integer.value = level; 486 arg0.integer.value = level;
487 487
488 if (device->cap._BCM) 488 if (device->cap._BCM)
489 status = acpi_evaluate_object(device->dev->handle, "_BCM", 489 status = acpi_evaluate_object(device->dev->handle, "_BCM",
490 &args, NULL); 490 &args, NULL);
491 device->brightness->curr = level; 491 device->brightness->curr = level;
492 return status; 492 return status;
493 } 493 }
494 494
495 static int 495 static int
496 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, 496 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
497 unsigned long long *level) 497 unsigned long long *level)
498 { 498 {
499 if (device->cap._BQC) 499 if (device->cap._BQC)
500 return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, 500 return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
501 level); 501 level);
502 *level = device->brightness->curr; 502 *level = device->brightness->curr;
503 return AE_OK; 503 return AE_OK;
504 } 504 }
505 505
506 static int 506 static int
507 acpi_video_device_EDID(struct acpi_video_device *device, 507 acpi_video_device_EDID(struct acpi_video_device *device,
508 union acpi_object **edid, ssize_t length) 508 union acpi_object **edid, ssize_t length)
509 { 509 {
510 int status; 510 int status;
511 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 511 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
512 union acpi_object *obj; 512 union acpi_object *obj;
513 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 513 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
514 struct acpi_object_list args = { 1, &arg0 }; 514 struct acpi_object_list args = { 1, &arg0 };
515 515
516 516
517 *edid = NULL; 517 *edid = NULL;
518 518
519 if (!device) 519 if (!device)
520 return -ENODEV; 520 return -ENODEV;
521 if (length == 128) 521 if (length == 128)
522 arg0.integer.value = 1; 522 arg0.integer.value = 1;
523 else if (length == 256) 523 else if (length == 256)
524 arg0.integer.value = 2; 524 arg0.integer.value = 2;
525 else 525 else
526 return -EINVAL; 526 return -EINVAL;
527 527
528 status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer); 528 status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer);
529 if (ACPI_FAILURE(status)) 529 if (ACPI_FAILURE(status))
530 return -ENODEV; 530 return -ENODEV;
531 531
532 obj = buffer.pointer; 532 obj = buffer.pointer;
533 533
534 if (obj && obj->type == ACPI_TYPE_BUFFER) 534 if (obj && obj->type == ACPI_TYPE_BUFFER)
535 *edid = obj; 535 *edid = obj;
536 else { 536 else {
537 printk(KERN_ERR PREFIX "Invalid _DDC data\n"); 537 printk(KERN_ERR PREFIX "Invalid _DDC data\n");
538 status = -EFAULT; 538 status = -EFAULT;
539 kfree(obj); 539 kfree(obj);
540 } 540 }
541 541
542 return status; 542 return status;
543 } 543 }
544 544
545 /* bus */ 545 /* bus */
546 546
547 static int 547 static int
548 acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) 548 acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
549 { 549 {
550 int status; 550 int status;
551 unsigned long long tmp; 551 unsigned long long tmp;
552 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 552 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
553 struct acpi_object_list args = { 1, &arg0 }; 553 struct acpi_object_list args = { 1, &arg0 };
554 554
555 555
556 arg0.integer.value = option; 556 arg0.integer.value = option;
557 557
558 status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp); 558 status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp);
559 if (ACPI_SUCCESS(status)) 559 if (ACPI_SUCCESS(status))
560 status = tmp ? (-EINVAL) : (AE_OK); 560 status = tmp ? (-EINVAL) : (AE_OK);
561 561
562 return status; 562 return status;
563 } 563 }
564 564
565 static int 565 static int
566 acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) 566 acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
567 { 567 {
568 int status; 568 int status;
569 569
570 status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); 570 status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id);
571 571
572 return status; 572 return status;
573 } 573 }
574 574
575 static int 575 static int
576 acpi_video_bus_POST_options(struct acpi_video_bus *video, 576 acpi_video_bus_POST_options(struct acpi_video_bus *video,
577 unsigned long long *options) 577 unsigned long long *options)
578 { 578 {
579 int status; 579 int status;
580 580
581 status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options); 581 status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options);
582 *options &= 3; 582 *options &= 3;
583 583
584 return status; 584 return status;
585 } 585 }
586 586
587 /* 587 /*
588 * Arg: 588 * Arg:
589 * video : video bus device pointer 589 * video : video bus device pointer
590 * bios_flag : 590 * bios_flag :
591 * 0. The system BIOS should NOT automatically switch(toggle) 591 * 0. The system BIOS should NOT automatically switch(toggle)
592 * the active display output. 592 * the active display output.
593 * 1. The system BIOS should automatically switch (toggle) the 593 * 1. The system BIOS should automatically switch (toggle) the
594 * active display output. No switch event. 594 * active display output. No switch event.
595 * 2. The _DGS value should be locked. 595 * 2. The _DGS value should be locked.
596 * 3. The system BIOS should not automatically switch (toggle) the 596 * 3. The system BIOS should not automatically switch (toggle) the
597 * active display output, but instead generate the display switch 597 * active display output, but instead generate the display switch
598 * event notify code. 598 * event notify code.
599 * lcd_flag : 599 * lcd_flag :
600 * 0. The system BIOS should automatically control the brightness level 600 * 0. The system BIOS should automatically control the brightness level
601 * of the LCD when the power changes from AC to DC 601 * of the LCD when the power changes from AC to DC
602 * 1. The system BIOS should NOT automatically control the brightness 602 * 1. The system BIOS should NOT automatically control the brightness
603 * level of the LCD when the power changes from AC to DC. 603 * level of the LCD when the power changes from AC to DC.
604 * Return Value: 604 * Return Value:
605 * -1 wrong arg. 605 * -1 wrong arg.
606 */ 606 */
607 607
608 static int 608 static int
609 acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) 609 acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
610 { 610 {
611 acpi_integer status = 0; 611 acpi_integer status = 0;
612 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 612 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
613 struct acpi_object_list args = { 1, &arg0 }; 613 struct acpi_object_list args = { 1, &arg0 };
614 614
615 615
616 if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) { 616 if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) {
617 status = -1; 617 status = -1;
618 goto Failed; 618 goto Failed;
619 } 619 }
620 arg0.integer.value = (lcd_flag << 2) | bios_flag; 620 arg0.integer.value = (lcd_flag << 2) | bios_flag;
621 video->dos_setting = arg0.integer.value; 621 video->dos_setting = arg0.integer.value;
622 acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL); 622 acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL);
623 623
624 Failed: 624 Failed:
625 return status; 625 return status;
626 } 626 }
627 627
628 /* 628 /*
629 * Arg: 629 * Arg:
630 * device : video output device (LCD, CRT, ..) 630 * device : video output device (LCD, CRT, ..)
631 * 631 *
632 * Return Value: 632 * Return Value:
633 * Maximum brightness level 633 * Maximum brightness level
634 * 634 *
635 * Allocate and initialize device->brightness. 635 * Allocate and initialize device->brightness.
636 */ 636 */
637 637
638 static int 638 static int
639 acpi_video_init_brightness(struct acpi_video_device *device) 639 acpi_video_init_brightness(struct acpi_video_device *device)
640 { 640 {
641 union acpi_object *obj = NULL; 641 union acpi_object *obj = NULL;
642 int i, max_level = 0, count = 0; 642 int i, max_level = 0, count = 0;
643 union acpi_object *o; 643 union acpi_object *o;
644 struct acpi_video_device_brightness *br = NULL; 644 struct acpi_video_device_brightness *br = NULL;
645 645
646 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { 646 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
647 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " 647 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
648 "LCD brightness level\n")); 648 "LCD brightness level\n"));
649 goto out; 649 goto out;
650 } 650 }
651 651
652 if (obj->package.count < 2) 652 if (obj->package.count < 2)
653 goto out; 653 goto out;
654 654
655 br = kzalloc(sizeof(*br), GFP_KERNEL); 655 br = kzalloc(sizeof(*br), GFP_KERNEL);
656 if (!br) { 656 if (!br) {
657 printk(KERN_ERR "can't allocate memory\n"); 657 printk(KERN_ERR "can't allocate memory\n");
658 goto out; 658 goto out;
659 } 659 }
660 660
661 br->levels = kmalloc(obj->package.count * sizeof *(br->levels), 661 br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
662 GFP_KERNEL); 662 GFP_KERNEL);
663 if (!br->levels) 663 if (!br->levels)
664 goto out_free; 664 goto out_free;
665 665
666 for (i = 0; i < obj->package.count; i++) { 666 for (i = 0; i < obj->package.count; i++) {
667 o = (union acpi_object *)&obj->package.elements[i]; 667 o = (union acpi_object *)&obj->package.elements[i];
668 if (o->type != ACPI_TYPE_INTEGER) { 668 if (o->type != ACPI_TYPE_INTEGER) {
669 printk(KERN_ERR PREFIX "Invalid data\n"); 669 printk(KERN_ERR PREFIX "Invalid data\n");
670 continue; 670 continue;
671 } 671 }
672 br->levels[count] = (u32) o->integer.value; 672 br->levels[count] = (u32) o->integer.value;
673 673
674 if (br->levels[count] > max_level) 674 if (br->levels[count] > max_level)
675 max_level = br->levels[count]; 675 max_level = br->levels[count];
676 count++; 676 count++;
677 } 677 }
678 678
679 if (count < 2) 679 if (count < 2)
680 goto out_free_levels; 680 goto out_free_levels;
681 681
682 br->count = count; 682 br->count = count;
683 device->brightness = br; 683 device->brightness = br;
684 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count)); 684 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
685 kfree(obj); 685 kfree(obj);
686 return max_level; 686 return max_level;
687 687
688 out_free_levels: 688 out_free_levels:
689 kfree(br->levels); 689 kfree(br->levels);
690 out_free: 690 out_free:
691 kfree(br); 691 kfree(br);
692 out: 692 out:
693 device->brightness = NULL; 693 device->brightness = NULL;
694 kfree(obj); 694 kfree(obj);
695 return 0; 695 return 0;
696 } 696 }
697 697
698 /* 698 /*
699 * Arg: 699 * Arg:
700 * device : video output device (LCD, CRT, ..) 700 * device : video output device (LCD, CRT, ..)
701 * 701 *
702 * Return Value: 702 * Return Value:
703 * None 703 * None
704 * 704 *
705 * Find out all required AML methods defined under the output 705 * Find out all required AML methods defined under the output
706 * device. 706 * device.
707 */ 707 */
708 708
709 static void acpi_video_device_find_cap(struct acpi_video_device *device) 709 static void acpi_video_device_find_cap(struct acpi_video_device *device)
710 { 710 {
711 acpi_handle h_dummy1; 711 acpi_handle h_dummy1;
712 u32 max_level = 0; 712 u32 max_level = 0;
713 713
714 714
715 memset(&device->cap, 0, sizeof(device->cap)); 715 memset(&device->cap, 0, sizeof(device->cap));
716 716
717 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { 717 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) {
718 device->cap._ADR = 1; 718 device->cap._ADR = 1;
719 } 719 }
720 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) { 720 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) {
721 device->cap._BCL = 1; 721 device->cap._BCL = 1;
722 } 722 }
723 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { 723 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
724 device->cap._BCM = 1; 724 device->cap._BCM = 1;
725 } 725 }
726 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) 726 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
727 device->cap._BQC = 1; 727 device->cap._BQC = 1;
728 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { 728 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
729 device->cap._DDC = 1; 729 device->cap._DDC = 1;
730 } 730 }
731 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) { 731 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) {
732 device->cap._DCS = 1; 732 device->cap._DCS = 1;
733 } 733 }
734 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) { 734 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) {
735 device->cap._DGS = 1; 735 device->cap._DGS = 1;
736 } 736 }
737 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) { 737 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) {
738 device->cap._DSS = 1; 738 device->cap._DSS = 1;
739 } 739 }
740 740
741 max_level = acpi_video_init_brightness(device); 741 if (acpi_video_backlight_support())
742 max_level = acpi_video_init_brightness(device);
742 743
743 if (device->cap._BCL && device->cap._BCM && max_level > 0) { 744 if (device->cap._BCL && device->cap._BCM && max_level > 0) {
744 int result; 745 int result;
745 static int count = 0; 746 static int count = 0;
746 char *name; 747 char *name;
747 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 748 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
748 if (!name) 749 if (!name)
749 return; 750 return;
750 751
751 sprintf(name, "acpi_video%d", count++); 752 sprintf(name, "acpi_video%d", count++);
752 device->backlight = backlight_device_register(name, 753 device->backlight = backlight_device_register(name,
753 NULL, device, &acpi_backlight_ops); 754 NULL, device, &acpi_backlight_ops);
754 device->backlight->props.max_brightness = device->brightness->count-3; 755 device->backlight->props.max_brightness = device->brightness->count-3;
755 /* 756 /*
756 * If there exists the _BQC object, the _BQC object will be 757 * If there exists the _BQC object, the _BQC object will be
757 * called to get the current backlight brightness. Otherwise 758 * called to get the current backlight brightness. Otherwise
758 * the brightness will be set to the maximum. 759 * the brightness will be set to the maximum.
759 */ 760 */
760 if (device->cap._BQC) 761 if (device->cap._BQC)
761 device->backlight->props.brightness = 762 device->backlight->props.brightness =
762 acpi_video_get_brightness(device->backlight); 763 acpi_video_get_brightness(device->backlight);
763 else 764 else
764 device->backlight->props.brightness = 765 device->backlight->props.brightness =
765 device->backlight->props.max_brightness; 766 device->backlight->props.max_brightness;
766 backlight_update_status(device->backlight); 767 backlight_update_status(device->backlight);
767 kfree(name); 768 kfree(name);
768 769
769 device->cdev = thermal_cooling_device_register("LCD", 770 device->cdev = thermal_cooling_device_register("LCD",
770 device->dev, &video_cooling_ops); 771 device->dev, &video_cooling_ops);
771 if (IS_ERR(device->cdev)) 772 if (IS_ERR(device->cdev))
772 return; 773 return;
773 774
774 dev_info(&device->dev->dev, "registered as cooling_device%d\n", 775 dev_info(&device->dev->dev, "registered as cooling_device%d\n",
775 device->cdev->id); 776 device->cdev->id);
776 result = sysfs_create_link(&device->dev->dev.kobj, 777 result = sysfs_create_link(&device->dev->dev.kobj,
777 &device->cdev->device.kobj, 778 &device->cdev->device.kobj,
778 "thermal_cooling"); 779 "thermal_cooling");
779 if (result) 780 if (result)
780 printk(KERN_ERR PREFIX "Create sysfs link\n"); 781 printk(KERN_ERR PREFIX "Create sysfs link\n");
781 result = sysfs_create_link(&device->cdev->device.kobj, 782 result = sysfs_create_link(&device->cdev->device.kobj,
782 &device->dev->dev.kobj, "device"); 783 &device->dev->dev.kobj, "device");
783 if (result) 784 if (result)
784 printk(KERN_ERR PREFIX "Create sysfs link\n"); 785 printk(KERN_ERR PREFIX "Create sysfs link\n");
785 786
786 } 787 }
787 if (device->cap._DCS && device->cap._DSS){ 788
788 static int count = 0; 789 if (acpi_video_display_switch_support()) {
789 char *name; 790
790 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 791 if (device->cap._DCS && device->cap._DSS) {
791 if (!name) 792 static int count;
792 return; 793 char *name;
793 sprintf(name, "acpi_video%d", count++); 794 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
794 device->output_dev = video_output_register(name, 795 if (!name)
795 NULL, device, &acpi_output_properties); 796 return;
796 kfree(name); 797 sprintf(name, "acpi_video%d", count++);
798 device->output_dev = video_output_register(name,
799 NULL, device, &acpi_output_properties);
800 kfree(name);
801 }
797 } 802 }
798 return;
799 } 803 }
800 804
801 /* 805 /*
802 * Arg: 806 * Arg:
803 * device : video output device (VGA) 807 * device : video output device (VGA)
804 * 808 *
805 * Return Value: 809 * Return Value:
806 * None 810 * None
807 * 811 *
808 * Find out all required AML methods defined under the video bus device. 812 * Find out all required AML methods defined under the video bus device.
809 */ 813 */
810 814
811 static void acpi_video_bus_find_cap(struct acpi_video_bus *video) 815 static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
812 { 816 {
813 acpi_handle h_dummy1; 817 acpi_handle h_dummy1;
814 818
815 memset(&video->cap, 0, sizeof(video->cap)); 819 memset(&video->cap, 0, sizeof(video->cap));
816 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { 820 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) {
817 video->cap._DOS = 1; 821 video->cap._DOS = 1;
818 } 822 }
819 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) { 823 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) {
820 video->cap._DOD = 1; 824 video->cap._DOD = 1;
821 } 825 }
822 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) { 826 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) {
823 video->cap._ROM = 1; 827 video->cap._ROM = 1;
824 } 828 }
825 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) { 829 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) {
826 video->cap._GPD = 1; 830 video->cap._GPD = 1;
827 } 831 }
828 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) { 832 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) {
829 video->cap._SPD = 1; 833 video->cap._SPD = 1;
830 } 834 }
831 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) { 835 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) {
832 video->cap._VPO = 1; 836 video->cap._VPO = 1;
833 } 837 }
834 } 838 }
835 839
836 /* 840 /*
837 * Check whether the video bus device has required AML method to 841 * Check whether the video bus device has required AML method to
838 * support the desired features 842 * support the desired features
839 */ 843 */
840 844
841 static int acpi_video_bus_check(struct acpi_video_bus *video) 845 static int acpi_video_bus_check(struct acpi_video_bus *video)
842 { 846 {
843 acpi_status status = -ENOENT; 847 acpi_status status = -ENOENT;
848 struct device *dev;
844 849
845
846 if (!video) 850 if (!video)
847 return -EINVAL; 851 return -EINVAL;
852
853 dev = acpi_get_physical_pci_device(video->device->handle);
854 if (!dev)
855 return -ENODEV;
856 put_device(dev);
848 857
849 /* Since there is no HID, CID and so on for VGA driver, we have 858 /* Since there is no HID, CID and so on for VGA driver, we have
850 * to check well known required nodes. 859 * to check well known required nodes.
851 */ 860 */
852 861
853 /* Does this device support video switching? */ 862 /* Does this device support video switching? */
854 if (video->cap._DOS) { 863 if (video->cap._DOS) {
855 video->flags.multihead = 1; 864 video->flags.multihead = 1;
856 status = 0; 865 status = 0;
857 } 866 }
858 867
859 /* Does this device support retrieving a video ROM? */ 868 /* Does this device support retrieving a video ROM? */
860 if (video->cap._ROM) { 869 if (video->cap._ROM) {
861 video->flags.rom = 1; 870 video->flags.rom = 1;
862 status = 0; 871 status = 0;
863 } 872 }
864 873
865 /* Does this device support configuring which video device to POST? */ 874 /* Does this device support configuring which video device to POST? */
866 if (video->cap._GPD && video->cap._SPD && video->cap._VPO) { 875 if (video->cap._GPD && video->cap._SPD && video->cap._VPO) {
867 video->flags.post = 1; 876 video->flags.post = 1;
868 status = 0; 877 status = 0;
869 } 878 }
870 879
871 return status; 880 return status;
872 } 881 }
873 882
874 /* -------------------------------------------------------------------------- 883 /* --------------------------------------------------------------------------
875 FS Interface (/proc) 884 FS Interface (/proc)
876 -------------------------------------------------------------------------- */ 885 -------------------------------------------------------------------------- */
877 886
878 static struct proc_dir_entry *acpi_video_dir; 887 static struct proc_dir_entry *acpi_video_dir;
879 888
880 /* video devices */ 889 /* video devices */
881 890
882 static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) 891 static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
883 { 892 {
884 struct acpi_video_device *dev = seq->private; 893 struct acpi_video_device *dev = seq->private;
885 894
886 895
887 if (!dev) 896 if (!dev)
888 goto end; 897 goto end;
889 898
890 seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id); 899 seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id);
891 seq_printf(seq, "type: "); 900 seq_printf(seq, "type: ");
892 if (dev->flags.crt) 901 if (dev->flags.crt)
893 seq_printf(seq, "CRT\n"); 902 seq_printf(seq, "CRT\n");
894 else if (dev->flags.lcd) 903 else if (dev->flags.lcd)
895 seq_printf(seq, "LCD\n"); 904 seq_printf(seq, "LCD\n");
896 else if (dev->flags.tvout) 905 else if (dev->flags.tvout)
897 seq_printf(seq, "TVOUT\n"); 906 seq_printf(seq, "TVOUT\n");
898 else if (dev->flags.dvi) 907 else if (dev->flags.dvi)
899 seq_printf(seq, "DVI\n"); 908 seq_printf(seq, "DVI\n");
900 else 909 else
901 seq_printf(seq, "UNKNOWN\n"); 910 seq_printf(seq, "UNKNOWN\n");
902 911
903 seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no"); 912 seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no");
904 913
905 end: 914 end:
906 return 0; 915 return 0;
907 } 916 }
908 917
909 static int 918 static int
910 acpi_video_device_info_open_fs(struct inode *inode, struct file *file) 919 acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
911 { 920 {
912 return single_open(file, acpi_video_device_info_seq_show, 921 return single_open(file, acpi_video_device_info_seq_show,
913 PDE(inode)->data); 922 PDE(inode)->data);
914 } 923 }
915 924
916 static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) 925 static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
917 { 926 {
918 int status; 927 int status;
919 struct acpi_video_device *dev = seq->private; 928 struct acpi_video_device *dev = seq->private;
920 unsigned long long state; 929 unsigned long long state;
921 930
922 931
923 if (!dev) 932 if (!dev)
924 goto end; 933 goto end;
925 934
926 status = acpi_video_device_get_state(dev, &state); 935 status = acpi_video_device_get_state(dev, &state);
927 seq_printf(seq, "state: "); 936 seq_printf(seq, "state: ");
928 if (ACPI_SUCCESS(status)) 937 if (ACPI_SUCCESS(status))
929 seq_printf(seq, "0x%02llx\n", state); 938 seq_printf(seq, "0x%02llx\n", state);
930 else 939 else
931 seq_printf(seq, "<not supported>\n"); 940 seq_printf(seq, "<not supported>\n");
932 941
933 status = acpi_video_device_query(dev, &state); 942 status = acpi_video_device_query(dev, &state);
934 seq_printf(seq, "query: "); 943 seq_printf(seq, "query: ");
935 if (ACPI_SUCCESS(status)) 944 if (ACPI_SUCCESS(status))
936 seq_printf(seq, "0x%02llx\n", state); 945 seq_printf(seq, "0x%02llx\n", state);
937 else 946 else
938 seq_printf(seq, "<not supported>\n"); 947 seq_printf(seq, "<not supported>\n");
939 948
940 end: 949 end:
941 return 0; 950 return 0;
942 } 951 }
943 952
944 static int 953 static int
945 acpi_video_device_state_open_fs(struct inode *inode, struct file *file) 954 acpi_video_device_state_open_fs(struct inode *inode, struct file *file)
946 { 955 {
947 return single_open(file, acpi_video_device_state_seq_show, 956 return single_open(file, acpi_video_device_state_seq_show,
948 PDE(inode)->data); 957 PDE(inode)->data);
949 } 958 }
950 959
951 static ssize_t 960 static ssize_t
952 acpi_video_device_write_state(struct file *file, 961 acpi_video_device_write_state(struct file *file,
953 const char __user * buffer, 962 const char __user * buffer,
954 size_t count, loff_t * data) 963 size_t count, loff_t * data)
955 { 964 {
956 int status; 965 int status;
957 struct seq_file *m = file->private_data; 966 struct seq_file *m = file->private_data;
958 struct acpi_video_device *dev = m->private; 967 struct acpi_video_device *dev = m->private;
959 char str[12] = { 0 }; 968 char str[12] = { 0 };
960 u32 state = 0; 969 u32 state = 0;
961 970
962 971
963 if (!dev || count + 1 > sizeof str) 972 if (!dev || count + 1 > sizeof str)
964 return -EINVAL; 973 return -EINVAL;
965 974
966 if (copy_from_user(str, buffer, count)) 975 if (copy_from_user(str, buffer, count))
967 return -EFAULT; 976 return -EFAULT;
968 977
969 str[count] = 0; 978 str[count] = 0;
970 state = simple_strtoul(str, NULL, 0); 979 state = simple_strtoul(str, NULL, 0);
971 state &= ((1ul << 31) | (1ul << 30) | (1ul << 0)); 980 state &= ((1ul << 31) | (1ul << 30) | (1ul << 0));
972 981
973 status = acpi_video_device_set_state(dev, state); 982 status = acpi_video_device_set_state(dev, state);
974 983
975 if (status) 984 if (status)
976 return -EFAULT; 985 return -EFAULT;
977 986
978 return count; 987 return count;
979 } 988 }
980 989
981 static int 990 static int
982 acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) 991 acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
983 { 992 {
984 struct acpi_video_device *dev = seq->private; 993 struct acpi_video_device *dev = seq->private;
985 int i; 994 int i;
986 995
987 996
988 if (!dev || !dev->brightness) { 997 if (!dev || !dev->brightness) {
989 seq_printf(seq, "<not supported>\n"); 998 seq_printf(seq, "<not supported>\n");
990 return 0; 999 return 0;
991 } 1000 }
992 1001
993 seq_printf(seq, "levels: "); 1002 seq_printf(seq, "levels: ");
994 for (i = 0; i < dev->brightness->count; i++) 1003 for (i = 0; i < dev->brightness->count; i++)
995 seq_printf(seq, " %d", dev->brightness->levels[i]); 1004 seq_printf(seq, " %d", dev->brightness->levels[i]);
996 seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); 1005 seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
997 1006
998 return 0; 1007 return 0;
999 } 1008 }
1000 1009
1001 static int 1010 static int
1002 acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file) 1011 acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file)
1003 { 1012 {
1004 return single_open(file, acpi_video_device_brightness_seq_show, 1013 return single_open(file, acpi_video_device_brightness_seq_show,
1005 PDE(inode)->data); 1014 PDE(inode)->data);
1006 } 1015 }
1007 1016
1008 static ssize_t 1017 static ssize_t
1009 acpi_video_device_write_brightness(struct file *file, 1018 acpi_video_device_write_brightness(struct file *file,
1010 const char __user * buffer, 1019 const char __user * buffer,
1011 size_t count, loff_t * data) 1020 size_t count, loff_t * data)
1012 { 1021 {
1013 struct seq_file *m = file->private_data; 1022 struct seq_file *m = file->private_data;
1014 struct acpi_video_device *dev = m->private; 1023 struct acpi_video_device *dev = m->private;
1015 char str[5] = { 0 }; 1024 char str[5] = { 0 };
1016 unsigned int level = 0; 1025 unsigned int level = 0;
1017 int i; 1026 int i;
1018 1027
1019 1028
1020 if (!dev || !dev->brightness || count + 1 > sizeof str) 1029 if (!dev || !dev->brightness || count + 1 > sizeof str)
1021 return -EINVAL; 1030 return -EINVAL;
1022 1031
1023 if (copy_from_user(str, buffer, count)) 1032 if (copy_from_user(str, buffer, count))
1024 return -EFAULT; 1033 return -EFAULT;
1025 1034
1026 str[count] = 0; 1035 str[count] = 0;
1027 level = simple_strtoul(str, NULL, 0); 1036 level = simple_strtoul(str, NULL, 0);
1028 1037
1029 if (level > 100) 1038 if (level > 100)
1030 return -EFAULT; 1039 return -EFAULT;
1031 1040
1032 /* validate through the list of available levels */ 1041 /* validate through the list of available levels */
1033 for (i = 0; i < dev->brightness->count; i++) 1042 for (i = 0; i < dev->brightness->count; i++)
1034 if (level == dev->brightness->levels[i]) { 1043 if (level == dev->brightness->levels[i]) {
1035 if (ACPI_SUCCESS 1044 if (ACPI_SUCCESS
1036 (acpi_video_device_lcd_set_level(dev, level))) 1045 (acpi_video_device_lcd_set_level(dev, level)))
1037 dev->brightness->curr = level; 1046 dev->brightness->curr = level;
1038 break; 1047 break;
1039 } 1048 }
1040 1049
1041 return count; 1050 return count;
1042 } 1051 }
1043 1052
1044 static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) 1053 static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
1045 { 1054 {
1046 struct acpi_video_device *dev = seq->private; 1055 struct acpi_video_device *dev = seq->private;
1047 int status; 1056 int status;
1048 int i; 1057 int i;
1049 union acpi_object *edid = NULL; 1058 union acpi_object *edid = NULL;
1050 1059
1051 1060
1052 if (!dev) 1061 if (!dev)
1053 goto out; 1062 goto out;
1054 1063
1055 status = acpi_video_device_EDID(dev, &edid, 128); 1064 status = acpi_video_device_EDID(dev, &edid, 128);
1056 if (ACPI_FAILURE(status)) { 1065 if (ACPI_FAILURE(status)) {
1057 status = acpi_video_device_EDID(dev, &edid, 256); 1066 status = acpi_video_device_EDID(dev, &edid, 256);
1058 } 1067 }
1059 1068
1060 if (ACPI_FAILURE(status)) { 1069 if (ACPI_FAILURE(status)) {
1061 goto out; 1070 goto out;
1062 } 1071 }
1063 1072
1064 if (edid && edid->type == ACPI_TYPE_BUFFER) { 1073 if (edid && edid->type == ACPI_TYPE_BUFFER) {
1065 for (i = 0; i < edid->buffer.length; i++) 1074 for (i = 0; i < edid->buffer.length; i++)
1066 seq_putc(seq, edid->buffer.pointer[i]); 1075 seq_putc(seq, edid->buffer.pointer[i]);
1067 } 1076 }
1068 1077
1069 out: 1078 out:
1070 if (!edid) 1079 if (!edid)
1071 seq_printf(seq, "<not supported>\n"); 1080 seq_printf(seq, "<not supported>\n");
1072 else 1081 else
1073 kfree(edid); 1082 kfree(edid);
1074 1083
1075 return 0; 1084 return 0;
1076 } 1085 }
1077 1086
1078 static int 1087 static int
1079 acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file) 1088 acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
1080 { 1089 {
1081 return single_open(file, acpi_video_device_EDID_seq_show, 1090 return single_open(file, acpi_video_device_EDID_seq_show,
1082 PDE(inode)->data); 1091 PDE(inode)->data);
1083 } 1092 }
1084 1093
1085 static int acpi_video_device_add_fs(struct acpi_device *device) 1094 static int acpi_video_device_add_fs(struct acpi_device *device)
1086 { 1095 {
1087 struct proc_dir_entry *entry, *device_dir; 1096 struct proc_dir_entry *entry, *device_dir;
1088 struct acpi_video_device *vid_dev; 1097 struct acpi_video_device *vid_dev;
1089 1098
1090 vid_dev = acpi_driver_data(device); 1099 vid_dev = acpi_driver_data(device);
1091 if (!vid_dev) 1100 if (!vid_dev)
1092 return -ENODEV; 1101 return -ENODEV;
1093 1102
1094 device_dir = proc_mkdir(acpi_device_bid(device), 1103 device_dir = proc_mkdir(acpi_device_bid(device),
1095 vid_dev->video->dir); 1104 vid_dev->video->dir);
1096 if (!device_dir) 1105 if (!device_dir)
1097 return -ENOMEM; 1106 return -ENOMEM;
1098 1107
1099 device_dir->owner = THIS_MODULE; 1108 device_dir->owner = THIS_MODULE;
1100 1109
1101 /* 'info' [R] */ 1110 /* 'info' [R] */
1102 entry = proc_create_data("info", S_IRUGO, device_dir, 1111 entry = proc_create_data("info", S_IRUGO, device_dir,
1103 &acpi_video_device_info_fops, acpi_driver_data(device)); 1112 &acpi_video_device_info_fops, acpi_driver_data(device));
1104 if (!entry) 1113 if (!entry)
1105 goto err_remove_dir; 1114 goto err_remove_dir;
1106 1115
1107 /* 'state' [R/W] */ 1116 /* 'state' [R/W] */
1108 acpi_video_device_state_fops.write = acpi_video_device_write_state; 1117 acpi_video_device_state_fops.write = acpi_video_device_write_state;
1109 entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR, 1118 entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
1110 device_dir, 1119 device_dir,
1111 &acpi_video_device_state_fops, 1120 &acpi_video_device_state_fops,
1112 acpi_driver_data(device)); 1121 acpi_driver_data(device));
1113 if (!entry) 1122 if (!entry)
1114 goto err_remove_info; 1123 goto err_remove_info;
1115 1124
1116 /* 'brightness' [R/W] */ 1125 /* 'brightness' [R/W] */
1117 acpi_video_device_brightness_fops.write = 1126 acpi_video_device_brightness_fops.write =
1118 acpi_video_device_write_brightness; 1127 acpi_video_device_write_brightness;
1119 entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR, 1128 entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
1120 device_dir, 1129 device_dir,
1121 &acpi_video_device_brightness_fops, 1130 &acpi_video_device_brightness_fops,
1122 acpi_driver_data(device)); 1131 acpi_driver_data(device));
1123 if (!entry) 1132 if (!entry)
1124 goto err_remove_state; 1133 goto err_remove_state;
1125 1134
1126 /* 'EDID' [R] */ 1135 /* 'EDID' [R] */
1127 entry = proc_create_data("EDID", S_IRUGO, device_dir, 1136 entry = proc_create_data("EDID", S_IRUGO, device_dir,
1128 &acpi_video_device_EDID_fops, 1137 &acpi_video_device_EDID_fops,
1129 acpi_driver_data(device)); 1138 acpi_driver_data(device));
1130 if (!entry) 1139 if (!entry)
1131 goto err_remove_brightness; 1140 goto err_remove_brightness;
1132 1141
1133 acpi_device_dir(device) = device_dir; 1142 acpi_device_dir(device) = device_dir;
1134 1143
1135 return 0; 1144 return 0;
1136 1145
1137 err_remove_brightness: 1146 err_remove_brightness:
1138 remove_proc_entry("brightness", device_dir); 1147 remove_proc_entry("brightness", device_dir);
1139 err_remove_state: 1148 err_remove_state:
1140 remove_proc_entry("state", device_dir); 1149 remove_proc_entry("state", device_dir);
1141 err_remove_info: 1150 err_remove_info:
1142 remove_proc_entry("info", device_dir); 1151 remove_proc_entry("info", device_dir);
1143 err_remove_dir: 1152 err_remove_dir:
1144 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); 1153 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1145 return -ENOMEM; 1154 return -ENOMEM;
1146 } 1155 }
1147 1156
1148 static int acpi_video_device_remove_fs(struct acpi_device *device) 1157 static int acpi_video_device_remove_fs(struct acpi_device *device)
1149 { 1158 {
1150 struct acpi_video_device *vid_dev; 1159 struct acpi_video_device *vid_dev;
1151 struct proc_dir_entry *device_dir; 1160 struct proc_dir_entry *device_dir;
1152 1161
1153 vid_dev = acpi_driver_data(device); 1162 vid_dev = acpi_driver_data(device);
1154 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) 1163 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
1155 return -ENODEV; 1164 return -ENODEV;
1156 1165
1157 device_dir = acpi_device_dir(device); 1166 device_dir = acpi_device_dir(device);
1158 if (device_dir) { 1167 if (device_dir) {
1159 remove_proc_entry("info", device_dir); 1168 remove_proc_entry("info", device_dir);
1160 remove_proc_entry("state", device_dir); 1169 remove_proc_entry("state", device_dir);
1161 remove_proc_entry("brightness", device_dir); 1170 remove_proc_entry("brightness", device_dir);
1162 remove_proc_entry("EDID", device_dir); 1171 remove_proc_entry("EDID", device_dir);
1163 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); 1172 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1164 acpi_device_dir(device) = NULL; 1173 acpi_device_dir(device) = NULL;
1165 } 1174 }
1166 1175
1167 return 0; 1176 return 0;
1168 } 1177 }
1169 1178
1170 /* video bus */ 1179 /* video bus */
1171 static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) 1180 static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
1172 { 1181 {
1173 struct acpi_video_bus *video = seq->private; 1182 struct acpi_video_bus *video = seq->private;
1174 1183
1175 1184
1176 if (!video) 1185 if (!video)
1177 goto end; 1186 goto end;
1178 1187
1179 seq_printf(seq, "Switching heads: %s\n", 1188 seq_printf(seq, "Switching heads: %s\n",
1180 video->flags.multihead ? "yes" : "no"); 1189 video->flags.multihead ? "yes" : "no");
1181 seq_printf(seq, "Video ROM: %s\n", 1190 seq_printf(seq, "Video ROM: %s\n",
1182 video->flags.rom ? "yes" : "no"); 1191 video->flags.rom ? "yes" : "no");
1183 seq_printf(seq, "Device to be POSTed on boot: %s\n", 1192 seq_printf(seq, "Device to be POSTed on boot: %s\n",
1184 video->flags.post ? "yes" : "no"); 1193 video->flags.post ? "yes" : "no");
1185 1194
1186 end: 1195 end:
1187 return 0; 1196 return 0;
1188 } 1197 }
1189 1198
1190 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file) 1199 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
1191 { 1200 {
1192 return single_open(file, acpi_video_bus_info_seq_show, 1201 return single_open(file, acpi_video_bus_info_seq_show,
1193 PDE(inode)->data); 1202 PDE(inode)->data);
1194 } 1203 }
1195 1204
1196 static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) 1205 static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
1197 { 1206 {
1198 struct acpi_video_bus *video = seq->private; 1207 struct acpi_video_bus *video = seq->private;
1199 1208
1200 1209
1201 if (!video) 1210 if (!video)
1202 goto end; 1211 goto end;
1203 1212
1204 printk(KERN_INFO PREFIX "Please implement %s\n", __func__); 1213 printk(KERN_INFO PREFIX "Please implement %s\n", __func__);
1205 seq_printf(seq, "<TODO>\n"); 1214 seq_printf(seq, "<TODO>\n");
1206 1215
1207 end: 1216 end:
1208 return 0; 1217 return 0;
1209 } 1218 }
1210 1219
1211 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) 1220 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
1212 { 1221 {
1213 return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); 1222 return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);
1214 } 1223 }
1215 1224
1216 static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) 1225 static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
1217 { 1226 {
1218 struct acpi_video_bus *video = seq->private; 1227 struct acpi_video_bus *video = seq->private;
1219 unsigned long long options; 1228 unsigned long long options;
1220 int status; 1229 int status;
1221 1230
1222 1231
1223 if (!video) 1232 if (!video)
1224 goto end; 1233 goto end;
1225 1234
1226 status = acpi_video_bus_POST_options(video, &options); 1235 status = acpi_video_bus_POST_options(video, &options);
1227 if (ACPI_SUCCESS(status)) { 1236 if (ACPI_SUCCESS(status)) {
1228 if (!(options & 1)) { 1237 if (!(options & 1)) {
1229 printk(KERN_WARNING PREFIX 1238 printk(KERN_WARNING PREFIX
1230 "The motherboard VGA device is not listed as a possible POST device.\n"); 1239 "The motherboard VGA device is not listed as a possible POST device.\n");
1231 printk(KERN_WARNING PREFIX 1240 printk(KERN_WARNING PREFIX
1232 "This indicates a BIOS bug. Please contact the manufacturer.\n"); 1241 "This indicates a BIOS bug. Please contact the manufacturer.\n");
1233 } 1242 }
1234 printk("%llx\n", options); 1243 printk("%llx\n", options);
1235 seq_printf(seq, "can POST: <integrated video>"); 1244 seq_printf(seq, "can POST: <integrated video>");
1236 if (options & 2) 1245 if (options & 2)
1237 seq_printf(seq, " <PCI video>"); 1246 seq_printf(seq, " <PCI video>");
1238 if (options & 4) 1247 if (options & 4)
1239 seq_printf(seq, " <AGP video>"); 1248 seq_printf(seq, " <AGP video>");
1240 seq_putc(seq, '\n'); 1249 seq_putc(seq, '\n');
1241 } else 1250 } else
1242 seq_printf(seq, "<not supported>\n"); 1251 seq_printf(seq, "<not supported>\n");
1243 end: 1252 end:
1244 return 0; 1253 return 0;
1245 } 1254 }
1246 1255
1247 static int 1256 static int
1248 acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) 1257 acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
1249 { 1258 {
1250 return single_open(file, acpi_video_bus_POST_info_seq_show, 1259 return single_open(file, acpi_video_bus_POST_info_seq_show,
1251 PDE(inode)->data); 1260 PDE(inode)->data);
1252 } 1261 }
1253 1262
1254 static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) 1263 static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
1255 { 1264 {
1256 struct acpi_video_bus *video = seq->private; 1265 struct acpi_video_bus *video = seq->private;
1257 int status; 1266 int status;
1258 unsigned long long id; 1267 unsigned long long id;
1259 1268
1260 1269
1261 if (!video) 1270 if (!video)
1262 goto end; 1271 goto end;
1263 1272
1264 status = acpi_video_bus_get_POST(video, &id); 1273 status = acpi_video_bus_get_POST(video, &id);
1265 if (!ACPI_SUCCESS(status)) { 1274 if (!ACPI_SUCCESS(status)) {
1266 seq_printf(seq, "<not supported>\n"); 1275 seq_printf(seq, "<not supported>\n");
1267 goto end; 1276 goto end;
1268 } 1277 }
1269 seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]); 1278 seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]);
1270 1279
1271 end: 1280 end:
1272 return 0; 1281 return 0;
1273 } 1282 }
1274 1283
1275 static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) 1284 static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
1276 { 1285 {
1277 struct acpi_video_bus *video = seq->private; 1286 struct acpi_video_bus *video = seq->private;
1278 1287
1279 1288
1280 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); 1289 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
1281 1290
1282 return 0; 1291 return 0;
1283 } 1292 }
1284 1293
1285 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file) 1294 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file)
1286 { 1295 {
1287 return single_open(file, acpi_video_bus_POST_seq_show, 1296 return single_open(file, acpi_video_bus_POST_seq_show,
1288 PDE(inode)->data); 1297 PDE(inode)->data);
1289 } 1298 }
1290 1299
1291 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file) 1300 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file)
1292 { 1301 {
1293 return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); 1302 return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);
1294 } 1303 }
1295 1304
1296 static ssize_t 1305 static ssize_t
1297 acpi_video_bus_write_POST(struct file *file, 1306 acpi_video_bus_write_POST(struct file *file,
1298 const char __user * buffer, 1307 const char __user * buffer,
1299 size_t count, loff_t * data) 1308 size_t count, loff_t * data)
1300 { 1309 {
1301 int status; 1310 int status;
1302 struct seq_file *m = file->private_data; 1311 struct seq_file *m = file->private_data;
1303 struct acpi_video_bus *video = m->private; 1312 struct acpi_video_bus *video = m->private;
1304 char str[12] = { 0 }; 1313 char str[12] = { 0 };
1305 unsigned long long opt, options; 1314 unsigned long long opt, options;
1306 1315
1307 1316
1308 if (!video || count + 1 > sizeof str) 1317 if (!video || count + 1 > sizeof str)
1309 return -EINVAL; 1318 return -EINVAL;
1310 1319
1311 status = acpi_video_bus_POST_options(video, &options); 1320 status = acpi_video_bus_POST_options(video, &options);
1312 if (!ACPI_SUCCESS(status)) 1321 if (!ACPI_SUCCESS(status))
1313 return -EINVAL; 1322 return -EINVAL;
1314 1323
1315 if (copy_from_user(str, buffer, count)) 1324 if (copy_from_user(str, buffer, count))
1316 return -EFAULT; 1325 return -EFAULT;
1317 1326
1318 str[count] = 0; 1327 str[count] = 0;
1319 opt = strtoul(str, NULL, 0); 1328 opt = strtoul(str, NULL, 0);
1320 if (opt > 3) 1329 if (opt > 3)
1321 return -EFAULT; 1330 return -EFAULT;
1322 1331
1323 /* just in case an OEM 'forgot' the motherboard... */ 1332 /* just in case an OEM 'forgot' the motherboard... */
1324 options |= 1; 1333 options |= 1;
1325 1334
1326 if (options & (1ul << opt)) { 1335 if (options & (1ul << opt)) {
1327 status = acpi_video_bus_set_POST(video, opt); 1336 status = acpi_video_bus_set_POST(video, opt);
1328 if (!ACPI_SUCCESS(status)) 1337 if (!ACPI_SUCCESS(status))
1329 return -EFAULT; 1338 return -EFAULT;
1330 1339
1331 } 1340 }
1332 1341
1333 return count; 1342 return count;
1334 } 1343 }
1335 1344
1336 static ssize_t 1345 static ssize_t
1337 acpi_video_bus_write_DOS(struct file *file, 1346 acpi_video_bus_write_DOS(struct file *file,
1338 const char __user * buffer, 1347 const char __user * buffer,
1339 size_t count, loff_t * data) 1348 size_t count, loff_t * data)
1340 { 1349 {
1341 int status; 1350 int status;
1342 struct seq_file *m = file->private_data; 1351 struct seq_file *m = file->private_data;
1343 struct acpi_video_bus *video = m->private; 1352 struct acpi_video_bus *video = m->private;
1344 char str[12] = { 0 }; 1353 char str[12] = { 0 };
1345 unsigned long opt; 1354 unsigned long opt;
1346 1355
1347 1356
1348 if (!video || count + 1 > sizeof str) 1357 if (!video || count + 1 > sizeof str)
1349 return -EINVAL; 1358 return -EINVAL;
1350 1359
1351 if (copy_from_user(str, buffer, count)) 1360 if (copy_from_user(str, buffer, count))
1352 return -EFAULT; 1361 return -EFAULT;
1353 1362
1354 str[count] = 0; 1363 str[count] = 0;
1355 opt = strtoul(str, NULL, 0); 1364 opt = strtoul(str, NULL, 0);
1356 if (opt > 7) 1365 if (opt > 7)
1357 return -EFAULT; 1366 return -EFAULT;
1358 1367
1359 status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2); 1368 status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2);
1360 1369
1361 if (!ACPI_SUCCESS(status)) 1370 if (!ACPI_SUCCESS(status))
1362 return -EFAULT; 1371 return -EFAULT;
1363 1372
1364 return count; 1373 return count;
1365 } 1374 }
1366 1375
1367 static int acpi_video_bus_add_fs(struct acpi_device *device) 1376 static int acpi_video_bus_add_fs(struct acpi_device *device)
1368 { 1377 {
1369 struct acpi_video_bus *video = acpi_driver_data(device); 1378 struct acpi_video_bus *video = acpi_driver_data(device);
1370 struct proc_dir_entry *device_dir; 1379 struct proc_dir_entry *device_dir;
1371 struct proc_dir_entry *entry; 1380 struct proc_dir_entry *entry;
1372 1381
1373 device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir); 1382 device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
1374 if (!device_dir) 1383 if (!device_dir)
1375 return -ENOMEM; 1384 return -ENOMEM;
1376 1385
1377 device_dir->owner = THIS_MODULE; 1386 device_dir->owner = THIS_MODULE;
1378 1387
1379 /* 'info' [R] */ 1388 /* 'info' [R] */
1380 entry = proc_create_data("info", S_IRUGO, device_dir, 1389 entry = proc_create_data("info", S_IRUGO, device_dir,
1381 &acpi_video_bus_info_fops, 1390 &acpi_video_bus_info_fops,
1382 acpi_driver_data(device)); 1391 acpi_driver_data(device));
1383 if (!entry) 1392 if (!entry)
1384 goto err_remove_dir; 1393 goto err_remove_dir;
1385 1394
1386 /* 'ROM' [R] */ 1395 /* 'ROM' [R] */
1387 entry = proc_create_data("ROM", S_IRUGO, device_dir, 1396 entry = proc_create_data("ROM", S_IRUGO, device_dir,
1388 &acpi_video_bus_ROM_fops, 1397 &acpi_video_bus_ROM_fops,
1389 acpi_driver_data(device)); 1398 acpi_driver_data(device));
1390 if (!entry) 1399 if (!entry)
1391 goto err_remove_info; 1400 goto err_remove_info;
1392 1401
1393 /* 'POST_info' [R] */ 1402 /* 'POST_info' [R] */
1394 entry = proc_create_data("POST_info", S_IRUGO, device_dir, 1403 entry = proc_create_data("POST_info", S_IRUGO, device_dir,
1395 &acpi_video_bus_POST_info_fops, 1404 &acpi_video_bus_POST_info_fops,
1396 acpi_driver_data(device)); 1405 acpi_driver_data(device));
1397 if (!entry) 1406 if (!entry)
1398 goto err_remove_rom; 1407 goto err_remove_rom;
1399 1408
1400 /* 'POST' [R/W] */ 1409 /* 'POST' [R/W] */
1401 acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST; 1410 acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
1402 entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR, 1411 entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
1403 device_dir, 1412 device_dir,
1404 &acpi_video_bus_POST_fops, 1413 &acpi_video_bus_POST_fops,
1405 acpi_driver_data(device)); 1414 acpi_driver_data(device));
1406 if (!entry) 1415 if (!entry)
1407 goto err_remove_post_info; 1416 goto err_remove_post_info;
1408 1417
1409 /* 'DOS' [R/W] */ 1418 /* 'DOS' [R/W] */
1410 acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS; 1419 acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
1411 entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR, 1420 entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
1412 device_dir, 1421 device_dir,
1413 &acpi_video_bus_DOS_fops, 1422 &acpi_video_bus_DOS_fops,
1414 acpi_driver_data(device)); 1423 acpi_driver_data(device));
1415 if (!entry) 1424 if (!entry)
1416 goto err_remove_post; 1425 goto err_remove_post;
1417 1426
1418 video->dir = acpi_device_dir(device) = device_dir; 1427 video->dir = acpi_device_dir(device) = device_dir;
1419 return 0; 1428 return 0;
1420 1429
1421 err_remove_post: 1430 err_remove_post:
1422 remove_proc_entry("POST", device_dir); 1431 remove_proc_entry("POST", device_dir);
1423 err_remove_post_info: 1432 err_remove_post_info:
1424 remove_proc_entry("POST_info", device_dir); 1433 remove_proc_entry("POST_info", device_dir);
1425 err_remove_rom: 1434 err_remove_rom:
1426 remove_proc_entry("ROM", device_dir); 1435 remove_proc_entry("ROM", device_dir);
1427 err_remove_info: 1436 err_remove_info:
1428 remove_proc_entry("info", device_dir); 1437 remove_proc_entry("info", device_dir);
1429 err_remove_dir: 1438 err_remove_dir:
1430 remove_proc_entry(acpi_device_bid(device), acpi_video_dir); 1439 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1431 return -ENOMEM; 1440 return -ENOMEM;
1432 } 1441 }
1433 1442
1434 static int acpi_video_bus_remove_fs(struct acpi_device *device) 1443 static int acpi_video_bus_remove_fs(struct acpi_device *device)
1435 { 1444 {
1436 struct proc_dir_entry *device_dir = acpi_device_dir(device); 1445 struct proc_dir_entry *device_dir = acpi_device_dir(device);
1437 1446
1438 if (device_dir) { 1447 if (device_dir) {
1439 remove_proc_entry("info", device_dir); 1448 remove_proc_entry("info", device_dir);
1440 remove_proc_entry("ROM", device_dir); 1449 remove_proc_entry("ROM", device_dir);
1441 remove_proc_entry("POST_info", device_dir); 1450 remove_proc_entry("POST_info", device_dir);
1442 remove_proc_entry("POST", device_dir); 1451 remove_proc_entry("POST", device_dir);
1443 remove_proc_entry("DOS", device_dir); 1452 remove_proc_entry("DOS", device_dir);
1444 remove_proc_entry(acpi_device_bid(device), acpi_video_dir); 1453 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1445 acpi_device_dir(device) = NULL; 1454 acpi_device_dir(device) = NULL;
1446 } 1455 }
1447 1456
1448 return 0; 1457 return 0;
1449 } 1458 }
1450 1459
1451 /* -------------------------------------------------------------------------- 1460 /* --------------------------------------------------------------------------
1452 Driver Interface 1461 Driver Interface
1453 -------------------------------------------------------------------------- */ 1462 -------------------------------------------------------------------------- */
1454 1463
1455 /* device interface */ 1464 /* device interface */
1456 static struct acpi_video_device_attrib* 1465 static struct acpi_video_device_attrib*
1457 acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) 1466 acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1458 { 1467 {
1459 struct acpi_video_enumerated_device *ids; 1468 struct acpi_video_enumerated_device *ids;
1460 int i; 1469 int i;
1461 1470
1462 for (i = 0; i < video->attached_count; i++) { 1471 for (i = 0; i < video->attached_count; i++) {
1463 ids = &video->attached_array[i]; 1472 ids = &video->attached_array[i];
1464 if ((ids->value.int_val & 0xffff) == device_id) 1473 if ((ids->value.int_val & 0xffff) == device_id)
1465 return &ids->value.attrib; 1474 return &ids->value.attrib;
1466 } 1475 }
1467 1476
1468 return NULL; 1477 return NULL;
1469 } 1478 }
1470 1479
1471 static int 1480 static int
1472 acpi_video_bus_get_one_device(struct acpi_device *device, 1481 acpi_video_bus_get_one_device(struct acpi_device *device,
1473 struct acpi_video_bus *video) 1482 struct acpi_video_bus *video)
1474 { 1483 {
1475 unsigned long long device_id; 1484 unsigned long long device_id;
1476 int status; 1485 int status;
1477 struct acpi_video_device *data; 1486 struct acpi_video_device *data;
1478 struct acpi_video_device_attrib* attribute; 1487 struct acpi_video_device_attrib* attribute;
1479 1488
1480 if (!device || !video) 1489 if (!device || !video)
1481 return -EINVAL; 1490 return -EINVAL;
1482 1491
1483 status = 1492 status =
1484 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); 1493 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
1485 if (ACPI_SUCCESS(status)) { 1494 if (ACPI_SUCCESS(status)) {
1486 1495
1487 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); 1496 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
1488 if (!data) 1497 if (!data)
1489 return -ENOMEM; 1498 return -ENOMEM;
1490 1499
1491 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); 1500 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
1492 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); 1501 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1493 device->driver_data = data; 1502 device->driver_data = data;
1494 1503
1495 data->device_id = device_id; 1504 data->device_id = device_id;
1496 data->video = video; 1505 data->video = video;
1497 data->dev = device; 1506 data->dev = device;
1498 1507
1499 attribute = acpi_video_get_device_attr(video, device_id); 1508 attribute = acpi_video_get_device_attr(video, device_id);
1500 1509
1501 if((attribute != NULL) && attribute->device_id_scheme) { 1510 if((attribute != NULL) && attribute->device_id_scheme) {
1502 switch (attribute->display_type) { 1511 switch (attribute->display_type) {
1503 case ACPI_VIDEO_DISPLAY_CRT: 1512 case ACPI_VIDEO_DISPLAY_CRT:
1504 data->flags.crt = 1; 1513 data->flags.crt = 1;
1505 break; 1514 break;
1506 case ACPI_VIDEO_DISPLAY_TV: 1515 case ACPI_VIDEO_DISPLAY_TV:
1507 data->flags.tvout = 1; 1516 data->flags.tvout = 1;
1508 break; 1517 break;
1509 case ACPI_VIDEO_DISPLAY_DVI: 1518 case ACPI_VIDEO_DISPLAY_DVI:
1510 data->flags.dvi = 1; 1519 data->flags.dvi = 1;
1511 break; 1520 break;
1512 case ACPI_VIDEO_DISPLAY_LCD: 1521 case ACPI_VIDEO_DISPLAY_LCD:
1513 data->flags.lcd = 1; 1522 data->flags.lcd = 1;
1514 break; 1523 break;
1515 default: 1524 default:
1516 data->flags.unknown = 1; 1525 data->flags.unknown = 1;
1517 break; 1526 break;
1518 } 1527 }
1519 if(attribute->bios_can_detect) 1528 if(attribute->bios_can_detect)
1520 data->flags.bios = 1; 1529 data->flags.bios = 1;
1521 } else 1530 } else
1522 data->flags.unknown = 1; 1531 data->flags.unknown = 1;
1523 1532
1524 acpi_video_device_bind(video, data); 1533 acpi_video_device_bind(video, data);
1525 acpi_video_device_find_cap(data); 1534 acpi_video_device_find_cap(data);
1526 1535
1527 status = acpi_install_notify_handler(device->handle, 1536 status = acpi_install_notify_handler(device->handle,
1528 ACPI_DEVICE_NOTIFY, 1537 ACPI_DEVICE_NOTIFY,
1529 acpi_video_device_notify, 1538 acpi_video_device_notify,
1530 data); 1539 data);
1531 if (ACPI_FAILURE(status)) { 1540 if (ACPI_FAILURE(status)) {
1532 printk(KERN_ERR PREFIX 1541 printk(KERN_ERR PREFIX
1533 "Error installing notify handler\n"); 1542 "Error installing notify handler\n");
1534 if(data->brightness) 1543 if(data->brightness)
1535 kfree(data->brightness->levels); 1544 kfree(data->brightness->levels);
1536 kfree(data->brightness); 1545 kfree(data->brightness);
1537 kfree(data); 1546 kfree(data);
1538 return -ENODEV; 1547 return -ENODEV;
1539 } 1548 }
1540 1549
1541 mutex_lock(&video->device_list_lock); 1550 mutex_lock(&video->device_list_lock);
1542 list_add_tail(&data->entry, &video->video_device_list); 1551 list_add_tail(&data->entry, &video->video_device_list);
1543 mutex_unlock(&video->device_list_lock); 1552 mutex_unlock(&video->device_list_lock);
1544 1553
1545 acpi_video_device_add_fs(device); 1554 acpi_video_device_add_fs(device);
1546 1555
1547 return 0; 1556 return 0;
1548 } 1557 }
1549 1558
1550 return -ENOENT; 1559 return -ENOENT;
1551 } 1560 }
1552 1561
1553 /* 1562 /*
1554 * Arg: 1563 * Arg:
1555 * video : video bus device 1564 * video : video bus device
1556 * 1565 *
1557 * Return: 1566 * Return:
1558 * none 1567 * none
1559 * 1568 *
1560 * Enumerate the video device list of the video bus, 1569 * Enumerate the video device list of the video bus,
1561 * bind the ids with the corresponding video devices 1570 * bind the ids with the corresponding video devices
1562 * under the video bus. 1571 * under the video bus.
1563 */ 1572 */
1564 1573
1565 static void acpi_video_device_rebind(struct acpi_video_bus *video) 1574 static void acpi_video_device_rebind(struct acpi_video_bus *video)
1566 { 1575 {
1567 struct acpi_video_device *dev; 1576 struct acpi_video_device *dev;
1568 1577
1569 mutex_lock(&video->device_list_lock); 1578 mutex_lock(&video->device_list_lock);
1570 1579
1571 list_for_each_entry(dev, &video->video_device_list, entry) 1580 list_for_each_entry(dev, &video->video_device_list, entry)
1572 acpi_video_device_bind(video, dev); 1581 acpi_video_device_bind(video, dev);
1573 1582
1574 mutex_unlock(&video->device_list_lock); 1583 mutex_unlock(&video->device_list_lock);
1575 } 1584 }
1576 1585
1577 /* 1586 /*
1578 * Arg: 1587 * Arg:
1579 * video : video bus device 1588 * video : video bus device
1580 * device : video output device under the video 1589 * device : video output device under the video
1581 * bus 1590 * bus
1582 * 1591 *
1583 * Return: 1592 * Return:
1584 * none 1593 * none
1585 * 1594 *
1586 * Bind the ids with the corresponding video devices 1595 * Bind the ids with the corresponding video devices
1587 * under the video bus. 1596 * under the video bus.
1588 */ 1597 */
1589 1598
1590 static void 1599 static void
1591 acpi_video_device_bind(struct acpi_video_bus *video, 1600 acpi_video_device_bind(struct acpi_video_bus *video,
1592 struct acpi_video_device *device) 1601 struct acpi_video_device *device)
1593 { 1602 {
1594 struct acpi_video_enumerated_device *ids; 1603 struct acpi_video_enumerated_device *ids;
1595 int i; 1604 int i;
1596 1605
1597 for (i = 0; i < video->attached_count; i++) { 1606 for (i = 0; i < video->attached_count; i++) {
1598 ids = &video->attached_array[i]; 1607 ids = &video->attached_array[i];
1599 if (device->device_id == (ids->value.int_val & 0xffff)) { 1608 if (device->device_id == (ids->value.int_val & 0xffff)) {
1600 ids->bind_info = device; 1609 ids->bind_info = device;
1601 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); 1610 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
1602 } 1611 }
1603 } 1612 }
1604 } 1613 }
1605 1614
1606 /* 1615 /*
1607 * Arg: 1616 * Arg:
1608 * video : video bus device 1617 * video : video bus device
1609 * 1618 *
1610 * Return: 1619 * Return:
1611 * < 0 : error 1620 * < 0 : error
1612 * 1621 *
1613 * Call _DOD to enumerate all devices attached to display adapter 1622 * Call _DOD to enumerate all devices attached to display adapter
1614 * 1623 *
1615 */ 1624 */
1616 1625
1617 static int acpi_video_device_enumerate(struct acpi_video_bus *video) 1626 static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1618 { 1627 {
1619 int status; 1628 int status;
1620 int count; 1629 int count;
1621 int i; 1630 int i;
1622 struct acpi_video_enumerated_device *active_list; 1631 struct acpi_video_enumerated_device *active_list;
1623 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 1632 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1624 union acpi_object *dod = NULL; 1633 union acpi_object *dod = NULL;
1625 union acpi_object *obj; 1634 union acpi_object *obj;
1626 1635
1627 status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer); 1636 status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer);
1628 if (!ACPI_SUCCESS(status)) { 1637 if (!ACPI_SUCCESS(status)) {
1629 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD")); 1638 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD"));
1630 return status; 1639 return status;
1631 } 1640 }
1632 1641
1633 dod = buffer.pointer; 1642 dod = buffer.pointer;
1634 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { 1643 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
1635 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); 1644 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
1636 status = -EFAULT; 1645 status = -EFAULT;
1637 goto out; 1646 goto out;
1638 } 1647 }
1639 1648
1640 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", 1649 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
1641 dod->package.count)); 1650 dod->package.count));
1642 1651
1643 active_list = kcalloc(1 + dod->package.count, 1652 active_list = kcalloc(1 + dod->package.count,
1644 sizeof(struct acpi_video_enumerated_device), 1653 sizeof(struct acpi_video_enumerated_device),
1645 GFP_KERNEL); 1654 GFP_KERNEL);
1646 if (!active_list) { 1655 if (!active_list) {
1647 status = -ENOMEM; 1656 status = -ENOMEM;
1648 goto out; 1657 goto out;
1649 } 1658 }
1650 1659
1651 count = 0; 1660 count = 0;
1652 for (i = 0; i < dod->package.count; i++) { 1661 for (i = 0; i < dod->package.count; i++) {
1653 obj = &dod->package.elements[i]; 1662 obj = &dod->package.elements[i];
1654 1663
1655 if (obj->type != ACPI_TYPE_INTEGER) { 1664 if (obj->type != ACPI_TYPE_INTEGER) {
1656 printk(KERN_ERR PREFIX 1665 printk(KERN_ERR PREFIX
1657 "Invalid _DOD data in element %d\n", i); 1666 "Invalid _DOD data in element %d\n", i);
1658 continue; 1667 continue;
1659 } 1668 }
1660 1669
1661 active_list[count].value.int_val = obj->integer.value; 1670 active_list[count].value.int_val = obj->integer.value;
1662 active_list[count].bind_info = NULL; 1671 active_list[count].bind_info = NULL;
1663 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, 1672 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
1664 (int)obj->integer.value)); 1673 (int)obj->integer.value));
1665 count++; 1674 count++;
1666 } 1675 }
1667 1676
1668 kfree(video->attached_array); 1677 kfree(video->attached_array);
1669 1678
1670 video->attached_array = active_list; 1679 video->attached_array = active_list;
1671 video->attached_count = count; 1680 video->attached_count = count;
1672 1681
1673 out: 1682 out:
1674 kfree(buffer.pointer); 1683 kfree(buffer.pointer);
1675 return status; 1684 return status;
1676 } 1685 }
1677 1686
1678 static int 1687 static int
1679 acpi_video_get_next_level(struct acpi_video_device *device, 1688 acpi_video_get_next_level(struct acpi_video_device *device,
1680 u32 level_current, u32 event) 1689 u32 level_current, u32 event)
1681 { 1690 {
1682 int min, max, min_above, max_below, i, l, delta = 255; 1691 int min, max, min_above, max_below, i, l, delta = 255;
1683 max = max_below = 0; 1692 max = max_below = 0;
1684 min = min_above = 255; 1693 min = min_above = 255;
1685 /* Find closest level to level_current */ 1694 /* Find closest level to level_current */
1686 for (i = 0; i < device->brightness->count; i++) { 1695 for (i = 0; i < device->brightness->count; i++) {
1687 l = device->brightness->levels[i]; 1696 l = device->brightness->levels[i];
1688 if (abs(l - level_current) < abs(delta)) { 1697 if (abs(l - level_current) < abs(delta)) {
1689 delta = l - level_current; 1698 delta = l - level_current;
1690 if (!delta) 1699 if (!delta)
1691 break; 1700 break;
1692 } 1701 }
1693 } 1702 }
1694 /* Ajust level_current to closest available level */ 1703 /* Ajust level_current to closest available level */
1695 level_current += delta; 1704 level_current += delta;
1696 for (i = 0; i < device->brightness->count; i++) { 1705 for (i = 0; i < device->brightness->count; i++) {
1697 l = device->brightness->levels[i]; 1706 l = device->brightness->levels[i];
1698 if (l < min) 1707 if (l < min)
1699 min = l; 1708 min = l;
1700 if (l > max) 1709 if (l > max)
1701 max = l; 1710 max = l;
1702 if (l < min_above && l > level_current) 1711 if (l < min_above && l > level_current)
1703 min_above = l; 1712 min_above = l;
1704 if (l > max_below && l < level_current) 1713 if (l > max_below && l < level_current)
1705 max_below = l; 1714 max_below = l;
1706 } 1715 }
1707 1716
1708 switch (event) { 1717 switch (event) {
1709 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: 1718 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
1710 return (level_current < max) ? min_above : min; 1719 return (level_current < max) ? min_above : min;
1711 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: 1720 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
1712 return (level_current < max) ? min_above : max; 1721 return (level_current < max) ? min_above : max;
1713 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: 1722 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
1714 return (level_current > min) ? max_below : min; 1723 return (level_current > min) ? max_below : min;
1715 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: 1724 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
1716 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: 1725 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
1717 return 0; 1726 return 0;
1718 default: 1727 default:
1719 return level_current; 1728 return level_current;
1720 } 1729 }
1721 } 1730 }
1722 1731
1723 static void 1732 static void
1724 acpi_video_switch_brightness(struct acpi_video_device *device, int event) 1733 acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1725 { 1734 {
1726 unsigned long long level_current, level_next; 1735 unsigned long long level_current, level_next;
1727 if (!device->brightness) 1736 if (!device->brightness)
1728 return; 1737 return;
1729 acpi_video_device_lcd_get_level_current(device, &level_current); 1738 acpi_video_device_lcd_get_level_current(device, &level_current);
1730 level_next = acpi_video_get_next_level(device, level_current, event); 1739 level_next = acpi_video_get_next_level(device, level_current, event);
1731 acpi_video_device_lcd_set_level(device, level_next); 1740 acpi_video_device_lcd_set_level(device, level_next);
1732 } 1741 }
1733 1742
1734 static int 1743 static int
1735 acpi_video_bus_get_devices(struct acpi_video_bus *video, 1744 acpi_video_bus_get_devices(struct acpi_video_bus *video,
1736 struct acpi_device *device) 1745 struct acpi_device *device)
1737 { 1746 {
1738 int status = 0; 1747 int status = 0;
1739 struct acpi_device *dev; 1748 struct acpi_device *dev;
1740 1749
1741 acpi_video_device_enumerate(video); 1750 acpi_video_device_enumerate(video);
1742 1751
1743 list_for_each_entry(dev, &device->children, node) { 1752 list_for_each_entry(dev, &device->children, node) {
1744 1753
1745 status = acpi_video_bus_get_one_device(dev, video); 1754 status = acpi_video_bus_get_one_device(dev, video);
1746 if (ACPI_FAILURE(status)) { 1755 if (ACPI_FAILURE(status)) {
1747 printk(KERN_WARNING PREFIX 1756 printk(KERN_WARNING PREFIX
1748 "Cant attach device"); 1757 "Cant attach device");
1749 continue; 1758 continue;
1750 } 1759 }
1751 } 1760 }
1752 return status; 1761 return status;
1753 } 1762 }
1754 1763
1755 static int acpi_video_bus_put_one_device(struct acpi_video_device *device) 1764 static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1756 { 1765 {
1757 acpi_status status; 1766 acpi_status status;
1758 struct acpi_video_bus *video; 1767 struct acpi_video_bus *video;
1759 1768
1760 1769
1761 if (!device || !device->video) 1770 if (!device || !device->video)
1762 return -ENOENT; 1771 return -ENOENT;
1763 1772
1764 video = device->video; 1773 video = device->video;
1765 1774
1766 acpi_video_device_remove_fs(device->dev); 1775 acpi_video_device_remove_fs(device->dev);
1767 1776
1768 status = acpi_remove_notify_handler(device->dev->handle, 1777 status = acpi_remove_notify_handler(device->dev->handle,
1769 ACPI_DEVICE_NOTIFY, 1778 ACPI_DEVICE_NOTIFY,
1770 acpi_video_device_notify); 1779 acpi_video_device_notify);
1771 backlight_device_unregister(device->backlight); 1780 backlight_device_unregister(device->backlight);
1772 if (device->cdev) { 1781 if (device->cdev) {
1773 sysfs_remove_link(&device->dev->dev.kobj, 1782 sysfs_remove_link(&device->dev->dev.kobj,
1774 "thermal_cooling"); 1783 "thermal_cooling");
1775 sysfs_remove_link(&device->cdev->device.kobj, 1784 sysfs_remove_link(&device->cdev->device.kobj,
1776 "device"); 1785 "device");
1777 thermal_cooling_device_unregister(device->cdev); 1786 thermal_cooling_device_unregister(device->cdev);
1778 device->cdev = NULL; 1787 device->cdev = NULL;
1779 } 1788 }
1780 video_output_unregister(device->output_dev); 1789 video_output_unregister(device->output_dev);
1781 1790
1782 return 0; 1791 return 0;
1783 } 1792 }
1784 1793
1785 static int acpi_video_bus_put_devices(struct acpi_video_bus *video) 1794 static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1786 { 1795 {
1787 int status; 1796 int status;
1788 struct acpi_video_device *dev, *next; 1797 struct acpi_video_device *dev, *next;
1789 1798
1790 mutex_lock(&video->device_list_lock); 1799 mutex_lock(&video->device_list_lock);
1791 1800
1792 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) { 1801 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
1793 1802
1794 status = acpi_video_bus_put_one_device(dev); 1803 status = acpi_video_bus_put_one_device(dev);
1795 if (ACPI_FAILURE(status)) 1804 if (ACPI_FAILURE(status))
1796 printk(KERN_WARNING PREFIX 1805 printk(KERN_WARNING PREFIX
1797 "hhuuhhuu bug in acpi video driver.\n"); 1806 "hhuuhhuu bug in acpi video driver.\n");
1798 1807
1799 if (dev->brightness) { 1808 if (dev->brightness) {
1800 kfree(dev->brightness->levels); 1809 kfree(dev->brightness->levels);
1801 kfree(dev->brightness); 1810 kfree(dev->brightness);
1802 } 1811 }
1803 list_del(&dev->entry); 1812 list_del(&dev->entry);
1804 kfree(dev); 1813 kfree(dev);
1805 } 1814 }
1806 1815
1807 mutex_unlock(&video->device_list_lock); 1816 mutex_unlock(&video->device_list_lock);
1808 1817
1809 return 0; 1818 return 0;
1810 } 1819 }
1811 1820
1812 /* acpi_video interface */ 1821 /* acpi_video interface */
1813 1822
1814 static int acpi_video_bus_start_devices(struct acpi_video_bus *video) 1823 static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
1815 { 1824 {
1816 return acpi_video_bus_DOS(video, 0, 0); 1825 return acpi_video_bus_DOS(video, 0, 0);
1817 } 1826 }
1818 1827
1819 static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) 1828 static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
1820 { 1829 {
1821 return acpi_video_bus_DOS(video, 0, 1); 1830 return acpi_video_bus_DOS(video, 0, 1);
1822 } 1831 }
1823 1832
1824 static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) 1833 static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1825 { 1834 {
1826 struct acpi_video_bus *video = data; 1835 struct acpi_video_bus *video = data;
1827 struct acpi_device *device = NULL; 1836 struct acpi_device *device = NULL;
1828 struct input_dev *input; 1837 struct input_dev *input;
1829 int keycode; 1838 int keycode;
1830 1839
1831 if (!video) 1840 if (!video)
1832 return; 1841 return;
1833 1842
1834 device = video->device; 1843 device = video->device;
1835 input = video->input; 1844 input = video->input;
1836 1845
1837 switch (event) { 1846 switch (event) {
1838 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, 1847 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
1839 * most likely via hotkey. */ 1848 * most likely via hotkey. */
1840 acpi_bus_generate_proc_event(device, event, 0); 1849 acpi_bus_generate_proc_event(device, event, 0);
1841 keycode = KEY_SWITCHVIDEOMODE; 1850 keycode = KEY_SWITCHVIDEOMODE;
1842 break; 1851 break;
1843 1852
1844 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video 1853 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
1845 * connector. */ 1854 * connector. */
1846 acpi_video_device_enumerate(video); 1855 acpi_video_device_enumerate(video);
1847 acpi_video_device_rebind(video); 1856 acpi_video_device_rebind(video);
1848 acpi_bus_generate_proc_event(device, event, 0); 1857 acpi_bus_generate_proc_event(device, event, 0);
1849 keycode = KEY_SWITCHVIDEOMODE; 1858 keycode = KEY_SWITCHVIDEOMODE;
1850 break; 1859 break;
1851 1860
1852 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ 1861 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
1853 acpi_bus_generate_proc_event(device, event, 0); 1862 acpi_bus_generate_proc_event(device, event, 0);
1854 keycode = KEY_SWITCHVIDEOMODE; 1863 keycode = KEY_SWITCHVIDEOMODE;
1855 break; 1864 break;
1856 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ 1865 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
1857 acpi_bus_generate_proc_event(device, event, 0); 1866 acpi_bus_generate_proc_event(device, event, 0);
1858 keycode = KEY_VIDEO_NEXT; 1867 keycode = KEY_VIDEO_NEXT;
1859 break; 1868 break;
1860 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ 1869 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
1861 acpi_bus_generate_proc_event(device, event, 0); 1870 acpi_bus_generate_proc_event(device, event, 0);
1862 keycode = KEY_VIDEO_PREV; 1871 keycode = KEY_VIDEO_PREV;
1863 break; 1872 break;
1864 1873
1865 default: 1874 default:
1866 keycode = KEY_UNKNOWN; 1875 keycode = KEY_UNKNOWN;
1867 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1876 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1868 "Unsupported event [0x%x]\n", event)); 1877 "Unsupported event [0x%x]\n", event));
1869 break; 1878 break;
1870 } 1879 }
1871 1880
1872 acpi_notifier_call_chain(device, event, 0); 1881 acpi_notifier_call_chain(device, event, 0);
1873 input_report_key(input, keycode, 1); 1882 input_report_key(input, keycode, 1);
1874 input_sync(input); 1883 input_sync(input);
1875 input_report_key(input, keycode, 0); 1884 input_report_key(input, keycode, 0);
1876 input_sync(input); 1885 input_sync(input);
1877 1886
1878 return; 1887 return;
1879 } 1888 }
1880 1889
1881 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) 1890 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1882 { 1891 {
1883 struct acpi_video_device *video_device = data; 1892 struct acpi_video_device *video_device = data;
1884 struct acpi_device *device = NULL; 1893 struct acpi_device *device = NULL;
1885 struct acpi_video_bus *bus; 1894 struct acpi_video_bus *bus;
1886 struct input_dev *input; 1895 struct input_dev *input;
1887 int keycode; 1896 int keycode;
1888 1897
1889 if (!video_device) 1898 if (!video_device)
1890 return; 1899 return;
1891 1900
1892 device = video_device->dev; 1901 device = video_device->dev;
1893 bus = video_device->video; 1902 bus = video_device->video;
1894 input = bus->input; 1903 input = bus->input;
1895 1904
1896 switch (event) { 1905 switch (event) {
1897 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ 1906 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
1898 if (brightness_switch_enabled) 1907 if (brightness_switch_enabled)
1899 acpi_video_switch_brightness(video_device, event); 1908 acpi_video_switch_brightness(video_device, event);
1900 acpi_bus_generate_proc_event(device, event, 0); 1909 acpi_bus_generate_proc_event(device, event, 0);
1901 keycode = KEY_BRIGHTNESS_CYCLE; 1910 keycode = KEY_BRIGHTNESS_CYCLE;
1902 break; 1911 break;
1903 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ 1912 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
1904 if (brightness_switch_enabled) 1913 if (brightness_switch_enabled)
1905 acpi_video_switch_brightness(video_device, event); 1914 acpi_video_switch_brightness(video_device, event);
1906 acpi_bus_generate_proc_event(device, event, 0); 1915 acpi_bus_generate_proc_event(device, event, 0);
1907 keycode = KEY_BRIGHTNESSUP; 1916 keycode = KEY_BRIGHTNESSUP;
1908 break; 1917 break;
1909 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ 1918 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
1910 if (brightness_switch_enabled) 1919 if (brightness_switch_enabled)
1911 acpi_video_switch_brightness(video_device, event); 1920 acpi_video_switch_brightness(video_device, event);
1912 acpi_bus_generate_proc_event(device, event, 0); 1921 acpi_bus_generate_proc_event(device, event, 0);
1913 keycode = KEY_BRIGHTNESSDOWN; 1922 keycode = KEY_BRIGHTNESSDOWN;
1914 break; 1923 break;
1915 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ 1924 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
1916 if (brightness_switch_enabled) 1925 if (brightness_switch_enabled)
1917 acpi_video_switch_brightness(video_device, event); 1926 acpi_video_switch_brightness(video_device, event);
1918 acpi_bus_generate_proc_event(device, event, 0); 1927 acpi_bus_generate_proc_event(device, event, 0);
1919 keycode = KEY_BRIGHTNESS_ZERO; 1928 keycode = KEY_BRIGHTNESS_ZERO;
1920 break; 1929 break;
1921 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ 1930 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
1922 if (brightness_switch_enabled) 1931 if (brightness_switch_enabled)
1923 acpi_video_switch_brightness(video_device, event); 1932 acpi_video_switch_brightness(video_device, event);
1924 acpi_bus_generate_proc_event(device, event, 0); 1933 acpi_bus_generate_proc_event(device, event, 0);
1925 keycode = KEY_DISPLAY_OFF; 1934 keycode = KEY_DISPLAY_OFF;
1926 break; 1935 break;
1927 default: 1936 default:
1928 keycode = KEY_UNKNOWN; 1937 keycode = KEY_UNKNOWN;
1929 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1938 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1930 "Unsupported event [0x%x]\n", event)); 1939 "Unsupported event [0x%x]\n", event));
1931 break; 1940 break;
1932 } 1941 }
1933 1942
1934 acpi_notifier_call_chain(device, event, 0); 1943 acpi_notifier_call_chain(device, event, 0);
1935 input_report_key(input, keycode, 1); 1944 input_report_key(input, keycode, 1);
1936 input_sync(input); 1945 input_sync(input);
1937 input_report_key(input, keycode, 0); 1946 input_report_key(input, keycode, 0);
1938 input_sync(input); 1947 input_sync(input);
1939 1948
1940 return; 1949 return;
1941 } 1950 }
1942 1951
1943 static int instance; 1952 static int instance;
1944 static int acpi_video_resume(struct acpi_device *device) 1953 static int acpi_video_resume(struct acpi_device *device)
1945 { 1954 {
1946 struct acpi_video_bus *video; 1955 struct acpi_video_bus *video;
1947 struct acpi_video_device *video_device; 1956 struct acpi_video_device *video_device;
1948 int i; 1957 int i;
1949 1958
1950 if (!device || !acpi_driver_data(device)) 1959 if (!device || !acpi_driver_data(device))
1951 return -EINVAL; 1960 return -EINVAL;
1952 1961
1953 video = acpi_driver_data(device); 1962 video = acpi_driver_data(device);
1954 1963
1955 for (i = 0; i < video->attached_count; i++) { 1964 for (i = 0; i < video->attached_count; i++) {
1956 video_device = video->attached_array[i].bind_info; 1965 video_device = video->attached_array[i].bind_info;
1957 if (video_device && video_device->backlight) 1966 if (video_device && video_device->backlight)
1958 acpi_video_set_brightness(video_device->backlight); 1967 acpi_video_set_brightness(video_device->backlight);
1959 } 1968 }
1960 return AE_OK; 1969 return AE_OK;
1961 } 1970 }
1962 1971
1963 static int acpi_video_bus_add(struct acpi_device *device) 1972 static int acpi_video_bus_add(struct acpi_device *device)
1964 { 1973 {
1965 acpi_status status; 1974 acpi_status status;
1966 struct acpi_video_bus *video; 1975 struct acpi_video_bus *video;
1967 struct input_dev *input; 1976 struct input_dev *input;
1968 int error; 1977 int error;
1969 1978
1970 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); 1979 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
1971 if (!video) 1980 if (!video)
1972 return -ENOMEM; 1981 return -ENOMEM;
1973 1982
1974 /* a hack to fix the duplicate name "VID" problem on T61 */ 1983 /* a hack to fix the duplicate name "VID" problem on T61 */
1975 if (!strcmp(device->pnp.bus_id, "VID")) { 1984 if (!strcmp(device->pnp.bus_id, "VID")) {
1976 if (instance) 1985 if (instance)
1977 device->pnp.bus_id[3] = '0' + instance; 1986 device->pnp.bus_id[3] = '0' + instance;
1978 instance ++; 1987 instance ++;
1979 } 1988 }
1980 1989
1981 video->device = device; 1990 video->device = device;
1982 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); 1991 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
1983 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); 1992 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1984 device->driver_data = video; 1993 device->driver_data = video;
1985 1994
1986 acpi_video_bus_find_cap(video); 1995 acpi_video_bus_find_cap(video);
1987 error = acpi_video_bus_check(video); 1996 error = acpi_video_bus_check(video);
1988 if (error) 1997 if (error)
1989 goto err_free_video; 1998 goto err_free_video;
1990 1999
1991 error = acpi_video_bus_add_fs(device); 2000 error = acpi_video_bus_add_fs(device);
1992 if (error) 2001 if (error)
1993 goto err_free_video; 2002 goto err_free_video;
1994 2003
1995 mutex_init(&video->device_list_lock); 2004 mutex_init(&video->device_list_lock);
1996 INIT_LIST_HEAD(&video->video_device_list); 2005 INIT_LIST_HEAD(&video->video_device_list);
1997 2006
1998 acpi_video_bus_get_devices(video, device); 2007 acpi_video_bus_get_devices(video, device);
1999 acpi_video_bus_start_devices(video); 2008 acpi_video_bus_start_devices(video);
2000 2009
2001 status = acpi_install_notify_handler(device->handle, 2010 status = acpi_install_notify_handler(device->handle,
2002 ACPI_DEVICE_NOTIFY, 2011 ACPI_DEVICE_NOTIFY,
2003 acpi_video_bus_notify, video); 2012 acpi_video_bus_notify, video);
2004 if (ACPI_FAILURE(status)) { 2013 if (ACPI_FAILURE(status)) {
2005 printk(KERN_ERR PREFIX 2014 printk(KERN_ERR PREFIX
2006 "Error installing notify handler\n"); 2015 "Error installing notify handler\n");
2007 error = -ENODEV; 2016 error = -ENODEV;
2008 goto err_stop_video; 2017 goto err_stop_video;
2009 } 2018 }
2010 2019
2011 video->input = input = input_allocate_device(); 2020 video->input = input = input_allocate_device();
2012 if (!input) { 2021 if (!input) {
2013 error = -ENOMEM; 2022 error = -ENOMEM;
2014 goto err_uninstall_notify; 2023 goto err_uninstall_notify;
2015 } 2024 }
2016 2025
2017 snprintf(video->phys, sizeof(video->phys), 2026 snprintf(video->phys, sizeof(video->phys),
2018 "%s/video/input0", acpi_device_hid(video->device)); 2027 "%s/video/input0", acpi_device_hid(video->device));
2019 2028
2020 input->name = acpi_device_name(video->device); 2029 input->name = acpi_device_name(video->device);
2021 input->phys = video->phys; 2030 input->phys = video->phys;
2022 input->id.bustype = BUS_HOST; 2031 input->id.bustype = BUS_HOST;
2023 input->id.product = 0x06; 2032 input->id.product = 0x06;
2024 input->dev.parent = &device->dev; 2033 input->dev.parent = &device->dev;
2025 input->evbit[0] = BIT(EV_KEY); 2034 input->evbit[0] = BIT(EV_KEY);
2026 set_bit(KEY_SWITCHVIDEOMODE, input->keybit); 2035 set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
2027 set_bit(KEY_VIDEO_NEXT, input->keybit); 2036 set_bit(KEY_VIDEO_NEXT, input->keybit);
2028 set_bit(KEY_VIDEO_PREV, input->keybit); 2037 set_bit(KEY_VIDEO_PREV, input->keybit);
2029 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit); 2038 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
2030 set_bit(KEY_BRIGHTNESSUP, input->keybit); 2039 set_bit(KEY_BRIGHTNESSUP, input->keybit);
2031 set_bit(KEY_BRIGHTNESSDOWN, input->keybit); 2040 set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
2032 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); 2041 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
2033 set_bit(KEY_DISPLAY_OFF, input->keybit); 2042 set_bit(KEY_DISPLAY_OFF, input->keybit);
2034 set_bit(KEY_UNKNOWN, input->keybit); 2043 set_bit(KEY_UNKNOWN, input->keybit);
2035 2044
2036 error = input_register_device(input); 2045 error = input_register_device(input);
2037 if (error) 2046 if (error)
2038 goto err_free_input_dev; 2047 goto err_free_input_dev;
2039 2048
2040 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", 2049 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
2041 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 2050 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
2042 video->flags.multihead ? "yes" : "no", 2051 video->flags.multihead ? "yes" : "no",
2043 video->flags.rom ? "yes" : "no", 2052 video->flags.rom ? "yes" : "no",
2044 video->flags.post ? "yes" : "no"); 2053 video->flags.post ? "yes" : "no");
2045 2054
2046 return 0; 2055 return 0;
2047 2056
2048 err_free_input_dev: 2057 err_free_input_dev:
2049 input_free_device(input); 2058 input_free_device(input);
2050 err_uninstall_notify: 2059 err_uninstall_notify:
2051 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, 2060 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
2052 acpi_video_bus_notify); 2061 acpi_video_bus_notify);
2053 err_stop_video: 2062 err_stop_video:
2054 acpi_video_bus_stop_devices(video); 2063 acpi_video_bus_stop_devices(video);
2055 acpi_video_bus_put_devices(video); 2064 acpi_video_bus_put_devices(video);
2056 kfree(video->attached_array); 2065 kfree(video->attached_array);
2057 acpi_video_bus_remove_fs(device); 2066 acpi_video_bus_remove_fs(device);
2058 err_free_video: 2067 err_free_video:
2059 kfree(video); 2068 kfree(video);
2060 device->driver_data = NULL; 2069 device->driver_data = NULL;
2061 2070
2062 return error; 2071 return error;
2063 } 2072 }
2064 2073
2065 static int acpi_video_bus_remove(struct acpi_device *device, int type) 2074 static int acpi_video_bus_remove(struct acpi_device *device, int type)
2066 { 2075 {
2067 acpi_status status = 0; 2076 acpi_status status = 0;
2068 struct acpi_video_bus *video = NULL; 2077 struct acpi_video_bus *video = NULL;
2069 2078
2070 2079
2071 if (!device || !acpi_driver_data(device)) 2080 if (!device || !acpi_driver_data(device))
2072 return -EINVAL; 2081 return -EINVAL;
2073 2082
2074 video = acpi_driver_data(device); 2083 video = acpi_driver_data(device);
2075 2084
2076 acpi_video_bus_stop_devices(video); 2085 acpi_video_bus_stop_devices(video);
2077 2086
2078 status = acpi_remove_notify_handler(video->device->handle, 2087 status = acpi_remove_notify_handler(video->device->handle,
2079 ACPI_DEVICE_NOTIFY, 2088 ACPI_DEVICE_NOTIFY,
2080 acpi_video_bus_notify); 2089 acpi_video_bus_notify);
2081 2090
2082 acpi_video_bus_put_devices(video); 2091 acpi_video_bus_put_devices(video);
2083 acpi_video_bus_remove_fs(device); 2092 acpi_video_bus_remove_fs(device);
2084 2093
2085 input_unregister_device(video->input); 2094 input_unregister_device(video->input);
2086 kfree(video->attached_array); 2095 kfree(video->attached_array);
2087 kfree(video); 2096 kfree(video);
2088 2097
2089 return 0; 2098 return 0;
2090 } 2099 }
2091 2100
2092 static int __init acpi_video_init(void) 2101 static int __init acpi_video_init(void)
2093 { 2102 {
2094 int result = 0; 2103 int result = 0;
2095 2104
2096 acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); 2105 acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
2097 if (!acpi_video_dir) 2106 if (!acpi_video_dir)
2098 return -ENODEV; 2107 return -ENODEV;
2099 acpi_video_dir->owner = THIS_MODULE; 2108 acpi_video_dir->owner = THIS_MODULE;
2100 2109
2101 result = acpi_bus_register_driver(&acpi_video_bus); 2110 result = acpi_bus_register_driver(&acpi_video_bus);
2102 if (result < 0) { 2111 if (result < 0) {
2103 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); 2112 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2104 return -ENODEV; 2113 return -ENODEV;
2105 } 2114 }
2106 2115
2107 return 0; 2116 return 0;
2108 } 2117 }
2109 2118
2110 static void __exit acpi_video_exit(void) 2119 static void __exit acpi_video_exit(void)
2111 { 2120 {
2112 2121
2113 acpi_bus_unregister_driver(&acpi_video_bus); 2122 acpi_bus_unregister_driver(&acpi_video_bus);
2114 2123
2115 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); 2124 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2116 2125
2117 return; 2126 return;
2118 } 2127 }
2119 2128
2120 module_init(acpi_video_init); 2129 module_init(acpi_video_init);
drivers/acpi/video_detect.c
File was created 1 /*
2 * Copyright (C) 2008 SuSE Linux Products GmbH
3 * Thomas Renninger <trenn@suse.de>
4 *
5 * May be copied or modified under the terms of the GNU General Public License
6 *
7 * video_detect.c:
8 * Provides acpi_is_video_device() for early scanning of ACPI devices in scan.c
9 * There a Linux specific (Spec does not provide a HID for video devices) is
10 * assinged
11 *
12 * After PCI devices are glued with ACPI devices
13 * acpi_get_physical_pci_device() can be called to identify ACPI graphics
14 * devices for which a real graphics card is plugged in
15 *
16 * Now acpi_video_get_capabilities() can be called to check which
17 * capabilities the graphics cards plugged in support. The check for general
18 * video capabilities will be triggered by the first caller of
19 * acpi_video_get_capabilities(NULL); which will happen when the first
20 * backlight (or display output) switching supporting driver calls:
21 * acpi_video_backlight_support();
22 *
23 * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B)
24 * are available, video.ko should be used to handle the device.
25 *
26 * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi,
27 * sony_acpi,... can take care about backlight brightness and display output
28 * switching.
29 *
30 * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
31 * this file will not be compiled, acpi_video_get_capabilities() and
32 * acpi_video_backlight_support() will always return 0 and vendor specific
33 * drivers always can handle backlight.
34 *
35 */
36
37 #include <linux/acpi.h>
38 #include <linux/dmi.h>
39
40 ACPI_MODULE_NAME("video");
41 #define _COMPONENT ACPI_VIDEO_COMPONENT
42
43 static long acpi_video_support;
44 static bool acpi_video_caps_checked;
45
46 static acpi_status
47 acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
48 void **retyurn_value)
49 {
50 long *cap = context;
51 acpi_handle h_dummy;
52
53 if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) &&
54 ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) {
55 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
56 "support\n"));
57 *cap |= ACPI_VIDEO_BACKLIGHT;
58 /* We have backlight support, no need to scan further */
59 return AE_CTRL_TERMINATE;
60 }
61 return 0;
62 }
63
64 /* Returns true if the device is a video device which can be handled by
65 * video.ko.
66 * The device will get a Linux specific CID added in scan.c to
67 * identify the device as an ACPI graphics device
68 * Be aware that the graphics device may not be physically present
69 * Use acpi_video_get_capabilities() to detect general ACPI video
70 * capabilities of present cards
71 */
72 long acpi_is_video_device(struct acpi_device *device)
73 {
74 acpi_handle h_dummy;
75 long video_caps = 0;
76
77 if (!device)
78 return 0;
79
80 /* Does this device able to support video switching ? */
81 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
82 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
83 video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
84
85 /* Does this device able to retrieve a video ROM ? */
86 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
87 video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
88
89 /* Does this device able to configure which video head to be POSTed ? */
90 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
91 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
92 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
93 video_caps |= ACPI_VIDEO_DEVICE_POSTING;
94
95 /* Only check for backlight functionality if one of the above hit. */
96 if (video_caps)
97 acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle,
98 ACPI_UINT32_MAX, acpi_backlight_cap_match,
99 &video_caps, NULL);
100
101 return video_caps;
102 }
103 EXPORT_SYMBOL(acpi_is_video_device);
104
105 static acpi_status
106 find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
107 {
108 long *cap = context;
109 struct device *dev;
110 struct acpi_device *acpi_dev;
111
112 const struct acpi_device_id video_ids[] = {
113 {ACPI_VIDEO_HID, 0},
114 {"", 0},
115 };
116 if (acpi_bus_get_device(handle, &acpi_dev))
117 return AE_OK;
118
119 if (!acpi_match_device_ids(acpi_dev, video_ids)) {
120 dev = acpi_get_physical_pci_device(handle);
121 if (!dev)
122 return AE_OK;
123 put_device(dev);
124 *cap |= acpi_is_video_device(acpi_dev);
125 }
126 return AE_OK;
127 }
128
129 /*
130 * Returns the video capabilities of a specific ACPI graphics device
131 *
132 * if NULL is passed as argument all ACPI devices are enumerated and
133 * all graphics capabilities of physically present devices are
134 * summerized and returned. This is cached and done only once.
135 */
136 long acpi_video_get_capabilities(acpi_handle graphics_handle)
137 {
138 long caps = 0;
139 struct acpi_device *tmp_dev;
140 acpi_status status;
141
142 if (acpi_video_caps_checked && graphics_handle == NULL)
143 return acpi_video_support;
144
145 if (!graphics_handle) {
146 /* Only do the global walk through all graphics devices once */
147 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
148 ACPI_UINT32_MAX, find_video,
149 &caps, NULL);
150 /* There might be boot param flags set already... */
151 acpi_video_support |= caps;
152 acpi_video_caps_checked = 1;
153 /* Add blacklists here. Be careful to use the right *DMI* bits
154 * to still be able to override logic via boot params, e.g.:
155 *
156 * if (dmi_name_in_vendors("XY")) {
157 * acpi_video_support |=
158 * ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR;
159 * acpi_video_support |=
160 * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR;
161 *}
162 */
163 } else {
164 status = acpi_bus_get_device(graphics_handle, &tmp_dev);
165 if (ACPI_FAILURE(status)) {
166 ACPI_EXCEPTION((AE_INFO, status, "Invalid device"));
167 return 0;
168 }
169 acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle,
170 ACPI_UINT32_MAX, find_video,
171 &caps, NULL);
172 }
173 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n",
174 graphics_handle ? caps : acpi_video_support,
175 graphics_handle ? "on device " : "in general",
176 graphics_handle ? acpi_device_bid(tmp_dev) : ""));
177 return caps;
178 }
179 EXPORT_SYMBOL(acpi_video_get_capabilities);
180
181 /* Returns true if video.ko can do backlight switching */
182 int acpi_video_backlight_support(void)
183 {
184 /*
185 * We must check whether the ACPI graphics device is physically plugged
186 * in. Therefore this must be called after binding PCI and ACPI devices
187 */
188 if (!acpi_video_caps_checked)
189 acpi_video_get_capabilities(NULL);
190
191 /* First check for boot param -> highest prio */
192 if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR)
193 return 0;
194 else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO)
195 return 1;
196
197 /* Then check for DMI blacklist -> second highest prio */
198 if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VENDOR)
199 return 0;
200 else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VIDEO)
201 return 1;
202
203 /* Then go the default way */
204 return acpi_video_support & ACPI_VIDEO_BACKLIGHT;
205 }
206 EXPORT_SYMBOL(acpi_video_backlight_support);
207
208 /*
209 * Returns true if video.ko can do display output switching.
210 * This does not work well/at all with binary graphics drivers
211 * which disable system io ranges and do it on their own.
212 */
213 int acpi_video_display_switch_support(void)
214 {
215 if (!acpi_video_caps_checked)
216 acpi_video_get_capabilities(NULL);
217
218 if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR)
219 return 0;
220 else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO)
221 return 1;
222
223 if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR)
224 return 0;
225 else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO)
226 return 1;
227
228 return acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING;
229 }
230 EXPORT_SYMBOL(acpi_video_display_switch_support);
231
232 /*
233 * Use acpi_display_output=vendor/video or acpi_backlight=vendor/video
234 * To force that backlight or display output switching is processed by vendor
235 * specific acpi drivers or video.ko driver.
236 */
237 int __init acpi_backlight(char *str)
238 {
239 if (str == NULL || *str == '\0')
240 return 1;
241 else {
242 if (!strcmp("vendor", str))
243 acpi_video_support |=
244 ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR;
245 if (!strcmp("video", str))
246 acpi_video_support |=
247 ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO;
248 }
249 return 1;
250 }
251 __setup("acpi_backlight=", acpi_backlight);
252
253 int __init acpi_display_output(char *str)
254 {
255 if (str == NULL || *str == '\0')
256 return 1;
257 else {
258 if (!strcmp("vendor", str))
259 acpi_video_support |=
260 ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR;
261 if (!strcmp("video", str))
262 acpi_video_support |=
263 ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO;
264 }
265 return 1;
266 }
267 __setup("acpi_display_output=", acpi_display_output);
268
drivers/misc/acer-wmi.c
1 /* 1 /*
2 * Acer WMI Laptop Extras 2 * Acer WMI Laptop Extras
3 * 3 *
4 * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk> 4 * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
5 * 5 *
6 * Based on acer_acpi: 6 * Based on acer_acpi:
7 * Copyright (C) 2005-2007 E.M. Smith 7 * Copyright (C) 2005-2007 E.M. Smith
8 * Copyright (C) 2007-2008 Carlos Corbacho <cathectic@gmail.com> 8 * Copyright (C) 2007-2008 Carlos Corbacho <cathectic@gmail.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. 13 * (at your option) any later version.
14 * 14 *
15 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details. 18 * GNU General Public License for more details.
19 * 19 *
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */ 23 */
24 24
25 #include <linux/kernel.h> 25 #include <linux/kernel.h>
26 #include <linux/module.h> 26 #include <linux/module.h>
27 #include <linux/init.h> 27 #include <linux/init.h>
28 #include <linux/types.h> 28 #include <linux/types.h>
29 #include <linux/dmi.h> 29 #include <linux/dmi.h>
30 #include <linux/fb.h> 30 #include <linux/fb.h>
31 #include <linux/backlight.h> 31 #include <linux/backlight.h>
32 #include <linux/leds.h> 32 #include <linux/leds.h>
33 #include <linux/platform_device.h> 33 #include <linux/platform_device.h>
34 #include <linux/acpi.h> 34 #include <linux/acpi.h>
35 #include <linux/i8042.h> 35 #include <linux/i8042.h>
36 #include <linux/rfkill.h> 36 #include <linux/rfkill.h>
37 #include <linux/workqueue.h> 37 #include <linux/workqueue.h>
38 #include <linux/debugfs.h> 38 #include <linux/debugfs.h>
39 39
40 #include <acpi/acpi_drivers.h> 40 #include <acpi/acpi_drivers.h>
41 41
42 MODULE_AUTHOR("Carlos Corbacho"); 42 MODULE_AUTHOR("Carlos Corbacho");
43 MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver"); 43 MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver");
44 MODULE_LICENSE("GPL"); 44 MODULE_LICENSE("GPL");
45 45
46 #define ACER_LOGPREFIX "acer-wmi: " 46 #define ACER_LOGPREFIX "acer-wmi: "
47 #define ACER_ERR KERN_ERR ACER_LOGPREFIX 47 #define ACER_ERR KERN_ERR ACER_LOGPREFIX
48 #define ACER_NOTICE KERN_NOTICE ACER_LOGPREFIX 48 #define ACER_NOTICE KERN_NOTICE ACER_LOGPREFIX
49 #define ACER_INFO KERN_INFO ACER_LOGPREFIX 49 #define ACER_INFO KERN_INFO ACER_LOGPREFIX
50 50
51 /* 51 /*
52 * The following defines quirks to get some specific functions to work 52 * The following defines quirks to get some specific functions to work
53 * which are known to not be supported over ACPI-WMI (such as the mail LED 53 * which are known to not be supported over ACPI-WMI (such as the mail LED
54 * on WMID based Acer's) 54 * on WMID based Acer's)
55 */ 55 */
56 struct acer_quirks { 56 struct acer_quirks {
57 const char *vendor; 57 const char *vendor;
58 const char *model; 58 const char *model;
59 u16 quirks; 59 u16 quirks;
60 }; 60 };
61 61
62 /* 62 /*
63 * Magic Number 63 * Magic Number
64 * Meaning is unknown - this number is required for writing to ACPI for AMW0 64 * Meaning is unknown - this number is required for writing to ACPI for AMW0
65 * (it's also used in acerhk when directly accessing the BIOS) 65 * (it's also used in acerhk when directly accessing the BIOS)
66 */ 66 */
67 #define ACER_AMW0_WRITE 0x9610 67 #define ACER_AMW0_WRITE 0x9610
68 68
69 /* 69 /*
70 * Bit masks for the AMW0 interface 70 * Bit masks for the AMW0 interface
71 */ 71 */
72 #define ACER_AMW0_WIRELESS_MASK 0x35 72 #define ACER_AMW0_WIRELESS_MASK 0x35
73 #define ACER_AMW0_BLUETOOTH_MASK 0x34 73 #define ACER_AMW0_BLUETOOTH_MASK 0x34
74 #define ACER_AMW0_MAILLED_MASK 0x31 74 #define ACER_AMW0_MAILLED_MASK 0x31
75 75
76 /* 76 /*
77 * Method IDs for WMID interface 77 * Method IDs for WMID interface
78 */ 78 */
79 #define ACER_WMID_GET_WIRELESS_METHODID 1 79 #define ACER_WMID_GET_WIRELESS_METHODID 1
80 #define ACER_WMID_GET_BLUETOOTH_METHODID 2 80 #define ACER_WMID_GET_BLUETOOTH_METHODID 2
81 #define ACER_WMID_GET_BRIGHTNESS_METHODID 3 81 #define ACER_WMID_GET_BRIGHTNESS_METHODID 3
82 #define ACER_WMID_SET_WIRELESS_METHODID 4 82 #define ACER_WMID_SET_WIRELESS_METHODID 4
83 #define ACER_WMID_SET_BLUETOOTH_METHODID 5 83 #define ACER_WMID_SET_BLUETOOTH_METHODID 5
84 #define ACER_WMID_SET_BRIGHTNESS_METHODID 6 84 #define ACER_WMID_SET_BRIGHTNESS_METHODID 6
85 #define ACER_WMID_GET_THREEG_METHODID 10 85 #define ACER_WMID_GET_THREEG_METHODID 10
86 #define ACER_WMID_SET_THREEG_METHODID 11 86 #define ACER_WMID_SET_THREEG_METHODID 11
87 87
88 /* 88 /*
89 * Acer ACPI method GUIDs 89 * Acer ACPI method GUIDs
90 */ 90 */
91 #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB" 91 #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB"
92 #define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C" 92 #define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C"
93 #define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3" 93 #define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"
94 #define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A" 94 #define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
95 95
96 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); 96 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
97 MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"); 97 MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
98 98
99 /* Temporary workaround until the WMI sysfs interface goes in */ 99 /* Temporary workaround until the WMI sysfs interface goes in */
100 MODULE_ALIAS("dmi:*:*Acer*:*:"); 100 MODULE_ALIAS("dmi:*:*Acer*:*:");
101 101
102 /* 102 /*
103 * Interface capability flags 103 * Interface capability flags
104 */ 104 */
105 #define ACER_CAP_MAILLED (1<<0) 105 #define ACER_CAP_MAILLED (1<<0)
106 #define ACER_CAP_WIRELESS (1<<1) 106 #define ACER_CAP_WIRELESS (1<<1)
107 #define ACER_CAP_BLUETOOTH (1<<2) 107 #define ACER_CAP_BLUETOOTH (1<<2)
108 #define ACER_CAP_BRIGHTNESS (1<<3) 108 #define ACER_CAP_BRIGHTNESS (1<<3)
109 #define ACER_CAP_THREEG (1<<4) 109 #define ACER_CAP_THREEG (1<<4)
110 #define ACER_CAP_ANY (0xFFFFFFFF) 110 #define ACER_CAP_ANY (0xFFFFFFFF)
111 111
112 /* 112 /*
113 * Interface type flags 113 * Interface type flags
114 */ 114 */
115 enum interface_flags { 115 enum interface_flags {
116 ACER_AMW0, 116 ACER_AMW0,
117 ACER_AMW0_V2, 117 ACER_AMW0_V2,
118 ACER_WMID, 118 ACER_WMID,
119 }; 119 };
120 120
121 #define ACER_DEFAULT_WIRELESS 0 121 #define ACER_DEFAULT_WIRELESS 0
122 #define ACER_DEFAULT_BLUETOOTH 0 122 #define ACER_DEFAULT_BLUETOOTH 0
123 #define ACER_DEFAULT_MAILLED 0 123 #define ACER_DEFAULT_MAILLED 0
124 #define ACER_DEFAULT_THREEG 0 124 #define ACER_DEFAULT_THREEG 0
125 125
126 static int max_brightness = 0xF; 126 static int max_brightness = 0xF;
127 127
128 static int mailled = -1; 128 static int mailled = -1;
129 static int brightness = -1; 129 static int brightness = -1;
130 static int threeg = -1; 130 static int threeg = -1;
131 static int force_series; 131 static int force_series;
132 132
133 module_param(mailled, int, 0444); 133 module_param(mailled, int, 0444);
134 module_param(brightness, int, 0444); 134 module_param(brightness, int, 0444);
135 module_param(threeg, int, 0444); 135 module_param(threeg, int, 0444);
136 module_param(force_series, int, 0444); 136 module_param(force_series, int, 0444);
137 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); 137 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
138 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); 138 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
139 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); 139 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
140 MODULE_PARM_DESC(force_series, "Force a different laptop series"); 140 MODULE_PARM_DESC(force_series, "Force a different laptop series");
141 141
142 struct acer_data { 142 struct acer_data {
143 int mailled; 143 int mailled;
144 int threeg; 144 int threeg;
145 int brightness; 145 int brightness;
146 }; 146 };
147 147
148 struct acer_debug { 148 struct acer_debug {
149 struct dentry *root; 149 struct dentry *root;
150 struct dentry *devices; 150 struct dentry *devices;
151 u32 wmid_devices; 151 u32 wmid_devices;
152 }; 152 };
153 153
154 static struct rfkill *wireless_rfkill; 154 static struct rfkill *wireless_rfkill;
155 static struct rfkill *bluetooth_rfkill; 155 static struct rfkill *bluetooth_rfkill;
156 156
157 /* Each low-level interface must define at least some of the following */ 157 /* Each low-level interface must define at least some of the following */
158 struct wmi_interface { 158 struct wmi_interface {
159 /* The WMI device type */ 159 /* The WMI device type */
160 u32 type; 160 u32 type;
161 161
162 /* The capabilities this interface provides */ 162 /* The capabilities this interface provides */
163 u32 capability; 163 u32 capability;
164 164
165 /* Private data for the current interface */ 165 /* Private data for the current interface */
166 struct acer_data data; 166 struct acer_data data;
167 167
168 /* debugfs entries associated with this interface */ 168 /* debugfs entries associated with this interface */
169 struct acer_debug debug; 169 struct acer_debug debug;
170 }; 170 };
171 171
172 /* The static interface pointer, points to the currently detected interface */ 172 /* The static interface pointer, points to the currently detected interface */
173 static struct wmi_interface *interface; 173 static struct wmi_interface *interface;
174 174
175 /* 175 /*
176 * Embedded Controller quirks 176 * Embedded Controller quirks
177 * Some laptops require us to directly access the EC to either enable or query 177 * Some laptops require us to directly access the EC to either enable or query
178 * features that are not available through WMI. 178 * features that are not available through WMI.
179 */ 179 */
180 180
181 struct quirk_entry { 181 struct quirk_entry {
182 u8 wireless; 182 u8 wireless;
183 u8 mailled; 183 u8 mailled;
184 s8 brightness; 184 s8 brightness;
185 u8 bluetooth; 185 u8 bluetooth;
186 }; 186 };
187 187
188 static struct quirk_entry *quirks; 188 static struct quirk_entry *quirks;
189 189
190 static void set_quirks(void) 190 static void set_quirks(void)
191 { 191 {
192 if (!interface) 192 if (!interface)
193 return; 193 return;
194 194
195 if (quirks->mailled) 195 if (quirks->mailled)
196 interface->capability |= ACER_CAP_MAILLED; 196 interface->capability |= ACER_CAP_MAILLED;
197 197
198 if (quirks->brightness) 198 if (quirks->brightness)
199 interface->capability |= ACER_CAP_BRIGHTNESS; 199 interface->capability |= ACER_CAP_BRIGHTNESS;
200 } 200 }
201 201
202 static int dmi_matched(const struct dmi_system_id *dmi) 202 static int dmi_matched(const struct dmi_system_id *dmi)
203 { 203 {
204 quirks = dmi->driver_data; 204 quirks = dmi->driver_data;
205 return 0; 205 return 0;
206 } 206 }
207 207
208 static struct quirk_entry quirk_unknown = { 208 static struct quirk_entry quirk_unknown = {
209 }; 209 };
210 210
211 static struct quirk_entry quirk_acer_aspire_1520 = { 211 static struct quirk_entry quirk_acer_aspire_1520 = {
212 .brightness = -1, 212 .brightness = -1,
213 }; 213 };
214 214
215 static struct quirk_entry quirk_acer_travelmate_2490 = { 215 static struct quirk_entry quirk_acer_travelmate_2490 = {
216 .mailled = 1, 216 .mailled = 1,
217 }; 217 };
218 218
219 /* This AMW0 laptop has no bluetooth */ 219 /* This AMW0 laptop has no bluetooth */
220 static struct quirk_entry quirk_medion_md_98300 = { 220 static struct quirk_entry quirk_medion_md_98300 = {
221 .wireless = 1, 221 .wireless = 1,
222 }; 222 };
223 223
224 static struct quirk_entry quirk_fujitsu_amilo_li_1718 = { 224 static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
225 .wireless = 2, 225 .wireless = 2,
226 }; 226 };
227 227
228 static struct dmi_system_id acer_quirks[] = { 228 static struct dmi_system_id acer_quirks[] = {
229 { 229 {
230 .callback = dmi_matched, 230 .callback = dmi_matched,
231 .ident = "Acer Aspire 1360", 231 .ident = "Acer Aspire 1360",
232 .matches = { 232 .matches = {
233 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 233 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
234 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), 234 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
235 }, 235 },
236 .driver_data = &quirk_acer_aspire_1520, 236 .driver_data = &quirk_acer_aspire_1520,
237 }, 237 },
238 { 238 {
239 .callback = dmi_matched, 239 .callback = dmi_matched,
240 .ident = "Acer Aspire 1520", 240 .ident = "Acer Aspire 1520",
241 .matches = { 241 .matches = {
242 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 242 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
243 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"), 243 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"),
244 }, 244 },
245 .driver_data = &quirk_acer_aspire_1520, 245 .driver_data = &quirk_acer_aspire_1520,
246 }, 246 },
247 { 247 {
248 .callback = dmi_matched, 248 .callback = dmi_matched,
249 .ident = "Acer Aspire 3100", 249 .ident = "Acer Aspire 3100",
250 .matches = { 250 .matches = {
251 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 251 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
252 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"), 252 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
253 }, 253 },
254 .driver_data = &quirk_acer_travelmate_2490, 254 .driver_data = &quirk_acer_travelmate_2490,
255 }, 255 },
256 { 256 {
257 .callback = dmi_matched, 257 .callback = dmi_matched,
258 .ident = "Acer Aspire 3610", 258 .ident = "Acer Aspire 3610",
259 .matches = { 259 .matches = {
260 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 260 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
261 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"), 261 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"),
262 }, 262 },
263 .driver_data = &quirk_acer_travelmate_2490, 263 .driver_data = &quirk_acer_travelmate_2490,
264 }, 264 },
265 { 265 {
266 .callback = dmi_matched, 266 .callback = dmi_matched,
267 .ident = "Acer Aspire 5100", 267 .ident = "Acer Aspire 5100",
268 .matches = { 268 .matches = {
269 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 269 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
270 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), 270 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
271 }, 271 },
272 .driver_data = &quirk_acer_travelmate_2490, 272 .driver_data = &quirk_acer_travelmate_2490,
273 }, 273 },
274 { 274 {
275 .callback = dmi_matched, 275 .callback = dmi_matched,
276 .ident = "Acer Aspire 5610", 276 .ident = "Acer Aspire 5610",
277 .matches = { 277 .matches = {
278 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 278 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
279 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), 279 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
280 }, 280 },
281 .driver_data = &quirk_acer_travelmate_2490, 281 .driver_data = &quirk_acer_travelmate_2490,
282 }, 282 },
283 { 283 {
284 .callback = dmi_matched, 284 .callback = dmi_matched,
285 .ident = "Acer Aspire 5630", 285 .ident = "Acer Aspire 5630",
286 .matches = { 286 .matches = {
287 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 287 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
288 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), 288 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
289 }, 289 },
290 .driver_data = &quirk_acer_travelmate_2490, 290 .driver_data = &quirk_acer_travelmate_2490,
291 }, 291 },
292 { 292 {
293 .callback = dmi_matched, 293 .callback = dmi_matched,
294 .ident = "Acer Aspire 5650", 294 .ident = "Acer Aspire 5650",
295 .matches = { 295 .matches = {
296 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 296 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
297 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), 297 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
298 }, 298 },
299 .driver_data = &quirk_acer_travelmate_2490, 299 .driver_data = &quirk_acer_travelmate_2490,
300 }, 300 },
301 { 301 {
302 .callback = dmi_matched, 302 .callback = dmi_matched,
303 .ident = "Acer Aspire 5680", 303 .ident = "Acer Aspire 5680",
304 .matches = { 304 .matches = {
305 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 305 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
306 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), 306 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
307 }, 307 },
308 .driver_data = &quirk_acer_travelmate_2490, 308 .driver_data = &quirk_acer_travelmate_2490,
309 }, 309 },
310 { 310 {
311 .callback = dmi_matched, 311 .callback = dmi_matched,
312 .ident = "Acer Aspire 9110", 312 .ident = "Acer Aspire 9110",
313 .matches = { 313 .matches = {
314 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 314 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
315 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), 315 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
316 }, 316 },
317 .driver_data = &quirk_acer_travelmate_2490, 317 .driver_data = &quirk_acer_travelmate_2490,
318 }, 318 },
319 { 319 {
320 .callback = dmi_matched, 320 .callback = dmi_matched,
321 .ident = "Acer TravelMate 2490", 321 .ident = "Acer TravelMate 2490",
322 .matches = { 322 .matches = {
323 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 323 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
324 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), 324 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
325 }, 325 },
326 .driver_data = &quirk_acer_travelmate_2490, 326 .driver_data = &quirk_acer_travelmate_2490,
327 }, 327 },
328 { 328 {
329 .callback = dmi_matched, 329 .callback = dmi_matched,
330 .ident = "Acer TravelMate 4200", 330 .ident = "Acer TravelMate 4200",
331 .matches = { 331 .matches = {
332 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 332 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
333 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"), 333 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"),
334 }, 334 },
335 .driver_data = &quirk_acer_travelmate_2490, 335 .driver_data = &quirk_acer_travelmate_2490,
336 }, 336 },
337 { 337 {
338 .callback = dmi_matched, 338 .callback = dmi_matched,
339 .ident = "Fujitsu Siemens Amilo Li 1718", 339 .ident = "Fujitsu Siemens Amilo Li 1718",
340 .matches = { 340 .matches = {
341 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 341 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
342 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"), 342 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"),
343 }, 343 },
344 .driver_data = &quirk_fujitsu_amilo_li_1718, 344 .driver_data = &quirk_fujitsu_amilo_li_1718,
345 }, 345 },
346 { 346 {
347 .callback = dmi_matched, 347 .callback = dmi_matched,
348 .ident = "Medion MD 98300", 348 .ident = "Medion MD 98300",
349 .matches = { 349 .matches = {
350 DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), 350 DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
351 DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"), 351 DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"),
352 }, 352 },
353 .driver_data = &quirk_medion_md_98300, 353 .driver_data = &quirk_medion_md_98300,
354 }, 354 },
355 {} 355 {}
356 }; 356 };
357 357
358 /* Find which quirks are needed for a particular vendor/ model pair */ 358 /* Find which quirks are needed for a particular vendor/ model pair */
359 static void find_quirks(void) 359 static void find_quirks(void)
360 { 360 {
361 if (!force_series) { 361 if (!force_series) {
362 dmi_check_system(acer_quirks); 362 dmi_check_system(acer_quirks);
363 } else if (force_series == 2490) { 363 } else if (force_series == 2490) {
364 quirks = &quirk_acer_travelmate_2490; 364 quirks = &quirk_acer_travelmate_2490;
365 } 365 }
366 366
367 if (quirks == NULL) 367 if (quirks == NULL)
368 quirks = &quirk_unknown; 368 quirks = &quirk_unknown;
369 369
370 set_quirks(); 370 set_quirks();
371 } 371 }
372 372
373 /* 373 /*
374 * General interface convenience methods 374 * General interface convenience methods
375 */ 375 */
376 376
377 static bool has_cap(u32 cap) 377 static bool has_cap(u32 cap)
378 { 378 {
379 if ((interface->capability & cap) != 0) 379 if ((interface->capability & cap) != 0)
380 return 1; 380 return 1;
381 381
382 return 0; 382 return 0;
383 } 383 }
384 384
385 /* 385 /*
386 * AMW0 (V1) interface 386 * AMW0 (V1) interface
387 */ 387 */
388 struct wmab_args { 388 struct wmab_args {
389 u32 eax; 389 u32 eax;
390 u32 ebx; 390 u32 ebx;
391 u32 ecx; 391 u32 ecx;
392 u32 edx; 392 u32 edx;
393 }; 393 };
394 394
395 struct wmab_ret { 395 struct wmab_ret {
396 u32 eax; 396 u32 eax;
397 u32 ebx; 397 u32 ebx;
398 u32 ecx; 398 u32 ecx;
399 u32 edx; 399 u32 edx;
400 u32 eex; 400 u32 eex;
401 }; 401 };
402 402
403 static acpi_status wmab_execute(struct wmab_args *regbuf, 403 static acpi_status wmab_execute(struct wmab_args *regbuf,
404 struct acpi_buffer *result) 404 struct acpi_buffer *result)
405 { 405 {
406 struct acpi_buffer input; 406 struct acpi_buffer input;
407 acpi_status status; 407 acpi_status status;
408 input.length = sizeof(struct wmab_args); 408 input.length = sizeof(struct wmab_args);
409 input.pointer = (u8 *)regbuf; 409 input.pointer = (u8 *)regbuf;
410 410
411 status = wmi_evaluate_method(AMW0_GUID1, 1, 1, &input, result); 411 status = wmi_evaluate_method(AMW0_GUID1, 1, 1, &input, result);
412 412
413 return status; 413 return status;
414 } 414 }
415 415
416 static acpi_status AMW0_get_u32(u32 *value, u32 cap, 416 static acpi_status AMW0_get_u32(u32 *value, u32 cap,
417 struct wmi_interface *iface) 417 struct wmi_interface *iface)
418 { 418 {
419 int err; 419 int err;
420 u8 result; 420 u8 result;
421 421
422 switch (cap) { 422 switch (cap) {
423 case ACER_CAP_MAILLED: 423 case ACER_CAP_MAILLED:
424 switch (quirks->mailled) { 424 switch (quirks->mailled) {
425 default: 425 default:
426 err = ec_read(0xA, &result); 426 err = ec_read(0xA, &result);
427 if (err) 427 if (err)
428 return AE_ERROR; 428 return AE_ERROR;
429 *value = (result >> 7) & 0x1; 429 *value = (result >> 7) & 0x1;
430 return AE_OK; 430 return AE_OK;
431 } 431 }
432 break; 432 break;
433 case ACER_CAP_WIRELESS: 433 case ACER_CAP_WIRELESS:
434 switch (quirks->wireless) { 434 switch (quirks->wireless) {
435 case 1: 435 case 1:
436 err = ec_read(0x7B, &result); 436 err = ec_read(0x7B, &result);
437 if (err) 437 if (err)
438 return AE_ERROR; 438 return AE_ERROR;
439 *value = result & 0x1; 439 *value = result & 0x1;
440 return AE_OK; 440 return AE_OK;
441 case 2: 441 case 2:
442 err = ec_read(0x71, &result); 442 err = ec_read(0x71, &result);
443 if (err) 443 if (err)
444 return AE_ERROR; 444 return AE_ERROR;
445 *value = result & 0x1; 445 *value = result & 0x1;
446 return AE_OK; 446 return AE_OK;
447 default: 447 default:
448 err = ec_read(0xA, &result); 448 err = ec_read(0xA, &result);
449 if (err) 449 if (err)
450 return AE_ERROR; 450 return AE_ERROR;
451 *value = (result >> 2) & 0x1; 451 *value = (result >> 2) & 0x1;
452 return AE_OK; 452 return AE_OK;
453 } 453 }
454 break; 454 break;
455 case ACER_CAP_BLUETOOTH: 455 case ACER_CAP_BLUETOOTH:
456 switch (quirks->bluetooth) { 456 switch (quirks->bluetooth) {
457 default: 457 default:
458 err = ec_read(0xA, &result); 458 err = ec_read(0xA, &result);
459 if (err) 459 if (err)
460 return AE_ERROR; 460 return AE_ERROR;
461 *value = (result >> 4) & 0x1; 461 *value = (result >> 4) & 0x1;
462 return AE_OK; 462 return AE_OK;
463 } 463 }
464 break; 464 break;
465 case ACER_CAP_BRIGHTNESS: 465 case ACER_CAP_BRIGHTNESS:
466 switch (quirks->brightness) { 466 switch (quirks->brightness) {
467 default: 467 default:
468 err = ec_read(0x83, &result); 468 err = ec_read(0x83, &result);
469 if (err) 469 if (err)
470 return AE_ERROR; 470 return AE_ERROR;
471 *value = result; 471 *value = result;
472 return AE_OK; 472 return AE_OK;
473 } 473 }
474 break; 474 break;
475 default: 475 default:
476 return AE_ERROR; 476 return AE_ERROR;
477 } 477 }
478 return AE_OK; 478 return AE_OK;
479 } 479 }
480 480
481 static acpi_status AMW0_set_u32(u32 value, u32 cap, struct wmi_interface *iface) 481 static acpi_status AMW0_set_u32(u32 value, u32 cap, struct wmi_interface *iface)
482 { 482 {
483 struct wmab_args args; 483 struct wmab_args args;
484 484
485 args.eax = ACER_AMW0_WRITE; 485 args.eax = ACER_AMW0_WRITE;
486 args.ebx = value ? (1<<8) : 0; 486 args.ebx = value ? (1<<8) : 0;
487 args.ecx = args.edx = 0; 487 args.ecx = args.edx = 0;
488 488
489 switch (cap) { 489 switch (cap) {
490 case ACER_CAP_MAILLED: 490 case ACER_CAP_MAILLED:
491 if (value > 1) 491 if (value > 1)
492 return AE_BAD_PARAMETER; 492 return AE_BAD_PARAMETER;
493 args.ebx |= ACER_AMW0_MAILLED_MASK; 493 args.ebx |= ACER_AMW0_MAILLED_MASK;
494 break; 494 break;
495 case ACER_CAP_WIRELESS: 495 case ACER_CAP_WIRELESS:
496 if (value > 1) 496 if (value > 1)
497 return AE_BAD_PARAMETER; 497 return AE_BAD_PARAMETER;
498 args.ebx |= ACER_AMW0_WIRELESS_MASK; 498 args.ebx |= ACER_AMW0_WIRELESS_MASK;
499 break; 499 break;
500 case ACER_CAP_BLUETOOTH: 500 case ACER_CAP_BLUETOOTH:
501 if (value > 1) 501 if (value > 1)
502 return AE_BAD_PARAMETER; 502 return AE_BAD_PARAMETER;
503 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 503 args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
504 break; 504 break;
505 case ACER_CAP_BRIGHTNESS: 505 case ACER_CAP_BRIGHTNESS:
506 if (value > max_brightness) 506 if (value > max_brightness)
507 return AE_BAD_PARAMETER; 507 return AE_BAD_PARAMETER;
508 switch (quirks->brightness) { 508 switch (quirks->brightness) {
509 default: 509 default:
510 return ec_write(0x83, value); 510 return ec_write(0x83, value);
511 break; 511 break;
512 } 512 }
513 default: 513 default:
514 return AE_ERROR; 514 return AE_ERROR;
515 } 515 }
516 516
517 /* Actually do the set */ 517 /* Actually do the set */
518 return wmab_execute(&args, NULL); 518 return wmab_execute(&args, NULL);
519 } 519 }
520 520
521 static acpi_status AMW0_find_mailled(void) 521 static acpi_status AMW0_find_mailled(void)
522 { 522 {
523 struct wmab_args args; 523 struct wmab_args args;
524 struct wmab_ret ret; 524 struct wmab_ret ret;
525 acpi_status status = AE_OK; 525 acpi_status status = AE_OK;
526 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 526 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
527 union acpi_object *obj; 527 union acpi_object *obj;
528 528
529 args.eax = 0x86; 529 args.eax = 0x86;
530 args.ebx = args.ecx = args.edx = 0; 530 args.ebx = args.ecx = args.edx = 0;
531 531
532 status = wmab_execute(&args, &out); 532 status = wmab_execute(&args, &out);
533 if (ACPI_FAILURE(status)) 533 if (ACPI_FAILURE(status))
534 return status; 534 return status;
535 535
536 obj = (union acpi_object *) out.pointer; 536 obj = (union acpi_object *) out.pointer;
537 if (obj && obj->type == ACPI_TYPE_BUFFER && 537 if (obj && obj->type == ACPI_TYPE_BUFFER &&
538 obj->buffer.length == sizeof(struct wmab_ret)) { 538 obj->buffer.length == sizeof(struct wmab_ret)) {
539 ret = *((struct wmab_ret *) obj->buffer.pointer); 539 ret = *((struct wmab_ret *) obj->buffer.pointer);
540 } else { 540 } else {
541 return AE_ERROR; 541 return AE_ERROR;
542 } 542 }
543 543
544 if (ret.eex & 0x1) 544 if (ret.eex & 0x1)
545 interface->capability |= ACER_CAP_MAILLED; 545 interface->capability |= ACER_CAP_MAILLED;
546 546
547 kfree(out.pointer); 547 kfree(out.pointer);
548 548
549 return AE_OK; 549 return AE_OK;
550 } 550 }
551 551
552 static acpi_status AMW0_set_capabilities(void) 552 static acpi_status AMW0_set_capabilities(void)
553 { 553 {
554 struct wmab_args args; 554 struct wmab_args args;
555 struct wmab_ret ret; 555 struct wmab_ret ret;
556 acpi_status status = AE_OK; 556 acpi_status status = AE_OK;
557 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 557 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
558 union acpi_object *obj; 558 union acpi_object *obj;
559 559
560 /* 560 /*
561 * On laptops with this strange GUID (non Acer), normal probing doesn't 561 * On laptops with this strange GUID (non Acer), normal probing doesn't
562 * work. 562 * work.
563 */ 563 */
564 if (wmi_has_guid(AMW0_GUID2)) { 564 if (wmi_has_guid(AMW0_GUID2)) {
565 interface->capability |= ACER_CAP_WIRELESS; 565 interface->capability |= ACER_CAP_WIRELESS;
566 return AE_OK; 566 return AE_OK;
567 } 567 }
568 568
569 args.eax = ACER_AMW0_WRITE; 569 args.eax = ACER_AMW0_WRITE;
570 args.ecx = args.edx = 0; 570 args.ecx = args.edx = 0;
571 571
572 args.ebx = 0xa2 << 8; 572 args.ebx = 0xa2 << 8;
573 args.ebx |= ACER_AMW0_WIRELESS_MASK; 573 args.ebx |= ACER_AMW0_WIRELESS_MASK;
574 574
575 status = wmab_execute(&args, &out); 575 status = wmab_execute(&args, &out);
576 if (ACPI_FAILURE(status)) 576 if (ACPI_FAILURE(status))
577 return status; 577 return status;
578 578
579 obj = (union acpi_object *) out.pointer; 579 obj = (union acpi_object *) out.pointer;
580 if (obj && obj->type == ACPI_TYPE_BUFFER && 580 if (obj && obj->type == ACPI_TYPE_BUFFER &&
581 obj->buffer.length == sizeof(struct wmab_ret)) { 581 obj->buffer.length == sizeof(struct wmab_ret)) {
582 ret = *((struct wmab_ret *) obj->buffer.pointer); 582 ret = *((struct wmab_ret *) obj->buffer.pointer);
583 } else { 583 } else {
584 return AE_ERROR; 584 return AE_ERROR;
585 } 585 }
586 586
587 if (ret.eax & 0x1) 587 if (ret.eax & 0x1)
588 interface->capability |= ACER_CAP_WIRELESS; 588 interface->capability |= ACER_CAP_WIRELESS;
589 589
590 args.ebx = 2 << 8; 590 args.ebx = 2 << 8;
591 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 591 args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
592 592
593 status = wmab_execute(&args, &out); 593 status = wmab_execute(&args, &out);
594 if (ACPI_FAILURE(status)) 594 if (ACPI_FAILURE(status))
595 return status; 595 return status;
596 596
597 obj = (union acpi_object *) out.pointer; 597 obj = (union acpi_object *) out.pointer;
598 if (obj && obj->type == ACPI_TYPE_BUFFER 598 if (obj && obj->type == ACPI_TYPE_BUFFER
599 && obj->buffer.length == sizeof(struct wmab_ret)) { 599 && obj->buffer.length == sizeof(struct wmab_ret)) {
600 ret = *((struct wmab_ret *) obj->buffer.pointer); 600 ret = *((struct wmab_ret *) obj->buffer.pointer);
601 } else { 601 } else {
602 return AE_ERROR; 602 return AE_ERROR;
603 } 603 }
604 604
605 if (ret.eax & 0x1) 605 if (ret.eax & 0x1)
606 interface->capability |= ACER_CAP_BLUETOOTH; 606 interface->capability |= ACER_CAP_BLUETOOTH;
607 607
608 kfree(out.pointer); 608 kfree(out.pointer);
609 609
610 /* 610 /*
611 * This appears to be safe to enable, since all Wistron based laptops 611 * This appears to be safe to enable, since all Wistron based laptops
612 * appear to use the same EC register for brightness, even if they 612 * appear to use the same EC register for brightness, even if they
613 * differ for wireless, etc 613 * differ for wireless, etc
614 */ 614 */
615 if (quirks->brightness >= 0) 615 if (quirks->brightness >= 0)
616 interface->capability |= ACER_CAP_BRIGHTNESS; 616 interface->capability |= ACER_CAP_BRIGHTNESS;
617 617
618 return AE_OK; 618 return AE_OK;
619 } 619 }
620 620
621 static struct wmi_interface AMW0_interface = { 621 static struct wmi_interface AMW0_interface = {
622 .type = ACER_AMW0, 622 .type = ACER_AMW0,
623 }; 623 };
624 624
625 static struct wmi_interface AMW0_V2_interface = { 625 static struct wmi_interface AMW0_V2_interface = {
626 .type = ACER_AMW0_V2, 626 .type = ACER_AMW0_V2,
627 }; 627 };
628 628
629 /* 629 /*
630 * New interface (The WMID interface) 630 * New interface (The WMID interface)
631 */ 631 */
632 static acpi_status 632 static acpi_status
633 WMI_execute_u32(u32 method_id, u32 in, u32 *out) 633 WMI_execute_u32(u32 method_id, u32 in, u32 *out)
634 { 634 {
635 struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) }; 635 struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) };
636 struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; 636 struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
637 union acpi_object *obj; 637 union acpi_object *obj;
638 u32 tmp; 638 u32 tmp;
639 acpi_status status; 639 acpi_status status;
640 640
641 status = wmi_evaluate_method(WMID_GUID1, 1, method_id, &input, &result); 641 status = wmi_evaluate_method(WMID_GUID1, 1, method_id, &input, &result);
642 642
643 if (ACPI_FAILURE(status)) 643 if (ACPI_FAILURE(status))
644 return status; 644 return status;
645 645
646 obj = (union acpi_object *) result.pointer; 646 obj = (union acpi_object *) result.pointer;
647 if (obj && obj->type == ACPI_TYPE_BUFFER && 647 if (obj && obj->type == ACPI_TYPE_BUFFER &&
648 obj->buffer.length == sizeof(u32)) { 648 obj->buffer.length == sizeof(u32)) {
649 tmp = *((u32 *) obj->buffer.pointer); 649 tmp = *((u32 *) obj->buffer.pointer);
650 } else { 650 } else {
651 tmp = 0; 651 tmp = 0;
652 } 652 }
653 653
654 if (out) 654 if (out)
655 *out = tmp; 655 *out = tmp;
656 656
657 kfree(result.pointer); 657 kfree(result.pointer);
658 658
659 return status; 659 return status;
660 } 660 }
661 661
662 static acpi_status WMID_get_u32(u32 *value, u32 cap, 662 static acpi_status WMID_get_u32(u32 *value, u32 cap,
663 struct wmi_interface *iface) 663 struct wmi_interface *iface)
664 { 664 {
665 acpi_status status; 665 acpi_status status;
666 u8 tmp; 666 u8 tmp;
667 u32 result, method_id = 0; 667 u32 result, method_id = 0;
668 668
669 switch (cap) { 669 switch (cap) {
670 case ACER_CAP_WIRELESS: 670 case ACER_CAP_WIRELESS:
671 method_id = ACER_WMID_GET_WIRELESS_METHODID; 671 method_id = ACER_WMID_GET_WIRELESS_METHODID;
672 break; 672 break;
673 case ACER_CAP_BLUETOOTH: 673 case ACER_CAP_BLUETOOTH:
674 method_id = ACER_WMID_GET_BLUETOOTH_METHODID; 674 method_id = ACER_WMID_GET_BLUETOOTH_METHODID;
675 break; 675 break;
676 case ACER_CAP_BRIGHTNESS: 676 case ACER_CAP_BRIGHTNESS:
677 method_id = ACER_WMID_GET_BRIGHTNESS_METHODID; 677 method_id = ACER_WMID_GET_BRIGHTNESS_METHODID;
678 break; 678 break;
679 case ACER_CAP_THREEG: 679 case ACER_CAP_THREEG:
680 method_id = ACER_WMID_GET_THREEG_METHODID; 680 method_id = ACER_WMID_GET_THREEG_METHODID;
681 break; 681 break;
682 case ACER_CAP_MAILLED: 682 case ACER_CAP_MAILLED:
683 if (quirks->mailled == 1) { 683 if (quirks->mailled == 1) {
684 ec_read(0x9f, &tmp); 684 ec_read(0x9f, &tmp);
685 *value = tmp & 0x1; 685 *value = tmp & 0x1;
686 return 0; 686 return 0;
687 } 687 }
688 default: 688 default:
689 return AE_ERROR; 689 return AE_ERROR;
690 } 690 }
691 status = WMI_execute_u32(method_id, 0, &result); 691 status = WMI_execute_u32(method_id, 0, &result);
692 692
693 if (ACPI_SUCCESS(status)) 693 if (ACPI_SUCCESS(status))
694 *value = (u8)result; 694 *value = (u8)result;
695 695
696 return status; 696 return status;
697 } 697 }
698 698
699 static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface) 699 static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface)
700 { 700 {
701 u32 method_id = 0; 701 u32 method_id = 0;
702 char param; 702 char param;
703 703
704 switch (cap) { 704 switch (cap) {
705 case ACER_CAP_BRIGHTNESS: 705 case ACER_CAP_BRIGHTNESS:
706 if (value > max_brightness) 706 if (value > max_brightness)
707 return AE_BAD_PARAMETER; 707 return AE_BAD_PARAMETER;
708 method_id = ACER_WMID_SET_BRIGHTNESS_METHODID; 708 method_id = ACER_WMID_SET_BRIGHTNESS_METHODID;
709 break; 709 break;
710 case ACER_CAP_WIRELESS: 710 case ACER_CAP_WIRELESS:
711 if (value > 1) 711 if (value > 1)
712 return AE_BAD_PARAMETER; 712 return AE_BAD_PARAMETER;
713 method_id = ACER_WMID_SET_WIRELESS_METHODID; 713 method_id = ACER_WMID_SET_WIRELESS_METHODID;
714 break; 714 break;
715 case ACER_CAP_BLUETOOTH: 715 case ACER_CAP_BLUETOOTH:
716 if (value > 1) 716 if (value > 1)
717 return AE_BAD_PARAMETER; 717 return AE_BAD_PARAMETER;
718 method_id = ACER_WMID_SET_BLUETOOTH_METHODID; 718 method_id = ACER_WMID_SET_BLUETOOTH_METHODID;
719 break; 719 break;
720 case ACER_CAP_THREEG: 720 case ACER_CAP_THREEG:
721 if (value > 1) 721 if (value > 1)
722 return AE_BAD_PARAMETER; 722 return AE_BAD_PARAMETER;
723 method_id = ACER_WMID_SET_THREEG_METHODID; 723 method_id = ACER_WMID_SET_THREEG_METHODID;
724 break; 724 break;
725 case ACER_CAP_MAILLED: 725 case ACER_CAP_MAILLED:
726 if (value > 1) 726 if (value > 1)
727 return AE_BAD_PARAMETER; 727 return AE_BAD_PARAMETER;
728 if (quirks->mailled == 1) { 728 if (quirks->mailled == 1) {
729 param = value ? 0x92 : 0x93; 729 param = value ? 0x92 : 0x93;
730 i8042_command(&param, 0x1059); 730 i8042_command(&param, 0x1059);
731 return 0; 731 return 0;
732 } 732 }
733 break; 733 break;
734 default: 734 default:
735 return AE_ERROR; 735 return AE_ERROR;
736 } 736 }
737 return WMI_execute_u32(method_id, (u32)value, NULL); 737 return WMI_execute_u32(method_id, (u32)value, NULL);
738 } 738 }
739 739
740 static acpi_status WMID_set_capabilities(void) 740 static acpi_status WMID_set_capabilities(void)
741 { 741 {
742 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 742 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
743 union acpi_object *obj; 743 union acpi_object *obj;
744 acpi_status status; 744 acpi_status status;
745 u32 devices; 745 u32 devices;
746 746
747 status = wmi_query_block(WMID_GUID2, 1, &out); 747 status = wmi_query_block(WMID_GUID2, 1, &out);
748 if (ACPI_FAILURE(status)) 748 if (ACPI_FAILURE(status))
749 return status; 749 return status;
750 750
751 obj = (union acpi_object *) out.pointer; 751 obj = (union acpi_object *) out.pointer;
752 if (obj && obj->type == ACPI_TYPE_BUFFER && 752 if (obj && obj->type == ACPI_TYPE_BUFFER &&
753 obj->buffer.length == sizeof(u32)) { 753 obj->buffer.length == sizeof(u32)) {
754 devices = *((u32 *) obj->buffer.pointer); 754 devices = *((u32 *) obj->buffer.pointer);
755 } else { 755 } else {
756 return AE_ERROR; 756 return AE_ERROR;
757 } 757 }
758 758
759 /* Not sure on the meaning of the relevant bits yet to detect these */ 759 /* Not sure on the meaning of the relevant bits yet to detect these */
760 interface->capability |= ACER_CAP_WIRELESS; 760 interface->capability |= ACER_CAP_WIRELESS;
761 interface->capability |= ACER_CAP_THREEG; 761 interface->capability |= ACER_CAP_THREEG;
762 762
763 /* WMID always provides brightness methods */ 763 /* WMID always provides brightness methods */
764 interface->capability |= ACER_CAP_BRIGHTNESS; 764 interface->capability |= ACER_CAP_BRIGHTNESS;
765 765
766 if (devices & 0x10) 766 if (devices & 0x10)
767 interface->capability |= ACER_CAP_BLUETOOTH; 767 interface->capability |= ACER_CAP_BLUETOOTH;
768 768
769 if (!(devices & 0x20)) 769 if (!(devices & 0x20))
770 max_brightness = 0x9; 770 max_brightness = 0x9;
771 771
772 return status; 772 return status;
773 } 773 }
774 774
775 static struct wmi_interface wmid_interface = { 775 static struct wmi_interface wmid_interface = {
776 .type = ACER_WMID, 776 .type = ACER_WMID,
777 }; 777 };
778 778
779 /* 779 /*
780 * Generic Device (interface-independent) 780 * Generic Device (interface-independent)
781 */ 781 */
782 782
783 static acpi_status get_u32(u32 *value, u32 cap) 783 static acpi_status get_u32(u32 *value, u32 cap)
784 { 784 {
785 acpi_status status = AE_ERROR; 785 acpi_status status = AE_ERROR;
786 786
787 switch (interface->type) { 787 switch (interface->type) {
788 case ACER_AMW0: 788 case ACER_AMW0:
789 status = AMW0_get_u32(value, cap, interface); 789 status = AMW0_get_u32(value, cap, interface);
790 break; 790 break;
791 case ACER_AMW0_V2: 791 case ACER_AMW0_V2:
792 if (cap == ACER_CAP_MAILLED) { 792 if (cap == ACER_CAP_MAILLED) {
793 status = AMW0_get_u32(value, cap, interface); 793 status = AMW0_get_u32(value, cap, interface);
794 break; 794 break;
795 } 795 }
796 case ACER_WMID: 796 case ACER_WMID:
797 status = WMID_get_u32(value, cap, interface); 797 status = WMID_get_u32(value, cap, interface);
798 break; 798 break;
799 } 799 }
800 800
801 return status; 801 return status;
802 } 802 }
803 803
804 static acpi_status set_u32(u32 value, u32 cap) 804 static acpi_status set_u32(u32 value, u32 cap)
805 { 805 {
806 acpi_status status; 806 acpi_status status;
807 807
808 if (interface->capability & cap) { 808 if (interface->capability & cap) {
809 switch (interface->type) { 809 switch (interface->type) {
810 case ACER_AMW0: 810 case ACER_AMW0:
811 return AMW0_set_u32(value, cap, interface); 811 return AMW0_set_u32(value, cap, interface);
812 case ACER_AMW0_V2: 812 case ACER_AMW0_V2:
813 if (cap == ACER_CAP_MAILLED) 813 if (cap == ACER_CAP_MAILLED)
814 return AMW0_set_u32(value, cap, interface); 814 return AMW0_set_u32(value, cap, interface);
815 815
816 /* 816 /*
817 * On some models, some WMID methods don't toggle 817 * On some models, some WMID methods don't toggle
818 * properly. For those cases, we want to run the AMW0 818 * properly. For those cases, we want to run the AMW0
819 * method afterwards to be certain we've really toggled 819 * method afterwards to be certain we've really toggled
820 * the device state. 820 * the device state.
821 */ 821 */
822 if (cap == ACER_CAP_WIRELESS || 822 if (cap == ACER_CAP_WIRELESS ||
823 cap == ACER_CAP_BLUETOOTH) { 823 cap == ACER_CAP_BLUETOOTH) {
824 status = WMID_set_u32(value, cap, interface); 824 status = WMID_set_u32(value, cap, interface);
825 if (ACPI_FAILURE(status)) 825 if (ACPI_FAILURE(status))
826 return status; 826 return status;
827 827
828 return AMW0_set_u32(value, cap, interface); 828 return AMW0_set_u32(value, cap, interface);
829 } 829 }
830 case ACER_WMID: 830 case ACER_WMID:
831 return WMID_set_u32(value, cap, interface); 831 return WMID_set_u32(value, cap, interface);
832 default: 832 default:
833 return AE_BAD_PARAMETER; 833 return AE_BAD_PARAMETER;
834 } 834 }
835 } 835 }
836 return AE_BAD_PARAMETER; 836 return AE_BAD_PARAMETER;
837 } 837 }
838 838
839 static void __init acer_commandline_init(void) 839 static void __init acer_commandline_init(void)
840 { 840 {
841 /* 841 /*
842 * These will all fail silently if the value given is invalid, or the 842 * These will all fail silently if the value given is invalid, or the
843 * capability isn't available on the given interface 843 * capability isn't available on the given interface
844 */ 844 */
845 set_u32(mailled, ACER_CAP_MAILLED); 845 set_u32(mailled, ACER_CAP_MAILLED);
846 set_u32(threeg, ACER_CAP_THREEG); 846 set_u32(threeg, ACER_CAP_THREEG);
847 set_u32(brightness, ACER_CAP_BRIGHTNESS); 847 set_u32(brightness, ACER_CAP_BRIGHTNESS);
848 } 848 }
849 849
850 /* 850 /*
851 * LED device (Mail LED only, no other LEDs known yet) 851 * LED device (Mail LED only, no other LEDs known yet)
852 */ 852 */
853 static void mail_led_set(struct led_classdev *led_cdev, 853 static void mail_led_set(struct led_classdev *led_cdev,
854 enum led_brightness value) 854 enum led_brightness value)
855 { 855 {
856 set_u32(value, ACER_CAP_MAILLED); 856 set_u32(value, ACER_CAP_MAILLED);
857 } 857 }
858 858
859 static struct led_classdev mail_led = { 859 static struct led_classdev mail_led = {
860 .name = "acer-wmi::mail", 860 .name = "acer-wmi::mail",
861 .brightness_set = mail_led_set, 861 .brightness_set = mail_led_set,
862 }; 862 };
863 863
864 static int __devinit acer_led_init(struct device *dev) 864 static int __devinit acer_led_init(struct device *dev)
865 { 865 {
866 return led_classdev_register(dev, &mail_led); 866 return led_classdev_register(dev, &mail_led);
867 } 867 }
868 868
869 static void acer_led_exit(void) 869 static void acer_led_exit(void)
870 { 870 {
871 led_classdev_unregister(&mail_led); 871 led_classdev_unregister(&mail_led);
872 } 872 }
873 873
874 /* 874 /*
875 * Backlight device 875 * Backlight device
876 */ 876 */
877 static struct backlight_device *acer_backlight_device; 877 static struct backlight_device *acer_backlight_device;
878 878
879 static int read_brightness(struct backlight_device *bd) 879 static int read_brightness(struct backlight_device *bd)
880 { 880 {
881 u32 value; 881 u32 value;
882 get_u32(&value, ACER_CAP_BRIGHTNESS); 882 get_u32(&value, ACER_CAP_BRIGHTNESS);
883 return value; 883 return value;
884 } 884 }
885 885
886 static int update_bl_status(struct backlight_device *bd) 886 static int update_bl_status(struct backlight_device *bd)
887 { 887 {
888 int intensity = bd->props.brightness; 888 int intensity = bd->props.brightness;
889 889
890 if (bd->props.power != FB_BLANK_UNBLANK) 890 if (bd->props.power != FB_BLANK_UNBLANK)
891 intensity = 0; 891 intensity = 0;
892 if (bd->props.fb_blank != FB_BLANK_UNBLANK) 892 if (bd->props.fb_blank != FB_BLANK_UNBLANK)
893 intensity = 0; 893 intensity = 0;
894 894
895 set_u32(intensity, ACER_CAP_BRIGHTNESS); 895 set_u32(intensity, ACER_CAP_BRIGHTNESS);
896 896
897 return 0; 897 return 0;
898 } 898 }
899 899
900 static struct backlight_ops acer_bl_ops = { 900 static struct backlight_ops acer_bl_ops = {
901 .get_brightness = read_brightness, 901 .get_brightness = read_brightness,
902 .update_status = update_bl_status, 902 .update_status = update_bl_status,
903 }; 903 };
904 904
905 static int __devinit acer_backlight_init(struct device *dev) 905 static int __devinit acer_backlight_init(struct device *dev)
906 { 906 {
907 struct backlight_device *bd; 907 struct backlight_device *bd;
908 908
909 bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops); 909 bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops);
910 if (IS_ERR(bd)) { 910 if (IS_ERR(bd)) {
911 printk(ACER_ERR "Could not register Acer backlight device\n"); 911 printk(ACER_ERR "Could not register Acer backlight device\n");
912 acer_backlight_device = NULL; 912 acer_backlight_device = NULL;
913 return PTR_ERR(bd); 913 return PTR_ERR(bd);
914 } 914 }
915 915
916 acer_backlight_device = bd; 916 acer_backlight_device = bd;
917 917
918 bd->props.power = FB_BLANK_UNBLANK; 918 bd->props.power = FB_BLANK_UNBLANK;
919 bd->props.brightness = max_brightness; 919 bd->props.brightness = max_brightness;
920 bd->props.max_brightness = max_brightness; 920 bd->props.max_brightness = max_brightness;
921 backlight_update_status(bd); 921 backlight_update_status(bd);
922 return 0; 922 return 0;
923 } 923 }
924 924
925 static void acer_backlight_exit(void) 925 static void acer_backlight_exit(void)
926 { 926 {
927 backlight_device_unregister(acer_backlight_device); 927 backlight_device_unregister(acer_backlight_device);
928 } 928 }
929 929
930 /* 930 /*
931 * Rfkill devices 931 * Rfkill devices
932 */ 932 */
933 static void acer_rfkill_update(struct work_struct *ignored); 933 static void acer_rfkill_update(struct work_struct *ignored);
934 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update); 934 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update);
935 static void acer_rfkill_update(struct work_struct *ignored) 935 static void acer_rfkill_update(struct work_struct *ignored)
936 { 936 {
937 u32 state; 937 u32 state;
938 acpi_status status; 938 acpi_status status;
939 939
940 status = get_u32(&state, ACER_CAP_WIRELESS); 940 status = get_u32(&state, ACER_CAP_WIRELESS);
941 if (ACPI_SUCCESS(status)) 941 if (ACPI_SUCCESS(status))
942 rfkill_force_state(wireless_rfkill, state ? 942 rfkill_force_state(wireless_rfkill, state ?
943 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED); 943 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED);
944 944
945 if (has_cap(ACER_CAP_BLUETOOTH)) { 945 if (has_cap(ACER_CAP_BLUETOOTH)) {
946 status = get_u32(&state, ACER_CAP_BLUETOOTH); 946 status = get_u32(&state, ACER_CAP_BLUETOOTH);
947 if (ACPI_SUCCESS(status)) 947 if (ACPI_SUCCESS(status))
948 rfkill_force_state(bluetooth_rfkill, state ? 948 rfkill_force_state(bluetooth_rfkill, state ?
949 RFKILL_STATE_UNBLOCKED : 949 RFKILL_STATE_UNBLOCKED :
950 RFKILL_STATE_SOFT_BLOCKED); 950 RFKILL_STATE_SOFT_BLOCKED);
951 } 951 }
952 952
953 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); 953 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
954 } 954 }
955 955
956 static int acer_rfkill_set(void *data, enum rfkill_state state) 956 static int acer_rfkill_set(void *data, enum rfkill_state state)
957 { 957 {
958 acpi_status status; 958 acpi_status status;
959 u32 *cap = data; 959 u32 *cap = data;
960 status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap); 960 status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap);
961 if (ACPI_FAILURE(status)) 961 if (ACPI_FAILURE(status))
962 return -ENODEV; 962 return -ENODEV;
963 return 0; 963 return 0;
964 } 964 }
965 965
966 static struct rfkill * acer_rfkill_register(struct device *dev, 966 static struct rfkill * acer_rfkill_register(struct device *dev,
967 enum rfkill_type type, char *name, u32 cap) 967 enum rfkill_type type, char *name, u32 cap)
968 { 968 {
969 int err; 969 int err;
970 u32 state; 970 u32 state;
971 u32 *data; 971 u32 *data;
972 struct rfkill *rfkill_dev; 972 struct rfkill *rfkill_dev;
973 973
974 rfkill_dev = rfkill_allocate(dev, type); 974 rfkill_dev = rfkill_allocate(dev, type);
975 if (!rfkill_dev) 975 if (!rfkill_dev)
976 return ERR_PTR(-ENOMEM); 976 return ERR_PTR(-ENOMEM);
977 rfkill_dev->name = name; 977 rfkill_dev->name = name;
978 get_u32(&state, cap); 978 get_u32(&state, cap);
979 rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED : 979 rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED :
980 RFKILL_STATE_SOFT_BLOCKED; 980 RFKILL_STATE_SOFT_BLOCKED;
981 data = kzalloc(sizeof(u32), GFP_KERNEL); 981 data = kzalloc(sizeof(u32), GFP_KERNEL);
982 if (!data) { 982 if (!data) {
983 rfkill_free(rfkill_dev); 983 rfkill_free(rfkill_dev);
984 return ERR_PTR(-ENOMEM); 984 return ERR_PTR(-ENOMEM);
985 } 985 }
986 *data = cap; 986 *data = cap;
987 rfkill_dev->data = data; 987 rfkill_dev->data = data;
988 rfkill_dev->toggle_radio = acer_rfkill_set; 988 rfkill_dev->toggle_radio = acer_rfkill_set;
989 rfkill_dev->user_claim_unsupported = 1; 989 rfkill_dev->user_claim_unsupported = 1;
990 990
991 err = rfkill_register(rfkill_dev); 991 err = rfkill_register(rfkill_dev);
992 if (err) { 992 if (err) {
993 kfree(rfkill_dev->data); 993 kfree(rfkill_dev->data);
994 rfkill_free(rfkill_dev); 994 rfkill_free(rfkill_dev);
995 return ERR_PTR(err); 995 return ERR_PTR(err);
996 } 996 }
997 return rfkill_dev; 997 return rfkill_dev;
998 } 998 }
999 999
1000 static int acer_rfkill_init(struct device *dev) 1000 static int acer_rfkill_init(struct device *dev)
1001 { 1001 {
1002 wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, 1002 wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
1003 "acer-wireless", ACER_CAP_WIRELESS); 1003 "acer-wireless", ACER_CAP_WIRELESS);
1004 if (IS_ERR(wireless_rfkill)) 1004 if (IS_ERR(wireless_rfkill))
1005 return PTR_ERR(wireless_rfkill); 1005 return PTR_ERR(wireless_rfkill);
1006 1006
1007 if (has_cap(ACER_CAP_BLUETOOTH)) { 1007 if (has_cap(ACER_CAP_BLUETOOTH)) {
1008 bluetooth_rfkill = acer_rfkill_register(dev, 1008 bluetooth_rfkill = acer_rfkill_register(dev,
1009 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", 1009 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
1010 ACER_CAP_BLUETOOTH); 1010 ACER_CAP_BLUETOOTH);
1011 if (IS_ERR(bluetooth_rfkill)) { 1011 if (IS_ERR(bluetooth_rfkill)) {
1012 kfree(wireless_rfkill->data); 1012 kfree(wireless_rfkill->data);
1013 rfkill_unregister(wireless_rfkill); 1013 rfkill_unregister(wireless_rfkill);
1014 return PTR_ERR(bluetooth_rfkill); 1014 return PTR_ERR(bluetooth_rfkill);
1015 } 1015 }
1016 } 1016 }
1017 1017
1018 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); 1018 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
1019 1019
1020 return 0; 1020 return 0;
1021 } 1021 }
1022 1022
1023 static void acer_rfkill_exit(void) 1023 static void acer_rfkill_exit(void)
1024 { 1024 {
1025 cancel_delayed_work_sync(&acer_rfkill_work); 1025 cancel_delayed_work_sync(&acer_rfkill_work);
1026 kfree(wireless_rfkill->data); 1026 kfree(wireless_rfkill->data);
1027 rfkill_unregister(wireless_rfkill); 1027 rfkill_unregister(wireless_rfkill);
1028 if (has_cap(ACER_CAP_BLUETOOTH)) { 1028 if (has_cap(ACER_CAP_BLUETOOTH)) {
1029 kfree(wireless_rfkill->data); 1029 kfree(wireless_rfkill->data);
1030 rfkill_unregister(bluetooth_rfkill); 1030 rfkill_unregister(bluetooth_rfkill);
1031 } 1031 }
1032 return; 1032 return;
1033 } 1033 }
1034 1034
1035 /* 1035 /*
1036 * sysfs interface 1036 * sysfs interface
1037 */ 1037 */
1038 static ssize_t show_bool_threeg(struct device *dev, 1038 static ssize_t show_bool_threeg(struct device *dev,
1039 struct device_attribute *attr, char *buf) 1039 struct device_attribute *attr, char *buf)
1040 { 1040 {
1041 u32 result; \ 1041 u32 result; \
1042 acpi_status status = get_u32(&result, ACER_CAP_THREEG); 1042 acpi_status status = get_u32(&result, ACER_CAP_THREEG);
1043 if (ACPI_SUCCESS(status)) 1043 if (ACPI_SUCCESS(status))
1044 return sprintf(buf, "%u\n", result); 1044 return sprintf(buf, "%u\n", result);
1045 return sprintf(buf, "Read error\n"); 1045 return sprintf(buf, "Read error\n");
1046 } 1046 }
1047 1047
1048 static ssize_t set_bool_threeg(struct device *dev, 1048 static ssize_t set_bool_threeg(struct device *dev,
1049 struct device_attribute *attr, const char *buf, size_t count) 1049 struct device_attribute *attr, const char *buf, size_t count)
1050 { 1050 {
1051 u32 tmp = simple_strtoul(buf, NULL, 10); 1051 u32 tmp = simple_strtoul(buf, NULL, 10);
1052 acpi_status status = set_u32(tmp, ACER_CAP_THREEG); 1052 acpi_status status = set_u32(tmp, ACER_CAP_THREEG);
1053 if (ACPI_FAILURE(status)) 1053 if (ACPI_FAILURE(status))
1054 return -EINVAL; 1054 return -EINVAL;
1055 return count; 1055 return count;
1056 } 1056 }
1057 static DEVICE_ATTR(threeg, S_IWUGO | S_IRUGO | S_IWUSR, show_bool_threeg, 1057 static DEVICE_ATTR(threeg, S_IWUGO | S_IRUGO | S_IWUSR, show_bool_threeg,
1058 set_bool_threeg); 1058 set_bool_threeg);
1059 1059
1060 static ssize_t show_interface(struct device *dev, struct device_attribute *attr, 1060 static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
1061 char *buf) 1061 char *buf)
1062 { 1062 {
1063 switch (interface->type) { 1063 switch (interface->type) {
1064 case ACER_AMW0: 1064 case ACER_AMW0:
1065 return sprintf(buf, "AMW0\n"); 1065 return sprintf(buf, "AMW0\n");
1066 case ACER_AMW0_V2: 1066 case ACER_AMW0_V2:
1067 return sprintf(buf, "AMW0 v2\n"); 1067 return sprintf(buf, "AMW0 v2\n");
1068 case ACER_WMID: 1068 case ACER_WMID:
1069 return sprintf(buf, "WMID\n"); 1069 return sprintf(buf, "WMID\n");
1070 default: 1070 default:
1071 return sprintf(buf, "Error!\n"); 1071 return sprintf(buf, "Error!\n");
1072 } 1072 }
1073 } 1073 }
1074 1074
1075 static DEVICE_ATTR(interface, S_IWUGO | S_IRUGO | S_IWUSR, 1075 static DEVICE_ATTR(interface, S_IWUGO | S_IRUGO | S_IWUSR,
1076 show_interface, NULL); 1076 show_interface, NULL);
1077 1077
1078 /* 1078 /*
1079 * debugfs functions 1079 * debugfs functions
1080 */ 1080 */
1081 static u32 get_wmid_devices(void) 1081 static u32 get_wmid_devices(void)
1082 { 1082 {
1083 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 1083 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
1084 union acpi_object *obj; 1084 union acpi_object *obj;
1085 acpi_status status; 1085 acpi_status status;
1086 1086
1087 status = wmi_query_block(WMID_GUID2, 1, &out); 1087 status = wmi_query_block(WMID_GUID2, 1, &out);
1088 if (ACPI_FAILURE(status)) 1088 if (ACPI_FAILURE(status))
1089 return 0; 1089 return 0;
1090 1090
1091 obj = (union acpi_object *) out.pointer; 1091 obj = (union acpi_object *) out.pointer;
1092 if (obj && obj->type == ACPI_TYPE_BUFFER && 1092 if (obj && obj->type == ACPI_TYPE_BUFFER &&
1093 obj->buffer.length == sizeof(u32)) { 1093 obj->buffer.length == sizeof(u32)) {
1094 return *((u32 *) obj->buffer.pointer); 1094 return *((u32 *) obj->buffer.pointer);
1095 } else { 1095 } else {
1096 return 0; 1096 return 0;
1097 } 1097 }
1098 } 1098 }
1099 1099
1100 /* 1100 /*
1101 * Platform device 1101 * Platform device
1102 */ 1102 */
1103 static int __devinit acer_platform_probe(struct platform_device *device) 1103 static int __devinit acer_platform_probe(struct platform_device *device)
1104 { 1104 {
1105 int err; 1105 int err;
1106 1106
1107 if (has_cap(ACER_CAP_MAILLED)) { 1107 if (has_cap(ACER_CAP_MAILLED)) {
1108 err = acer_led_init(&device->dev); 1108 err = acer_led_init(&device->dev);
1109 if (err) 1109 if (err)
1110 goto error_mailled; 1110 goto error_mailled;
1111 } 1111 }
1112 1112
1113 if (has_cap(ACER_CAP_BRIGHTNESS)) { 1113 if (has_cap(ACER_CAP_BRIGHTNESS)) {
1114 err = acer_backlight_init(&device->dev); 1114 err = acer_backlight_init(&device->dev);
1115 if (err) 1115 if (err)
1116 goto error_brightness; 1116 goto error_brightness;
1117 } 1117 }
1118 1118
1119 err = acer_rfkill_init(&device->dev); 1119 err = acer_rfkill_init(&device->dev);
1120 1120
1121 return err; 1121 return err;
1122 1122
1123 error_brightness: 1123 error_brightness:
1124 acer_led_exit(); 1124 acer_led_exit();
1125 error_mailled: 1125 error_mailled:
1126 return err; 1126 return err;
1127 } 1127 }
1128 1128
1129 static int acer_platform_remove(struct platform_device *device) 1129 static int acer_platform_remove(struct platform_device *device)
1130 { 1130 {
1131 if (has_cap(ACER_CAP_MAILLED)) 1131 if (has_cap(ACER_CAP_MAILLED))
1132 acer_led_exit(); 1132 acer_led_exit();
1133 if (has_cap(ACER_CAP_BRIGHTNESS)) 1133 if (has_cap(ACER_CAP_BRIGHTNESS))
1134 acer_backlight_exit(); 1134 acer_backlight_exit();
1135 1135
1136 acer_rfkill_exit(); 1136 acer_rfkill_exit();
1137 return 0; 1137 return 0;
1138 } 1138 }
1139 1139
1140 static int acer_platform_suspend(struct platform_device *dev, 1140 static int acer_platform_suspend(struct platform_device *dev,
1141 pm_message_t state) 1141 pm_message_t state)
1142 { 1142 {
1143 u32 value; 1143 u32 value;
1144 struct acer_data *data = &interface->data; 1144 struct acer_data *data = &interface->data;
1145 1145
1146 if (!data) 1146 if (!data)
1147 return -ENOMEM; 1147 return -ENOMEM;
1148 1148
1149 if (has_cap(ACER_CAP_MAILLED)) { 1149 if (has_cap(ACER_CAP_MAILLED)) {
1150 get_u32(&value, ACER_CAP_MAILLED); 1150 get_u32(&value, ACER_CAP_MAILLED);
1151 data->mailled = value; 1151 data->mailled = value;
1152 } 1152 }
1153 1153
1154 if (has_cap(ACER_CAP_BRIGHTNESS)) { 1154 if (has_cap(ACER_CAP_BRIGHTNESS)) {
1155 get_u32(&value, ACER_CAP_BRIGHTNESS); 1155 get_u32(&value, ACER_CAP_BRIGHTNESS);
1156 data->brightness = value; 1156 data->brightness = value;
1157 } 1157 }
1158 1158
1159 return 0; 1159 return 0;
1160 } 1160 }
1161 1161
1162 static int acer_platform_resume(struct platform_device *device) 1162 static int acer_platform_resume(struct platform_device *device)
1163 { 1163 {
1164 struct acer_data *data = &interface->data; 1164 struct acer_data *data = &interface->data;
1165 1165
1166 if (!data) 1166 if (!data)
1167 return -ENOMEM; 1167 return -ENOMEM;
1168 1168
1169 if (has_cap(ACER_CAP_MAILLED)) 1169 if (has_cap(ACER_CAP_MAILLED))
1170 set_u32(data->mailled, ACER_CAP_MAILLED); 1170 set_u32(data->mailled, ACER_CAP_MAILLED);
1171 1171
1172 if (has_cap(ACER_CAP_BRIGHTNESS)) 1172 if (has_cap(ACER_CAP_BRIGHTNESS))
1173 set_u32(data->brightness, ACER_CAP_BRIGHTNESS); 1173 set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
1174 1174
1175 return 0; 1175 return 0;
1176 } 1176 }
1177 1177
1178 static struct platform_driver acer_platform_driver = { 1178 static struct platform_driver acer_platform_driver = {
1179 .driver = { 1179 .driver = {
1180 .name = "acer-wmi", 1180 .name = "acer-wmi",
1181 .owner = THIS_MODULE, 1181 .owner = THIS_MODULE,
1182 }, 1182 },
1183 .probe = acer_platform_probe, 1183 .probe = acer_platform_probe,
1184 .remove = acer_platform_remove, 1184 .remove = acer_platform_remove,
1185 .suspend = acer_platform_suspend, 1185 .suspend = acer_platform_suspend,
1186 .resume = acer_platform_resume, 1186 .resume = acer_platform_resume,
1187 }; 1187 };
1188 1188
1189 static struct platform_device *acer_platform_device; 1189 static struct platform_device *acer_platform_device;
1190 1190
1191 static int remove_sysfs(struct platform_device *device) 1191 static int remove_sysfs(struct platform_device *device)
1192 { 1192 {
1193 if (has_cap(ACER_CAP_THREEG)) 1193 if (has_cap(ACER_CAP_THREEG))
1194 device_remove_file(&device->dev, &dev_attr_threeg); 1194 device_remove_file(&device->dev, &dev_attr_threeg);
1195 1195
1196 device_remove_file(&device->dev, &dev_attr_interface); 1196 device_remove_file(&device->dev, &dev_attr_interface);
1197 1197
1198 return 0; 1198 return 0;
1199 } 1199 }
1200 1200
1201 static int create_sysfs(void) 1201 static int create_sysfs(void)
1202 { 1202 {
1203 int retval = -ENOMEM; 1203 int retval = -ENOMEM;
1204 1204
1205 if (has_cap(ACER_CAP_THREEG)) { 1205 if (has_cap(ACER_CAP_THREEG)) {
1206 retval = device_create_file(&acer_platform_device->dev, 1206 retval = device_create_file(&acer_platform_device->dev,
1207 &dev_attr_threeg); 1207 &dev_attr_threeg);
1208 if (retval) 1208 if (retval)
1209 goto error_sysfs; 1209 goto error_sysfs;
1210 } 1210 }
1211 1211
1212 retval = device_create_file(&acer_platform_device->dev, 1212 retval = device_create_file(&acer_platform_device->dev,
1213 &dev_attr_interface); 1213 &dev_attr_interface);
1214 if (retval) 1214 if (retval)
1215 goto error_sysfs; 1215 goto error_sysfs;
1216 1216
1217 return 0; 1217 return 0;
1218 1218
1219 error_sysfs: 1219 error_sysfs:
1220 remove_sysfs(acer_platform_device); 1220 remove_sysfs(acer_platform_device);
1221 return retval; 1221 return retval;
1222 } 1222 }
1223 1223
1224 static void remove_debugfs(void) 1224 static void remove_debugfs(void)
1225 { 1225 {
1226 debugfs_remove(interface->debug.devices); 1226 debugfs_remove(interface->debug.devices);
1227 debugfs_remove(interface->debug.root); 1227 debugfs_remove(interface->debug.root);
1228 } 1228 }
1229 1229
1230 static int create_debugfs(void) 1230 static int create_debugfs(void)
1231 { 1231 {
1232 interface->debug.root = debugfs_create_dir("acer-wmi", NULL); 1232 interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
1233 if (!interface->debug.root) { 1233 if (!interface->debug.root) {
1234 printk(ACER_ERR "Failed to create debugfs directory"); 1234 printk(ACER_ERR "Failed to create debugfs directory");
1235 return -ENOMEM; 1235 return -ENOMEM;
1236 } 1236 }
1237 1237
1238 interface->debug.devices = debugfs_create_u32("devices", S_IRUGO, 1238 interface->debug.devices = debugfs_create_u32("devices", S_IRUGO,
1239 interface->debug.root, 1239 interface->debug.root,
1240 &interface->debug.wmid_devices); 1240 &interface->debug.wmid_devices);
1241 if (!interface->debug.devices) 1241 if (!interface->debug.devices)
1242 goto error_debugfs; 1242 goto error_debugfs;
1243 1243
1244 return 0; 1244 return 0;
1245 1245
1246 error_debugfs: 1246 error_debugfs:
1247 remove_debugfs(); 1247 remove_debugfs();
1248 return -ENOMEM; 1248 return -ENOMEM;
1249 } 1249 }
1250 1250
1251 static int __init acer_wmi_init(void) 1251 static int __init acer_wmi_init(void)
1252 { 1252 {
1253 int err; 1253 int err;
1254 1254
1255 printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n"); 1255 printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
1256 1256
1257 find_quirks(); 1257 find_quirks();
1258 1258
1259 /* 1259 /*
1260 * Detect which ACPI-WMI interface we're using. 1260 * Detect which ACPI-WMI interface we're using.
1261 */ 1261 */
1262 if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 1262 if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
1263 interface = &AMW0_V2_interface; 1263 interface = &AMW0_V2_interface;
1264 1264
1265 if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 1265 if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
1266 interface = &wmid_interface; 1266 interface = &wmid_interface;
1267 1267
1268 if (wmi_has_guid(WMID_GUID2) && interface) { 1268 if (wmi_has_guid(WMID_GUID2) && interface) {
1269 if (ACPI_FAILURE(WMID_set_capabilities())) { 1269 if (ACPI_FAILURE(WMID_set_capabilities())) {
1270 printk(ACER_ERR "Unable to detect available WMID " 1270 printk(ACER_ERR "Unable to detect available WMID "
1271 "devices\n"); 1271 "devices\n");
1272 return -ENODEV; 1272 return -ENODEV;
1273 } 1273 }
1274 } else if (!wmi_has_guid(WMID_GUID2) && interface) { 1274 } else if (!wmi_has_guid(WMID_GUID2) && interface) {
1275 printk(ACER_ERR "No WMID device detection method found\n"); 1275 printk(ACER_ERR "No WMID device detection method found\n");
1276 return -ENODEV; 1276 return -ENODEV;
1277 } 1277 }
1278 1278
1279 if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) { 1279 if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) {
1280 interface = &AMW0_interface; 1280 interface = &AMW0_interface;
1281 1281
1282 if (ACPI_FAILURE(AMW0_set_capabilities())) { 1282 if (ACPI_FAILURE(AMW0_set_capabilities())) {
1283 printk(ACER_ERR "Unable to detect available AMW0 " 1283 printk(ACER_ERR "Unable to detect available AMW0 "
1284 "devices\n"); 1284 "devices\n");
1285 return -ENODEV; 1285 return -ENODEV;
1286 } 1286 }
1287 } 1287 }
1288 1288
1289 if (wmi_has_guid(AMW0_GUID1)) 1289 if (wmi_has_guid(AMW0_GUID1))
1290 AMW0_find_mailled(); 1290 AMW0_find_mailled();
1291 1291
1292 if (!interface) { 1292 if (!interface) {
1293 printk(ACER_ERR "No or unsupported WMI interface, unable to " 1293 printk(ACER_ERR "No or unsupported WMI interface, unable to "
1294 "load\n"); 1294 "load\n");
1295 return -ENODEV; 1295 return -ENODEV;
1296 } 1296 }
1297 1297
1298 set_quirks(); 1298 set_quirks();
1299 1299
1300 if (!acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) {
1301 interface->capability &= ~ACER_CAP_BRIGHTNESS;
1302 printk(ACER_INFO "Brightness must be controlled by "
1303 "generic video driver\n");
1304 }
1305
1300 if (platform_driver_register(&acer_platform_driver)) { 1306 if (platform_driver_register(&acer_platform_driver)) {
1301 printk(ACER_ERR "Unable to register platform driver.\n"); 1307 printk(ACER_ERR "Unable to register platform driver.\n");
1302 goto error_platform_register; 1308 goto error_platform_register;
1303 } 1309 }
1304 acer_platform_device = platform_device_alloc("acer-wmi", -1); 1310 acer_platform_device = platform_device_alloc("acer-wmi", -1);
1305 platform_device_add(acer_platform_device); 1311 platform_device_add(acer_platform_device);
1306 1312
1307 err = create_sysfs(); 1313 err = create_sysfs();
1308 if (err) 1314 if (err)
1309 return err; 1315 return err;
1310 1316
1311 if (wmi_has_guid(WMID_GUID2)) { 1317 if (wmi_has_guid(WMID_GUID2)) {
1312 interface->debug.wmid_devices = get_wmid_devices(); 1318 interface->debug.wmid_devices = get_wmid_devices();
1313 err = create_debugfs(); 1319 err = create_debugfs();
1314 if (err) 1320 if (err)
1315 return err; 1321 return err;
1316 } 1322 }
1317 1323
1318 /* Override any initial settings with values from the commandline */ 1324 /* Override any initial settings with values from the commandline */
1319 acer_commandline_init(); 1325 acer_commandline_init();
1320 1326
1321 return 0; 1327 return 0;
1322 1328
1323 error_platform_register: 1329 error_platform_register:
1324 return -ENODEV; 1330 return -ENODEV;
1325 } 1331 }
1326 1332
1327 static void __exit acer_wmi_exit(void) 1333 static void __exit acer_wmi_exit(void)
1328 { 1334 {
1329 remove_sysfs(acer_platform_device); 1335 remove_sysfs(acer_platform_device);
1330 remove_debugfs(); 1336 remove_debugfs();
1331 platform_device_del(acer_platform_device); 1337 platform_device_del(acer_platform_device);
1332 platform_driver_unregister(&acer_platform_driver); 1338 platform_driver_unregister(&acer_platform_driver);
1333 1339
1334 printk(ACER_INFO "Acer Laptop WMI Extras unloaded\n"); 1340 printk(ACER_INFO "Acer Laptop WMI Extras unloaded\n");
1335 return; 1341 return;
1336 } 1342 }
1337 1343
1338 module_init(acer_wmi_init); 1344 module_init(acer_wmi_init);
1339 module_exit(acer_wmi_exit); 1345 module_exit(acer_wmi_exit);
1340 1346
drivers/misc/asus-laptop.c
1 /* 1 /*
2 * asus-laptop.c - Asus Laptop Support 2 * asus-laptop.c - Asus Laptop Support
3 * 3 *
4 * 4 *
5 * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor 5 * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
6 * Copyright (C) 2006-2007 Corentin Chary 6 * Copyright (C) 2006-2007 Corentin Chary
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * 21 *
22 * 22 *
23 * The development page for this driver is located at 23 * The development page for this driver is located at
24 * http://sourceforge.net/projects/acpi4asus/ 24 * http://sourceforge.net/projects/acpi4asus/
25 * 25 *
26 * Credits: 26 * Credits:
27 * Pontus Fuchs - Helper functions, cleanup 27 * Pontus Fuchs - Helper functions, cleanup
28 * Johann Wiesner - Small compile fixes 28 * Johann Wiesner - Small compile fixes
29 * John Belmonte - ACPI code for Toshiba laptop was a good starting point. 29 * John Belmonte - ACPI code for Toshiba laptop was a good starting point.
30 * Eric Burghard - LED display support for W1N 30 * Eric Burghard - LED display support for W1N
31 * Josh Green - Light Sens support 31 * Josh Green - Light Sens support
32 * Thomas Tuttle - His first patch for led support was very helpfull 32 * Thomas Tuttle - His first patch for led support was very helpfull
33 * Sam Lin - GPS support 33 * Sam Lin - GPS support
34 */ 34 */
35 35
36 #include <linux/kernel.h> 36 #include <linux/kernel.h>
37 #include <linux/module.h> 37 #include <linux/module.h>
38 #include <linux/init.h> 38 #include <linux/init.h>
39 #include <linux/types.h> 39 #include <linux/types.h>
40 #include <linux/err.h> 40 #include <linux/err.h>
41 #include <linux/proc_fs.h> 41 #include <linux/proc_fs.h>
42 #include <linux/backlight.h> 42 #include <linux/backlight.h>
43 #include <linux/fb.h> 43 #include <linux/fb.h>
44 #include <linux/leds.h> 44 #include <linux/leds.h>
45 #include <linux/platform_device.h> 45 #include <linux/platform_device.h>
46 #include <acpi/acpi_drivers.h> 46 #include <acpi/acpi_drivers.h>
47 #include <acpi/acpi_bus.h> 47 #include <acpi/acpi_bus.h>
48 #include <asm/uaccess.h> 48 #include <asm/uaccess.h>
49 49
50 #define ASUS_LAPTOP_VERSION "0.42" 50 #define ASUS_LAPTOP_VERSION "0.42"
51 51
52 #define ASUS_HOTK_NAME "Asus Laptop Support" 52 #define ASUS_HOTK_NAME "Asus Laptop Support"
53 #define ASUS_HOTK_CLASS "hotkey" 53 #define ASUS_HOTK_CLASS "hotkey"
54 #define ASUS_HOTK_DEVICE_NAME "Hotkey" 54 #define ASUS_HOTK_DEVICE_NAME "Hotkey"
55 #define ASUS_HOTK_FILE "asus-laptop" 55 #define ASUS_HOTK_FILE "asus-laptop"
56 #define ASUS_HOTK_PREFIX "\\_SB.ATKD." 56 #define ASUS_HOTK_PREFIX "\\_SB.ATKD."
57 57
58 /* 58 /*
59 * Some events we use, same for all Asus 59 * Some events we use, same for all Asus
60 */ 60 */
61 #define ATKD_BR_UP 0x10 61 #define ATKD_BR_UP 0x10
62 #define ATKD_BR_DOWN 0x20 62 #define ATKD_BR_DOWN 0x20
63 #define ATKD_LCD_ON 0x33 63 #define ATKD_LCD_ON 0x33
64 #define ATKD_LCD_OFF 0x34 64 #define ATKD_LCD_OFF 0x34
65 65
66 /* 66 /*
67 * Known bits returned by \_SB.ATKD.HWRS 67 * Known bits returned by \_SB.ATKD.HWRS
68 */ 68 */
69 #define WL_HWRS 0x80 69 #define WL_HWRS 0x80
70 #define BT_HWRS 0x100 70 #define BT_HWRS 0x100
71 71
72 /* 72 /*
73 * Flags for hotk status 73 * Flags for hotk status
74 * WL_ON and BT_ON are also used for wireless_status() 74 * WL_ON and BT_ON are also used for wireless_status()
75 */ 75 */
76 #define WL_ON 0x01 //internal Wifi 76 #define WL_ON 0x01 //internal Wifi
77 #define BT_ON 0x02 //internal Bluetooth 77 #define BT_ON 0x02 //internal Bluetooth
78 #define MLED_ON 0x04 //mail LED 78 #define MLED_ON 0x04 //mail LED
79 #define TLED_ON 0x08 //touchpad LED 79 #define TLED_ON 0x08 //touchpad LED
80 #define RLED_ON 0x10 //Record LED 80 #define RLED_ON 0x10 //Record LED
81 #define PLED_ON 0x20 //Phone LED 81 #define PLED_ON 0x20 //Phone LED
82 #define GLED_ON 0x40 //Gaming LED 82 #define GLED_ON 0x40 //Gaming LED
83 #define LCD_ON 0x80 //LCD backlight 83 #define LCD_ON 0x80 //LCD backlight
84 #define GPS_ON 0x100 //GPS 84 #define GPS_ON 0x100 //GPS
85 85
86 #define ASUS_LOG ASUS_HOTK_FILE ": " 86 #define ASUS_LOG ASUS_HOTK_FILE ": "
87 #define ASUS_ERR KERN_ERR ASUS_LOG 87 #define ASUS_ERR KERN_ERR ASUS_LOG
88 #define ASUS_WARNING KERN_WARNING ASUS_LOG 88 #define ASUS_WARNING KERN_WARNING ASUS_LOG
89 #define ASUS_NOTICE KERN_NOTICE ASUS_LOG 89 #define ASUS_NOTICE KERN_NOTICE ASUS_LOG
90 #define ASUS_INFO KERN_INFO ASUS_LOG 90 #define ASUS_INFO KERN_INFO ASUS_LOG
91 #define ASUS_DEBUG KERN_DEBUG ASUS_LOG 91 #define ASUS_DEBUG KERN_DEBUG ASUS_LOG
92 92
93 MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary"); 93 MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary");
94 MODULE_DESCRIPTION(ASUS_HOTK_NAME); 94 MODULE_DESCRIPTION(ASUS_HOTK_NAME);
95 MODULE_LICENSE("GPL"); 95 MODULE_LICENSE("GPL");
96 96
97 /* WAPF defines the behavior of the Fn+Fx wlan key 97 /* WAPF defines the behavior of the Fn+Fx wlan key
98 * The significance of values is yet to be found, but 98 * The significance of values is yet to be found, but
99 * most of the time: 99 * most of the time:
100 * 0x0 will do nothing 100 * 0x0 will do nothing
101 * 0x1 will allow to control the device with Fn+Fx key. 101 * 0x1 will allow to control the device with Fn+Fx key.
102 * 0x4 will send an ACPI event (0x88) while pressing the Fn+Fx key 102 * 0x4 will send an ACPI event (0x88) while pressing the Fn+Fx key
103 * 0x5 like 0x1 or 0x4 103 * 0x5 like 0x1 or 0x4
104 * So, if something doesn't work as you want, just try other values =) 104 * So, if something doesn't work as you want, just try other values =)
105 */ 105 */
106 static uint wapf = 1; 106 static uint wapf = 1;
107 module_param(wapf, uint, 0644); 107 module_param(wapf, uint, 0644);
108 MODULE_PARM_DESC(wapf, "WAPF value"); 108 MODULE_PARM_DESC(wapf, "WAPF value");
109 109
110 #define ASUS_HANDLE(object, paths...) \ 110 #define ASUS_HANDLE(object, paths...) \
111 static acpi_handle object##_handle = NULL; \ 111 static acpi_handle object##_handle = NULL; \
112 static char *object##_paths[] = { paths } 112 static char *object##_paths[] = { paths }
113 113
114 /* LED */ 114 /* LED */
115 ASUS_HANDLE(mled_set, ASUS_HOTK_PREFIX "MLED"); 115 ASUS_HANDLE(mled_set, ASUS_HOTK_PREFIX "MLED");
116 ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED"); 116 ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED");
117 ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED"); /* W1JC */ 117 ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED"); /* W1JC */
118 ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED"); /* A7J */ 118 ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED"); /* A7J */
119 ASUS_HANDLE(gled_set, ASUS_HOTK_PREFIX "GLED"); /* G1, G2 (probably) */ 119 ASUS_HANDLE(gled_set, ASUS_HOTK_PREFIX "GLED"); /* G1, G2 (probably) */
120 120
121 /* LEDD */ 121 /* LEDD */
122 ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM"); 122 ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM");
123 123
124 /* Bluetooth and WLAN 124 /* Bluetooth and WLAN
125 * WLED and BLED are not handled like other XLED, because in some dsdt 125 * WLED and BLED are not handled like other XLED, because in some dsdt
126 * they also control the WLAN/Bluetooth device. 126 * they also control the WLAN/Bluetooth device.
127 */ 127 */
128 ASUS_HANDLE(wl_switch, ASUS_HOTK_PREFIX "WLED"); 128 ASUS_HANDLE(wl_switch, ASUS_HOTK_PREFIX "WLED");
129 ASUS_HANDLE(bt_switch, ASUS_HOTK_PREFIX "BLED"); 129 ASUS_HANDLE(bt_switch, ASUS_HOTK_PREFIX "BLED");
130 ASUS_HANDLE(wireless_status, ASUS_HOTK_PREFIX "RSTS"); /* All new models */ 130 ASUS_HANDLE(wireless_status, ASUS_HOTK_PREFIX "RSTS"); /* All new models */
131 131
132 /* Brightness */ 132 /* Brightness */
133 ASUS_HANDLE(brightness_set, ASUS_HOTK_PREFIX "SPLV"); 133 ASUS_HANDLE(brightness_set, ASUS_HOTK_PREFIX "SPLV");
134 ASUS_HANDLE(brightness_get, ASUS_HOTK_PREFIX "GPLV"); 134 ASUS_HANDLE(brightness_get, ASUS_HOTK_PREFIX "GPLV");
135 135
136 /* Backlight */ 136 /* Backlight */
137 ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ 137 ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */
138 "\\_SB.PCI0.ISA.EC0._Q10", /* A1x */ 138 "\\_SB.PCI0.ISA.EC0._Q10", /* A1x */
139 "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */ 139 "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */
140 "\\_SB.PCI0.PX40.EC0.Q10", /* M1A */ 140 "\\_SB.PCI0.PX40.EC0.Q10", /* M1A */
141 "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */ 141 "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */
142 "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */ 142 "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */
143 "\\_SB.PCI0.PX40.Q10", /* S1x */ 143 "\\_SB.PCI0.PX40.Q10", /* S1x */
144 "\\Q10"); /* A2x, L2D, L3D, M2E */ 144 "\\Q10"); /* A2x, L2D, L3D, M2E */
145 145
146 /* Display */ 146 /* Display */
147 ASUS_HANDLE(display_set, ASUS_HOTK_PREFIX "SDSP"); 147 ASUS_HANDLE(display_set, ASUS_HOTK_PREFIX "SDSP");
148 ASUS_HANDLE(display_get, "\\_SB.PCI0.P0P1.VGA.GETD", /* A6B, A6K A6R A7D F3JM L4R M6R A3G 148 ASUS_HANDLE(display_get, "\\_SB.PCI0.P0P1.VGA.GETD", /* A6B, A6K A6R A7D F3JM L4R M6R A3G
149 M6A M6V VX-1 V6J V6V W3Z */ 149 M6A M6V VX-1 V6J V6V W3Z */
150 "\\_SB.PCI0.P0P2.VGA.GETD", /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V 150 "\\_SB.PCI0.P0P2.VGA.GETD", /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V
151 S5A M5A z33A W1Jc W2V G1 */ 151 S5A M5A z33A W1Jc W2V G1 */
152 "\\_SB.PCI0.P0P3.VGA.GETD", /* A6V A6Q */ 152 "\\_SB.PCI0.P0P3.VGA.GETD", /* A6V A6Q */
153 "\\_SB.PCI0.P0PA.VGA.GETD", /* A6T, A6M */ 153 "\\_SB.PCI0.P0PA.VGA.GETD", /* A6T, A6M */
154 "\\_SB.PCI0.PCI1.VGAC.NMAP", /* L3C */ 154 "\\_SB.PCI0.PCI1.VGAC.NMAP", /* L3C */
155 "\\_SB.PCI0.VGA.GETD", /* Z96F */ 155 "\\_SB.PCI0.VGA.GETD", /* Z96F */
156 "\\ACTD", /* A2D */ 156 "\\ACTD", /* A2D */
157 "\\ADVG", /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */ 157 "\\ADVG", /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */
158 "\\DNXT", /* P30 */ 158 "\\DNXT", /* P30 */
159 "\\INFB", /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */ 159 "\\INFB", /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */
160 "\\SSTE"); /* A3F A6F A3N A3L M6N W3N W6A */ 160 "\\SSTE"); /* A3F A6F A3N A3L M6N W3N W6A */
161 161
162 ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */ 162 ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */
163 ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL"); /* Z71A Z71V */ 163 ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL"); /* Z71A Z71V */
164 164
165 /* GPS */ 165 /* GPS */
166 /* R2H use different handle for GPS on/off */ 166 /* R2H use different handle for GPS on/off */
167 ASUS_HANDLE(gps_on, ASUS_HOTK_PREFIX "SDON"); /* R2H */ 167 ASUS_HANDLE(gps_on, ASUS_HOTK_PREFIX "SDON"); /* R2H */
168 ASUS_HANDLE(gps_off, ASUS_HOTK_PREFIX "SDOF"); /* R2H */ 168 ASUS_HANDLE(gps_off, ASUS_HOTK_PREFIX "SDOF"); /* R2H */
169 ASUS_HANDLE(gps_status, ASUS_HOTK_PREFIX "GPST"); 169 ASUS_HANDLE(gps_status, ASUS_HOTK_PREFIX "GPST");
170 170
171 /* 171 /*
172 * This is the main structure, we can use it to store anything interesting 172 * This is the main structure, we can use it to store anything interesting
173 * about the hotk device 173 * about the hotk device
174 */ 174 */
175 struct asus_hotk { 175 struct asus_hotk {
176 char *name; //laptop name 176 char *name; //laptop name
177 struct acpi_device *device; //the device we are in 177 struct acpi_device *device; //the device we are in
178 acpi_handle handle; //the handle of the hotk device 178 acpi_handle handle; //the handle of the hotk device
179 char status; //status of the hotk, for LEDs, ... 179 char status; //status of the hotk, for LEDs, ...
180 u32 ledd_status; //status of the LED display 180 u32 ledd_status; //status of the LED display
181 u8 light_level; //light sensor level 181 u8 light_level; //light sensor level
182 u8 light_switch; //light sensor switch value 182 u8 light_switch; //light sensor switch value
183 u16 event_count[128]; //count for each event TODO make this better 183 u16 event_count[128]; //count for each event TODO make this better
184 }; 184 };
185 185
186 /* 186 /*
187 * This header is made available to allow proper configuration given model, 187 * This header is made available to allow proper configuration given model,
188 * revision number , ... this info cannot go in struct asus_hotk because it is 188 * revision number , ... this info cannot go in struct asus_hotk because it is
189 * available before the hotk 189 * available before the hotk
190 */ 190 */
191 static struct acpi_table_header *asus_info; 191 static struct acpi_table_header *asus_info;
192 192
193 /* The actual device the driver binds to */ 193 /* The actual device the driver binds to */
194 static struct asus_hotk *hotk; 194 static struct asus_hotk *hotk;
195 195
196 /* 196 /*
197 * The hotkey driver declaration 197 * The hotkey driver declaration
198 */ 198 */
199 static const struct acpi_device_id asus_device_ids[] = { 199 static const struct acpi_device_id asus_device_ids[] = {
200 {"ATK0100", 0}, 200 {"ATK0100", 0},
201 {"", 0}, 201 {"", 0},
202 }; 202 };
203 MODULE_DEVICE_TABLE(acpi, asus_device_ids); 203 MODULE_DEVICE_TABLE(acpi, asus_device_ids);
204 204
205 static int asus_hotk_add(struct acpi_device *device); 205 static int asus_hotk_add(struct acpi_device *device);
206 static int asus_hotk_remove(struct acpi_device *device, int type); 206 static int asus_hotk_remove(struct acpi_device *device, int type);
207 static struct acpi_driver asus_hotk_driver = { 207 static struct acpi_driver asus_hotk_driver = {
208 .name = ASUS_HOTK_NAME, 208 .name = ASUS_HOTK_NAME,
209 .class = ASUS_HOTK_CLASS, 209 .class = ASUS_HOTK_CLASS,
210 .ids = asus_device_ids, 210 .ids = asus_device_ids,
211 .ops = { 211 .ops = {
212 .add = asus_hotk_add, 212 .add = asus_hotk_add,
213 .remove = asus_hotk_remove, 213 .remove = asus_hotk_remove,
214 }, 214 },
215 }; 215 };
216 216
217 /* The backlight device /sys/class/backlight */ 217 /* The backlight device /sys/class/backlight */
218 static struct backlight_device *asus_backlight_device; 218 static struct backlight_device *asus_backlight_device;
219 219
220 /* 220 /*
221 * The backlight class declaration 221 * The backlight class declaration
222 */ 222 */
223 static int read_brightness(struct backlight_device *bd); 223 static int read_brightness(struct backlight_device *bd);
224 static int update_bl_status(struct backlight_device *bd); 224 static int update_bl_status(struct backlight_device *bd);
225 static struct backlight_ops asusbl_ops = { 225 static struct backlight_ops asusbl_ops = {
226 .get_brightness = read_brightness, 226 .get_brightness = read_brightness,
227 .update_status = update_bl_status, 227 .update_status = update_bl_status,
228 }; 228 };
229 229
230 /* These functions actually update the LED's, and are called from a 230 /* These functions actually update the LED's, and are called from a
231 * workqueue. By doing this as separate work rather than when the LED 231 * workqueue. By doing this as separate work rather than when the LED
232 * subsystem asks, we avoid messing with the Asus ACPI stuff during a 232 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
233 * potentially bad time, such as a timer interrupt. */ 233 * potentially bad time, such as a timer interrupt. */
234 static struct workqueue_struct *led_workqueue; 234 static struct workqueue_struct *led_workqueue;
235 235
236 #define ASUS_LED(object, ledname) \ 236 #define ASUS_LED(object, ledname) \
237 static void object##_led_set(struct led_classdev *led_cdev, \ 237 static void object##_led_set(struct led_classdev *led_cdev, \
238 enum led_brightness value); \ 238 enum led_brightness value); \
239 static void object##_led_update(struct work_struct *ignored); \ 239 static void object##_led_update(struct work_struct *ignored); \
240 static int object##_led_wk; \ 240 static int object##_led_wk; \
241 static DECLARE_WORK(object##_led_work, object##_led_update); \ 241 static DECLARE_WORK(object##_led_work, object##_led_update); \
242 static struct led_classdev object##_led = { \ 242 static struct led_classdev object##_led = { \
243 .name = "asus::" ledname, \ 243 .name = "asus::" ledname, \
244 .brightness_set = object##_led_set, \ 244 .brightness_set = object##_led_set, \
245 } 245 }
246 246
247 ASUS_LED(mled, "mail"); 247 ASUS_LED(mled, "mail");
248 ASUS_LED(tled, "touchpad"); 248 ASUS_LED(tled, "touchpad");
249 ASUS_LED(rled, "record"); 249 ASUS_LED(rled, "record");
250 ASUS_LED(pled, "phone"); 250 ASUS_LED(pled, "phone");
251 ASUS_LED(gled, "gaming"); 251 ASUS_LED(gled, "gaming");
252 252
253 /* 253 /*
254 * This function evaluates an ACPI method, given an int as parameter, the 254 * This function evaluates an ACPI method, given an int as parameter, the
255 * method is searched within the scope of the handle, can be NULL. The output 255 * method is searched within the scope of the handle, can be NULL. The output
256 * of the method is written is output, which can also be NULL 256 * of the method is written is output, which can also be NULL
257 * 257 *
258 * returns 0 if write is successful, -1 else. 258 * returns 0 if write is successful, -1 else.
259 */ 259 */
260 static int write_acpi_int(acpi_handle handle, const char *method, int val, 260 static int write_acpi_int(acpi_handle handle, const char *method, int val,
261 struct acpi_buffer *output) 261 struct acpi_buffer *output)
262 { 262 {
263 struct acpi_object_list params; //list of input parameters (an int here) 263 struct acpi_object_list params; //list of input parameters (an int here)
264 union acpi_object in_obj; //the only param we use 264 union acpi_object in_obj; //the only param we use
265 acpi_status status; 265 acpi_status status;
266 266
267 if (!handle) 267 if (!handle)
268 return 0; 268 return 0;
269 269
270 params.count = 1; 270 params.count = 1;
271 params.pointer = &in_obj; 271 params.pointer = &in_obj;
272 in_obj.type = ACPI_TYPE_INTEGER; 272 in_obj.type = ACPI_TYPE_INTEGER;
273 in_obj.integer.value = val; 273 in_obj.integer.value = val;
274 274
275 status = acpi_evaluate_object(handle, (char *)method, &params, output); 275 status = acpi_evaluate_object(handle, (char *)method, &params, output);
276 if (status == AE_OK) 276 if (status == AE_OK)
277 return 0; 277 return 0;
278 else 278 else
279 return -1; 279 return -1;
280 } 280 }
281 281
282 static int read_wireless_status(int mask) 282 static int read_wireless_status(int mask)
283 { 283 {
284 unsigned long long status; 284 unsigned long long status;
285 acpi_status rv = AE_OK; 285 acpi_status rv = AE_OK;
286 286
287 if (!wireless_status_handle) 287 if (!wireless_status_handle)
288 return (hotk->status & mask) ? 1 : 0; 288 return (hotk->status & mask) ? 1 : 0;
289 289
290 rv = acpi_evaluate_integer(wireless_status_handle, NULL, NULL, &status); 290 rv = acpi_evaluate_integer(wireless_status_handle, NULL, NULL, &status);
291 if (ACPI_FAILURE(rv)) 291 if (ACPI_FAILURE(rv))
292 printk(ASUS_WARNING "Error reading Wireless status\n"); 292 printk(ASUS_WARNING "Error reading Wireless status\n");
293 else 293 else
294 return (status & mask) ? 1 : 0; 294 return (status & mask) ? 1 : 0;
295 295
296 return (hotk->status & mask) ? 1 : 0; 296 return (hotk->status & mask) ? 1 : 0;
297 } 297 }
298 298
299 static int read_gps_status(void) 299 static int read_gps_status(void)
300 { 300 {
301 unsigned long long status; 301 unsigned long long status;
302 acpi_status rv = AE_OK; 302 acpi_status rv = AE_OK;
303 303
304 rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status); 304 rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status);
305 if (ACPI_FAILURE(rv)) 305 if (ACPI_FAILURE(rv))
306 printk(ASUS_WARNING "Error reading GPS status\n"); 306 printk(ASUS_WARNING "Error reading GPS status\n");
307 else 307 else
308 return status ? 1 : 0; 308 return status ? 1 : 0;
309 309
310 return (hotk->status & GPS_ON) ? 1 : 0; 310 return (hotk->status & GPS_ON) ? 1 : 0;
311 } 311 }
312 312
313 /* Generic LED functions */ 313 /* Generic LED functions */
314 static int read_status(int mask) 314 static int read_status(int mask)
315 { 315 {
316 /* There is a special method for both wireless devices */ 316 /* There is a special method for both wireless devices */
317 if (mask == BT_ON || mask == WL_ON) 317 if (mask == BT_ON || mask == WL_ON)
318 return read_wireless_status(mask); 318 return read_wireless_status(mask);
319 else if (mask == GPS_ON) 319 else if (mask == GPS_ON)
320 return read_gps_status(); 320 return read_gps_status();
321 321
322 return (hotk->status & mask) ? 1 : 0; 322 return (hotk->status & mask) ? 1 : 0;
323 } 323 }
324 324
325 static void write_status(acpi_handle handle, int out, int mask) 325 static void write_status(acpi_handle handle, int out, int mask)
326 { 326 {
327 hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask); 327 hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask);
328 328
329 switch (mask) { 329 switch (mask) {
330 case MLED_ON: 330 case MLED_ON:
331 out = !(out & 0x1); 331 out = !(out & 0x1);
332 break; 332 break;
333 case GLED_ON: 333 case GLED_ON:
334 out = (out & 0x1) + 1; 334 out = (out & 0x1) + 1;
335 break; 335 break;
336 case GPS_ON: 336 case GPS_ON:
337 handle = (out) ? gps_on_handle : gps_off_handle; 337 handle = (out) ? gps_on_handle : gps_off_handle;
338 out = 0x02; 338 out = 0x02;
339 break; 339 break;
340 default: 340 default:
341 out &= 0x1; 341 out &= 0x1;
342 break; 342 break;
343 } 343 }
344 344
345 if (write_acpi_int(handle, NULL, out, NULL)) 345 if (write_acpi_int(handle, NULL, out, NULL))
346 printk(ASUS_WARNING " write failed %x\n", mask); 346 printk(ASUS_WARNING " write failed %x\n", mask);
347 } 347 }
348 348
349 /* /sys/class/led handlers */ 349 /* /sys/class/led handlers */
350 #define ASUS_LED_HANDLER(object, mask) \ 350 #define ASUS_LED_HANDLER(object, mask) \
351 static void object##_led_set(struct led_classdev *led_cdev, \ 351 static void object##_led_set(struct led_classdev *led_cdev, \
352 enum led_brightness value) \ 352 enum led_brightness value) \
353 { \ 353 { \
354 object##_led_wk = (value > 0) ? 1 : 0; \ 354 object##_led_wk = (value > 0) ? 1 : 0; \
355 queue_work(led_workqueue, &object##_led_work); \ 355 queue_work(led_workqueue, &object##_led_work); \
356 } \ 356 } \
357 static void object##_led_update(struct work_struct *ignored) \ 357 static void object##_led_update(struct work_struct *ignored) \
358 { \ 358 { \
359 int value = object##_led_wk; \ 359 int value = object##_led_wk; \
360 write_status(object##_set_handle, value, (mask)); \ 360 write_status(object##_set_handle, value, (mask)); \
361 } 361 }
362 362
363 ASUS_LED_HANDLER(mled, MLED_ON); 363 ASUS_LED_HANDLER(mled, MLED_ON);
364 ASUS_LED_HANDLER(pled, PLED_ON); 364 ASUS_LED_HANDLER(pled, PLED_ON);
365 ASUS_LED_HANDLER(rled, RLED_ON); 365 ASUS_LED_HANDLER(rled, RLED_ON);
366 ASUS_LED_HANDLER(tled, TLED_ON); 366 ASUS_LED_HANDLER(tled, TLED_ON);
367 ASUS_LED_HANDLER(gled, GLED_ON); 367 ASUS_LED_HANDLER(gled, GLED_ON);
368 368
369 static int get_lcd_state(void) 369 static int get_lcd_state(void)
370 { 370 {
371 return read_status(LCD_ON); 371 return read_status(LCD_ON);
372 } 372 }
373 373
374 static int set_lcd_state(int value) 374 static int set_lcd_state(int value)
375 { 375 {
376 int lcd = 0; 376 int lcd = 0;
377 acpi_status status = 0; 377 acpi_status status = 0;
378 378
379 lcd = value ? 1 : 0; 379 lcd = value ? 1 : 0;
380 380
381 if (lcd == get_lcd_state()) 381 if (lcd == get_lcd_state())
382 return 0; 382 return 0;
383 383
384 if (lcd_switch_handle) { 384 if (lcd_switch_handle) {
385 status = acpi_evaluate_object(lcd_switch_handle, 385 status = acpi_evaluate_object(lcd_switch_handle,
386 NULL, NULL, NULL); 386 NULL, NULL, NULL);
387 387
388 if (ACPI_FAILURE(status)) 388 if (ACPI_FAILURE(status))
389 printk(ASUS_WARNING "Error switching LCD\n"); 389 printk(ASUS_WARNING "Error switching LCD\n");
390 } 390 }
391 391
392 write_status(NULL, lcd, LCD_ON); 392 write_status(NULL, lcd, LCD_ON);
393 return 0; 393 return 0;
394 } 394 }
395 395
396 static void lcd_blank(int blank) 396 static void lcd_blank(int blank)
397 { 397 {
398 struct backlight_device *bd = asus_backlight_device; 398 struct backlight_device *bd = asus_backlight_device;
399 399
400 if (bd) { 400 if (bd) {
401 bd->props.power = blank; 401 bd->props.power = blank;
402 backlight_update_status(bd); 402 backlight_update_status(bd);
403 } 403 }
404 } 404 }
405 405
406 static int read_brightness(struct backlight_device *bd) 406 static int read_brightness(struct backlight_device *bd)
407 { 407 {
408 unsigned long long value; 408 unsigned long long value;
409 acpi_status rv = AE_OK; 409 acpi_status rv = AE_OK;
410 410
411 rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value); 411 rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value);
412 if (ACPI_FAILURE(rv)) 412 if (ACPI_FAILURE(rv))
413 printk(ASUS_WARNING "Error reading brightness\n"); 413 printk(ASUS_WARNING "Error reading brightness\n");
414 414
415 return value; 415 return value;
416 } 416 }
417 417
418 static int set_brightness(struct backlight_device *bd, int value) 418 static int set_brightness(struct backlight_device *bd, int value)
419 { 419 {
420 int ret = 0; 420 int ret = 0;
421 421
422 value = (0 < value) ? ((15 < value) ? 15 : value) : 0; 422 value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
423 /* 0 <= value <= 15 */ 423 /* 0 <= value <= 15 */
424 424
425 if (write_acpi_int(brightness_set_handle, NULL, value, NULL)) { 425 if (write_acpi_int(brightness_set_handle, NULL, value, NULL)) {
426 printk(ASUS_WARNING "Error changing brightness\n"); 426 printk(ASUS_WARNING "Error changing brightness\n");
427 ret = -EIO; 427 ret = -EIO;
428 } 428 }
429 429
430 return ret; 430 return ret;
431 } 431 }
432 432
433 static int update_bl_status(struct backlight_device *bd) 433 static int update_bl_status(struct backlight_device *bd)
434 { 434 {
435 int rv; 435 int rv;
436 int value = bd->props.brightness; 436 int value = bd->props.brightness;
437 437
438 rv = set_brightness(bd, value); 438 rv = set_brightness(bd, value);
439 if (rv) 439 if (rv)
440 return rv; 440 return rv;
441 441
442 value = (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0; 442 value = (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0;
443 return set_lcd_state(value); 443 return set_lcd_state(value);
444 } 444 }
445 445
446 /* 446 /*
447 * Platform device handlers 447 * Platform device handlers
448 */ 448 */
449 449
450 /* 450 /*
451 * We write our info in page, we begin at offset off and cannot write more 451 * We write our info in page, we begin at offset off and cannot write more
452 * than count bytes. We set eof to 1 if we handle those 2 values. We return the 452 * than count bytes. We set eof to 1 if we handle those 2 values. We return the
453 * number of bytes written in page 453 * number of bytes written in page
454 */ 454 */
455 static ssize_t show_infos(struct device *dev, 455 static ssize_t show_infos(struct device *dev,
456 struct device_attribute *attr, char *page) 456 struct device_attribute *attr, char *page)
457 { 457 {
458 int len = 0; 458 int len = 0;
459 unsigned long long temp; 459 unsigned long long temp;
460 char buf[16]; //enough for all info 460 char buf[16]; //enough for all info
461 acpi_status rv = AE_OK; 461 acpi_status rv = AE_OK;
462 462
463 /* 463 /*
464 * We use the easy way, we don't care of off and count, so we don't set eof 464 * We use the easy way, we don't care of off and count, so we don't set eof
465 * to 1 465 * to 1
466 */ 466 */
467 467
468 len += sprintf(page, ASUS_HOTK_NAME " " ASUS_LAPTOP_VERSION "\n"); 468 len += sprintf(page, ASUS_HOTK_NAME " " ASUS_LAPTOP_VERSION "\n");
469 len += sprintf(page + len, "Model reference : %s\n", hotk->name); 469 len += sprintf(page + len, "Model reference : %s\n", hotk->name);
470 /* 470 /*
471 * The SFUN method probably allows the original driver to get the list 471 * The SFUN method probably allows the original driver to get the list
472 * of features supported by a given model. For now, 0x0100 or 0x0800 472 * of features supported by a given model. For now, 0x0100 or 0x0800
473 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card. 473 * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
474 * The significance of others is yet to be found. 474 * The significance of others is yet to be found.
475 */ 475 */
476 rv = acpi_evaluate_integer(hotk->handle, "SFUN", NULL, &temp); 476 rv = acpi_evaluate_integer(hotk->handle, "SFUN", NULL, &temp);
477 if (!ACPI_FAILURE(rv)) 477 if (!ACPI_FAILURE(rv))
478 len += sprintf(page + len, "SFUN value : 0x%04x\n", 478 len += sprintf(page + len, "SFUN value : 0x%04x\n",
479 (uint) temp); 479 (uint) temp);
480 /* 480 /*
481 * Another value for userspace: the ASYM method returns 0x02 for 481 * Another value for userspace: the ASYM method returns 0x02 for
482 * battery low and 0x04 for battery critical, its readings tend to be 482 * battery low and 0x04 for battery critical, its readings tend to be
483 * more accurate than those provided by _BST. 483 * more accurate than those provided by _BST.
484 * Note: since not all the laptops provide this method, errors are 484 * Note: since not all the laptops provide this method, errors are
485 * silently ignored. 485 * silently ignored.
486 */ 486 */
487 rv = acpi_evaluate_integer(hotk->handle, "ASYM", NULL, &temp); 487 rv = acpi_evaluate_integer(hotk->handle, "ASYM", NULL, &temp);
488 if (!ACPI_FAILURE(rv)) 488 if (!ACPI_FAILURE(rv))
489 len += sprintf(page + len, "ASYM value : 0x%04x\n", 489 len += sprintf(page + len, "ASYM value : 0x%04x\n",
490 (uint) temp); 490 (uint) temp);
491 if (asus_info) { 491 if (asus_info) {
492 snprintf(buf, 16, "%d", asus_info->length); 492 snprintf(buf, 16, "%d", asus_info->length);
493 len += sprintf(page + len, "DSDT length : %s\n", buf); 493 len += sprintf(page + len, "DSDT length : %s\n", buf);
494 snprintf(buf, 16, "%d", asus_info->checksum); 494 snprintf(buf, 16, "%d", asus_info->checksum);
495 len += sprintf(page + len, "DSDT checksum : %s\n", buf); 495 len += sprintf(page + len, "DSDT checksum : %s\n", buf);
496 snprintf(buf, 16, "%d", asus_info->revision); 496 snprintf(buf, 16, "%d", asus_info->revision);
497 len += sprintf(page + len, "DSDT revision : %s\n", buf); 497 len += sprintf(page + len, "DSDT revision : %s\n", buf);
498 snprintf(buf, 7, "%s", asus_info->oem_id); 498 snprintf(buf, 7, "%s", asus_info->oem_id);
499 len += sprintf(page + len, "OEM id : %s\n", buf); 499 len += sprintf(page + len, "OEM id : %s\n", buf);
500 snprintf(buf, 9, "%s", asus_info->oem_table_id); 500 snprintf(buf, 9, "%s", asus_info->oem_table_id);
501 len += sprintf(page + len, "OEM table id : %s\n", buf); 501 len += sprintf(page + len, "OEM table id : %s\n", buf);
502 snprintf(buf, 16, "%x", asus_info->oem_revision); 502 snprintf(buf, 16, "%x", asus_info->oem_revision);
503 len += sprintf(page + len, "OEM revision : 0x%s\n", buf); 503 len += sprintf(page + len, "OEM revision : 0x%s\n", buf);
504 snprintf(buf, 5, "%s", asus_info->asl_compiler_id); 504 snprintf(buf, 5, "%s", asus_info->asl_compiler_id);
505 len += sprintf(page + len, "ASL comp vendor id : %s\n", buf); 505 len += sprintf(page + len, "ASL comp vendor id : %s\n", buf);
506 snprintf(buf, 16, "%x", asus_info->asl_compiler_revision); 506 snprintf(buf, 16, "%x", asus_info->asl_compiler_revision);
507 len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf); 507 len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf);
508 } 508 }
509 509
510 return len; 510 return len;
511 } 511 }
512 512
513 static int parse_arg(const char *buf, unsigned long count, int *val) 513 static int parse_arg(const char *buf, unsigned long count, int *val)
514 { 514 {
515 if (!count) 515 if (!count)
516 return 0; 516 return 0;
517 if (count > 31) 517 if (count > 31)
518 return -EINVAL; 518 return -EINVAL;
519 if (sscanf(buf, "%i", val) != 1) 519 if (sscanf(buf, "%i", val) != 1)
520 return -EINVAL; 520 return -EINVAL;
521 return count; 521 return count;
522 } 522 }
523 523
524 static ssize_t store_status(const char *buf, size_t count, 524 static ssize_t store_status(const char *buf, size_t count,
525 acpi_handle handle, int mask) 525 acpi_handle handle, int mask)
526 { 526 {
527 int rv, value; 527 int rv, value;
528 int out = 0; 528 int out = 0;
529 529
530 rv = parse_arg(buf, count, &value); 530 rv = parse_arg(buf, count, &value);
531 if (rv > 0) 531 if (rv > 0)
532 out = value ? 1 : 0; 532 out = value ? 1 : 0;
533 533
534 write_status(handle, out, mask); 534 write_status(handle, out, mask);
535 535
536 return rv; 536 return rv;
537 } 537 }
538 538
539 /* 539 /*
540 * LEDD display 540 * LEDD display
541 */ 541 */
542 static ssize_t show_ledd(struct device *dev, 542 static ssize_t show_ledd(struct device *dev,
543 struct device_attribute *attr, char *buf) 543 struct device_attribute *attr, char *buf)
544 { 544 {
545 return sprintf(buf, "0x%08x\n", hotk->ledd_status); 545 return sprintf(buf, "0x%08x\n", hotk->ledd_status);
546 } 546 }
547 547
548 static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, 548 static ssize_t store_ledd(struct device *dev, struct device_attribute *attr,
549 const char *buf, size_t count) 549 const char *buf, size_t count)
550 { 550 {
551 int rv, value; 551 int rv, value;
552 552
553 rv = parse_arg(buf, count, &value); 553 rv = parse_arg(buf, count, &value);
554 if (rv > 0) { 554 if (rv > 0) {
555 if (write_acpi_int(ledd_set_handle, NULL, value, NULL)) 555 if (write_acpi_int(ledd_set_handle, NULL, value, NULL))
556 printk(ASUS_WARNING "LED display write failed\n"); 556 printk(ASUS_WARNING "LED display write failed\n");
557 else 557 else
558 hotk->ledd_status = (u32) value; 558 hotk->ledd_status = (u32) value;
559 } 559 }
560 return rv; 560 return rv;
561 } 561 }
562 562
563 /* 563 /*
564 * WLAN 564 * WLAN
565 */ 565 */
566 static ssize_t show_wlan(struct device *dev, 566 static ssize_t show_wlan(struct device *dev,
567 struct device_attribute *attr, char *buf) 567 struct device_attribute *attr, char *buf)
568 { 568 {
569 return sprintf(buf, "%d\n", read_status(WL_ON)); 569 return sprintf(buf, "%d\n", read_status(WL_ON));
570 } 570 }
571 571
572 static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, 572 static ssize_t store_wlan(struct device *dev, struct device_attribute *attr,
573 const char *buf, size_t count) 573 const char *buf, size_t count)
574 { 574 {
575 return store_status(buf, count, wl_switch_handle, WL_ON); 575 return store_status(buf, count, wl_switch_handle, WL_ON);
576 } 576 }
577 577
578 /* 578 /*
579 * Bluetooth 579 * Bluetooth
580 */ 580 */
581 static ssize_t show_bluetooth(struct device *dev, 581 static ssize_t show_bluetooth(struct device *dev,
582 struct device_attribute *attr, char *buf) 582 struct device_attribute *attr, char *buf)
583 { 583 {
584 return sprintf(buf, "%d\n", read_status(BT_ON)); 584 return sprintf(buf, "%d\n", read_status(BT_ON));
585 } 585 }
586 586
587 static ssize_t store_bluetooth(struct device *dev, 587 static ssize_t store_bluetooth(struct device *dev,
588 struct device_attribute *attr, const char *buf, 588 struct device_attribute *attr, const char *buf,
589 size_t count) 589 size_t count)
590 { 590 {
591 return store_status(buf, count, bt_switch_handle, BT_ON); 591 return store_status(buf, count, bt_switch_handle, BT_ON);
592 } 592 }
593 593
594 /* 594 /*
595 * Display 595 * Display
596 */ 596 */
597 static void set_display(int value) 597 static void set_display(int value)
598 { 598 {
599 /* no sanity check needed for now */ 599 /* no sanity check needed for now */
600 if (write_acpi_int(display_set_handle, NULL, value, NULL)) 600 if (write_acpi_int(display_set_handle, NULL, value, NULL))
601 printk(ASUS_WARNING "Error setting display\n"); 601 printk(ASUS_WARNING "Error setting display\n");
602 return; 602 return;
603 } 603 }
604 604
605 static int read_display(void) 605 static int read_display(void)
606 { 606 {
607 unsigned long long value = 0; 607 unsigned long long value = 0;
608 acpi_status rv = AE_OK; 608 acpi_status rv = AE_OK;
609 609
610 /* In most of the case, we know how to set the display, but sometime 610 /* In most of the case, we know how to set the display, but sometime
611 we can't read it */ 611 we can't read it */
612 if (display_get_handle) { 612 if (display_get_handle) {
613 rv = acpi_evaluate_integer(display_get_handle, NULL, 613 rv = acpi_evaluate_integer(display_get_handle, NULL,
614 NULL, &value); 614 NULL, &value);
615 if (ACPI_FAILURE(rv)) 615 if (ACPI_FAILURE(rv))
616 printk(ASUS_WARNING "Error reading display status\n"); 616 printk(ASUS_WARNING "Error reading display status\n");
617 } 617 }
618 618
619 value &= 0x0F; /* needed for some models, shouldn't hurt others */ 619 value &= 0x0F; /* needed for some models, shouldn't hurt others */
620 620
621 return value; 621 return value;
622 } 622 }
623 623
624 /* 624 /*
625 * Now, *this* one could be more user-friendly, but so far, no-one has 625 * Now, *this* one could be more user-friendly, but so far, no-one has
626 * complained. The significance of bits is the same as in store_disp() 626 * complained. The significance of bits is the same as in store_disp()
627 */ 627 */
628 static ssize_t show_disp(struct device *dev, 628 static ssize_t show_disp(struct device *dev,
629 struct device_attribute *attr, char *buf) 629 struct device_attribute *attr, char *buf)
630 { 630 {
631 return sprintf(buf, "%d\n", read_display()); 631 return sprintf(buf, "%d\n", read_display());
632 } 632 }
633 633
634 /* 634 /*
635 * Experimental support for display switching. As of now: 1 should activate 635 * Experimental support for display switching. As of now: 1 should activate
636 * the LCD output, 2 should do for CRT, 4 for TV-Out and 8 for DVI. 636 * the LCD output, 2 should do for CRT, 4 for TV-Out and 8 for DVI.
637 * Any combination (bitwise) of these will suffice. I never actually tested 4 637 * Any combination (bitwise) of these will suffice. I never actually tested 4
638 * displays hooked up simultaneously, so be warned. See the acpi4asus README 638 * displays hooked up simultaneously, so be warned. See the acpi4asus README
639 * for more info. 639 * for more info.
640 */ 640 */
641 static ssize_t store_disp(struct device *dev, struct device_attribute *attr, 641 static ssize_t store_disp(struct device *dev, struct device_attribute *attr,
642 const char *buf, size_t count) 642 const char *buf, size_t count)
643 { 643 {
644 int rv, value; 644 int rv, value;
645 645
646 rv = parse_arg(buf, count, &value); 646 rv = parse_arg(buf, count, &value);
647 if (rv > 0) 647 if (rv > 0)
648 set_display(value); 648 set_display(value);
649 return rv; 649 return rv;
650 } 650 }
651 651
652 /* 652 /*
653 * Light Sens 653 * Light Sens
654 */ 654 */
655 static void set_light_sens_switch(int value) 655 static void set_light_sens_switch(int value)
656 { 656 {
657 if (write_acpi_int(ls_switch_handle, NULL, value, NULL)) 657 if (write_acpi_int(ls_switch_handle, NULL, value, NULL))
658 printk(ASUS_WARNING "Error setting light sensor switch\n"); 658 printk(ASUS_WARNING "Error setting light sensor switch\n");
659 hotk->light_switch = value; 659 hotk->light_switch = value;
660 } 660 }
661 661
662 static ssize_t show_lssw(struct device *dev, 662 static ssize_t show_lssw(struct device *dev,
663 struct device_attribute *attr, char *buf) 663 struct device_attribute *attr, char *buf)
664 { 664 {
665 return sprintf(buf, "%d\n", hotk->light_switch); 665 return sprintf(buf, "%d\n", hotk->light_switch);
666 } 666 }
667 667
668 static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, 668 static ssize_t store_lssw(struct device *dev, struct device_attribute *attr,
669 const char *buf, size_t count) 669 const char *buf, size_t count)
670 { 670 {
671 int rv, value; 671 int rv, value;
672 672
673 rv = parse_arg(buf, count, &value); 673 rv = parse_arg(buf, count, &value);
674 if (rv > 0) 674 if (rv > 0)
675 set_light_sens_switch(value ? 1 : 0); 675 set_light_sens_switch(value ? 1 : 0);
676 676
677 return rv; 677 return rv;
678 } 678 }
679 679
680 static void set_light_sens_level(int value) 680 static void set_light_sens_level(int value)
681 { 681 {
682 if (write_acpi_int(ls_level_handle, NULL, value, NULL)) 682 if (write_acpi_int(ls_level_handle, NULL, value, NULL))
683 printk(ASUS_WARNING "Error setting light sensor level\n"); 683 printk(ASUS_WARNING "Error setting light sensor level\n");
684 hotk->light_level = value; 684 hotk->light_level = value;
685 } 685 }
686 686
687 static ssize_t show_lslvl(struct device *dev, 687 static ssize_t show_lslvl(struct device *dev,
688 struct device_attribute *attr, char *buf) 688 struct device_attribute *attr, char *buf)
689 { 689 {
690 return sprintf(buf, "%d\n", hotk->light_level); 690 return sprintf(buf, "%d\n", hotk->light_level);
691 } 691 }
692 692
693 static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr, 693 static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr,
694 const char *buf, size_t count) 694 const char *buf, size_t count)
695 { 695 {
696 int rv, value; 696 int rv, value;
697 697
698 rv = parse_arg(buf, count, &value); 698 rv = parse_arg(buf, count, &value);
699 if (rv > 0) { 699 if (rv > 0) {
700 value = (0 < value) ? ((15 < value) ? 15 : value) : 0; 700 value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
701 /* 0 <= value <= 15 */ 701 /* 0 <= value <= 15 */
702 set_light_sens_level(value); 702 set_light_sens_level(value);
703 } 703 }
704 704
705 return rv; 705 return rv;
706 } 706 }
707 707
708 /* 708 /*
709 * GPS 709 * GPS
710 */ 710 */
711 static ssize_t show_gps(struct device *dev, 711 static ssize_t show_gps(struct device *dev,
712 struct device_attribute *attr, char *buf) 712 struct device_attribute *attr, char *buf)
713 { 713 {
714 return sprintf(buf, "%d\n", read_status(GPS_ON)); 714 return sprintf(buf, "%d\n", read_status(GPS_ON));
715 } 715 }
716 716
717 static ssize_t store_gps(struct device *dev, struct device_attribute *attr, 717 static ssize_t store_gps(struct device *dev, struct device_attribute *attr,
718 const char *buf, size_t count) 718 const char *buf, size_t count)
719 { 719 {
720 return store_status(buf, count, NULL, GPS_ON); 720 return store_status(buf, count, NULL, GPS_ON);
721 } 721 }
722 722
723 static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) 723 static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
724 { 724 {
725 /* TODO Find a better way to handle events count. */ 725 /* TODO Find a better way to handle events count. */
726 if (!hotk) 726 if (!hotk)
727 return; 727 return;
728 728
729 /* 729 /*
730 * We need to tell the backlight device when the backlight power is 730 * We need to tell the backlight device when the backlight power is
731 * switched 731 * switched
732 */ 732 */
733 if (event == ATKD_LCD_ON) { 733 if (event == ATKD_LCD_ON) {
734 write_status(NULL, 1, LCD_ON); 734 write_status(NULL, 1, LCD_ON);
735 lcd_blank(FB_BLANK_UNBLANK); 735 lcd_blank(FB_BLANK_UNBLANK);
736 } else if (event == ATKD_LCD_OFF) { 736 } else if (event == ATKD_LCD_OFF) {
737 write_status(NULL, 0, LCD_ON); 737 write_status(NULL, 0, LCD_ON);
738 lcd_blank(FB_BLANK_POWERDOWN); 738 lcd_blank(FB_BLANK_POWERDOWN);
739 } 739 }
740 740
741 acpi_bus_generate_proc_event(hotk->device, event, 741 acpi_bus_generate_proc_event(hotk->device, event,
742 hotk->event_count[event % 128]++); 742 hotk->event_count[event % 128]++);
743 743
744 return; 744 return;
745 } 745 }
746 746
747 #define ASUS_CREATE_DEVICE_ATTR(_name) \ 747 #define ASUS_CREATE_DEVICE_ATTR(_name) \
748 struct device_attribute dev_attr_##_name = { \ 748 struct device_attribute dev_attr_##_name = { \
749 .attr = { \ 749 .attr = { \
750 .name = __stringify(_name), \ 750 .name = __stringify(_name), \
751 .mode = 0 }, \ 751 .mode = 0 }, \
752 .show = NULL, \ 752 .show = NULL, \
753 .store = NULL, \ 753 .store = NULL, \
754 } 754 }
755 755
756 #define ASUS_SET_DEVICE_ATTR(_name, _mode, _show, _store) \ 756 #define ASUS_SET_DEVICE_ATTR(_name, _mode, _show, _store) \
757 do { \ 757 do { \
758 dev_attr_##_name.attr.mode = _mode; \ 758 dev_attr_##_name.attr.mode = _mode; \
759 dev_attr_##_name.show = _show; \ 759 dev_attr_##_name.show = _show; \
760 dev_attr_##_name.store = _store; \ 760 dev_attr_##_name.store = _store; \
761 } while(0) 761 } while(0)
762 762
763 static ASUS_CREATE_DEVICE_ATTR(infos); 763 static ASUS_CREATE_DEVICE_ATTR(infos);
764 static ASUS_CREATE_DEVICE_ATTR(wlan); 764 static ASUS_CREATE_DEVICE_ATTR(wlan);
765 static ASUS_CREATE_DEVICE_ATTR(bluetooth); 765 static ASUS_CREATE_DEVICE_ATTR(bluetooth);
766 static ASUS_CREATE_DEVICE_ATTR(display); 766 static ASUS_CREATE_DEVICE_ATTR(display);
767 static ASUS_CREATE_DEVICE_ATTR(ledd); 767 static ASUS_CREATE_DEVICE_ATTR(ledd);
768 static ASUS_CREATE_DEVICE_ATTR(ls_switch); 768 static ASUS_CREATE_DEVICE_ATTR(ls_switch);
769 static ASUS_CREATE_DEVICE_ATTR(ls_level); 769 static ASUS_CREATE_DEVICE_ATTR(ls_level);
770 static ASUS_CREATE_DEVICE_ATTR(gps); 770 static ASUS_CREATE_DEVICE_ATTR(gps);
771 771
772 static struct attribute *asuspf_attributes[] = { 772 static struct attribute *asuspf_attributes[] = {
773 &dev_attr_infos.attr, 773 &dev_attr_infos.attr,
774 &dev_attr_wlan.attr, 774 &dev_attr_wlan.attr,
775 &dev_attr_bluetooth.attr, 775 &dev_attr_bluetooth.attr,
776 &dev_attr_display.attr, 776 &dev_attr_display.attr,
777 &dev_attr_ledd.attr, 777 &dev_attr_ledd.attr,
778 &dev_attr_ls_switch.attr, 778 &dev_attr_ls_switch.attr,
779 &dev_attr_ls_level.attr, 779 &dev_attr_ls_level.attr,
780 &dev_attr_gps.attr, 780 &dev_attr_gps.attr,
781 NULL 781 NULL
782 }; 782 };
783 783
784 static struct attribute_group asuspf_attribute_group = { 784 static struct attribute_group asuspf_attribute_group = {
785 .attrs = asuspf_attributes 785 .attrs = asuspf_attributes
786 }; 786 };
787 787
788 static struct platform_driver asuspf_driver = { 788 static struct platform_driver asuspf_driver = {
789 .driver = { 789 .driver = {
790 .name = ASUS_HOTK_FILE, 790 .name = ASUS_HOTK_FILE,
791 .owner = THIS_MODULE, 791 .owner = THIS_MODULE,
792 } 792 }
793 }; 793 };
794 794
795 static struct platform_device *asuspf_device; 795 static struct platform_device *asuspf_device;
796 796
797 static void asus_hotk_add_fs(void) 797 static void asus_hotk_add_fs(void)
798 { 798 {
799 ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL); 799 ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL);
800 800
801 if (wl_switch_handle) 801 if (wl_switch_handle)
802 ASUS_SET_DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan); 802 ASUS_SET_DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan);
803 803
804 if (bt_switch_handle) 804 if (bt_switch_handle)
805 ASUS_SET_DEVICE_ATTR(bluetooth, 0644, 805 ASUS_SET_DEVICE_ATTR(bluetooth, 0644,
806 show_bluetooth, store_bluetooth); 806 show_bluetooth, store_bluetooth);
807 807
808 if (display_set_handle && display_get_handle) 808 if (display_set_handle && display_get_handle)
809 ASUS_SET_DEVICE_ATTR(display, 0644, show_disp, store_disp); 809 ASUS_SET_DEVICE_ATTR(display, 0644, show_disp, store_disp);
810 else if (display_set_handle) 810 else if (display_set_handle)
811 ASUS_SET_DEVICE_ATTR(display, 0200, NULL, store_disp); 811 ASUS_SET_DEVICE_ATTR(display, 0200, NULL, store_disp);
812 812
813 if (ledd_set_handle) 813 if (ledd_set_handle)
814 ASUS_SET_DEVICE_ATTR(ledd, 0644, show_ledd, store_ledd); 814 ASUS_SET_DEVICE_ATTR(ledd, 0644, show_ledd, store_ledd);
815 815
816 if (ls_switch_handle && ls_level_handle) { 816 if (ls_switch_handle && ls_level_handle) {
817 ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl); 817 ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl);
818 ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw); 818 ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw);
819 } 819 }
820 820
821 if (gps_status_handle && gps_on_handle && gps_off_handle) 821 if (gps_status_handle && gps_on_handle && gps_off_handle)
822 ASUS_SET_DEVICE_ATTR(gps, 0644, show_gps, store_gps); 822 ASUS_SET_DEVICE_ATTR(gps, 0644, show_gps, store_gps);
823 } 823 }
824 824
825 static int asus_handle_init(char *name, acpi_handle * handle, 825 static int asus_handle_init(char *name, acpi_handle * handle,
826 char **paths, int num_paths) 826 char **paths, int num_paths)
827 { 827 {
828 int i; 828 int i;
829 acpi_status status; 829 acpi_status status;
830 830
831 for (i = 0; i < num_paths; i++) { 831 for (i = 0; i < num_paths; i++) {
832 status = acpi_get_handle(NULL, paths[i], handle); 832 status = acpi_get_handle(NULL, paths[i], handle);
833 if (ACPI_SUCCESS(status)) 833 if (ACPI_SUCCESS(status))
834 return 0; 834 return 0;
835 } 835 }
836 836
837 *handle = NULL; 837 *handle = NULL;
838 return -ENODEV; 838 return -ENODEV;
839 } 839 }
840 840
841 #define ASUS_HANDLE_INIT(object) \ 841 #define ASUS_HANDLE_INIT(object) \
842 asus_handle_init(#object, &object##_handle, object##_paths, \ 842 asus_handle_init(#object, &object##_handle, object##_paths, \
843 ARRAY_SIZE(object##_paths)) 843 ARRAY_SIZE(object##_paths))
844 844
845 /* 845 /*
846 * This function is used to initialize the hotk with right values. In this 846 * This function is used to initialize the hotk with right values. In this
847 * method, we can make all the detection we want, and modify the hotk struct 847 * method, we can make all the detection we want, and modify the hotk struct
848 */ 848 */
849 static int asus_hotk_get_info(void) 849 static int asus_hotk_get_info(void)
850 { 850 {
851 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 851 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
852 union acpi_object *model = NULL; 852 union acpi_object *model = NULL;
853 unsigned long long bsts_result, hwrs_result; 853 unsigned long long bsts_result, hwrs_result;
854 char *string = NULL; 854 char *string = NULL;
855 acpi_status status; 855 acpi_status status;
856 856
857 /* 857 /*
858 * Get DSDT headers early enough to allow for differentiating between 858 * Get DSDT headers early enough to allow for differentiating between
859 * models, but late enough to allow acpi_bus_register_driver() to fail 859 * models, but late enough to allow acpi_bus_register_driver() to fail
860 * before doing anything ACPI-specific. Should we encounter a machine, 860 * before doing anything ACPI-specific. Should we encounter a machine,
861 * which needs special handling (i.e. its hotkey device has a different 861 * which needs special handling (i.e. its hotkey device has a different
862 * HID), this bit will be moved. A global variable asus_info contains 862 * HID), this bit will be moved. A global variable asus_info contains
863 * the DSDT header. 863 * the DSDT header.
864 */ 864 */
865 status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); 865 status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info);
866 if (ACPI_FAILURE(status)) 866 if (ACPI_FAILURE(status))
867 printk(ASUS_WARNING "Couldn't get the DSDT table header\n"); 867 printk(ASUS_WARNING "Couldn't get the DSDT table header\n");
868 868
869 /* We have to write 0 on init this far for all ASUS models */ 869 /* We have to write 0 on init this far for all ASUS models */
870 if (write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { 870 if (write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
871 printk(ASUS_ERR "Hotkey initialization failed\n"); 871 printk(ASUS_ERR "Hotkey initialization failed\n");
872 return -ENODEV; 872 return -ENODEV;
873 } 873 }
874 874
875 /* This needs to be called for some laptops to init properly */ 875 /* This needs to be called for some laptops to init properly */
876 status = 876 status =
877 acpi_evaluate_integer(hotk->handle, "BSTS", NULL, &bsts_result); 877 acpi_evaluate_integer(hotk->handle, "BSTS", NULL, &bsts_result);
878 if (ACPI_FAILURE(status)) 878 if (ACPI_FAILURE(status))
879 printk(ASUS_WARNING "Error calling BSTS\n"); 879 printk(ASUS_WARNING "Error calling BSTS\n");
880 else if (bsts_result) 880 else if (bsts_result)
881 printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n", 881 printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n",
882 (uint) bsts_result); 882 (uint) bsts_result);
883 883
884 /* This too ... */ 884 /* This too ... */
885 write_acpi_int(hotk->handle, "CWAP", wapf, NULL); 885 write_acpi_int(hotk->handle, "CWAP", wapf, NULL);
886 886
887 /* 887 /*
888 * Try to match the object returned by INIT to the specific model. 888 * Try to match the object returned by INIT to the specific model.
889 * Handle every possible object (or the lack of thereof) the DSDT 889 * Handle every possible object (or the lack of thereof) the DSDT
890 * writers might throw at us. When in trouble, we pass NULL to 890 * writers might throw at us. When in trouble, we pass NULL to
891 * asus_model_match() and try something completely different. 891 * asus_model_match() and try something completely different.
892 */ 892 */
893 if (buffer.pointer) { 893 if (buffer.pointer) {
894 model = buffer.pointer; 894 model = buffer.pointer;
895 switch (model->type) { 895 switch (model->type) {
896 case ACPI_TYPE_STRING: 896 case ACPI_TYPE_STRING:
897 string = model->string.pointer; 897 string = model->string.pointer;
898 break; 898 break;
899 case ACPI_TYPE_BUFFER: 899 case ACPI_TYPE_BUFFER:
900 string = model->buffer.pointer; 900 string = model->buffer.pointer;
901 break; 901 break;
902 default: 902 default:
903 string = ""; 903 string = "";
904 break; 904 break;
905 } 905 }
906 } 906 }
907 hotk->name = kstrdup(string, GFP_KERNEL); 907 hotk->name = kstrdup(string, GFP_KERNEL);
908 if (!hotk->name) 908 if (!hotk->name)
909 return -ENOMEM; 909 return -ENOMEM;
910 910
911 if (*string) 911 if (*string)
912 printk(ASUS_NOTICE " %s model detected\n", string); 912 printk(ASUS_NOTICE " %s model detected\n", string);
913 913
914 ASUS_HANDLE_INIT(mled_set); 914 ASUS_HANDLE_INIT(mled_set);
915 ASUS_HANDLE_INIT(tled_set); 915 ASUS_HANDLE_INIT(tled_set);
916 ASUS_HANDLE_INIT(rled_set); 916 ASUS_HANDLE_INIT(rled_set);
917 ASUS_HANDLE_INIT(pled_set); 917 ASUS_HANDLE_INIT(pled_set);
918 ASUS_HANDLE_INIT(gled_set); 918 ASUS_HANDLE_INIT(gled_set);
919 919
920 ASUS_HANDLE_INIT(ledd_set); 920 ASUS_HANDLE_INIT(ledd_set);
921 921
922 /* 922 /*
923 * The HWRS method return informations about the hardware. 923 * The HWRS method return informations about the hardware.
924 * 0x80 bit is for WLAN, 0x100 for Bluetooth. 924 * 0x80 bit is for WLAN, 0x100 for Bluetooth.
925 * The significance of others is yet to be found. 925 * The significance of others is yet to be found.
926 * If we don't find the method, we assume the device are present. 926 * If we don't find the method, we assume the device are present.
927 */ 927 */
928 status = 928 status =
929 acpi_evaluate_integer(hotk->handle, "HRWS", NULL, &hwrs_result); 929 acpi_evaluate_integer(hotk->handle, "HRWS", NULL, &hwrs_result);
930 if (ACPI_FAILURE(status)) 930 if (ACPI_FAILURE(status))
931 hwrs_result = WL_HWRS | BT_HWRS; 931 hwrs_result = WL_HWRS | BT_HWRS;
932 932
933 if (hwrs_result & WL_HWRS) 933 if (hwrs_result & WL_HWRS)
934 ASUS_HANDLE_INIT(wl_switch); 934 ASUS_HANDLE_INIT(wl_switch);
935 if (hwrs_result & BT_HWRS) 935 if (hwrs_result & BT_HWRS)
936 ASUS_HANDLE_INIT(bt_switch); 936 ASUS_HANDLE_INIT(bt_switch);
937 937
938 ASUS_HANDLE_INIT(wireless_status); 938 ASUS_HANDLE_INIT(wireless_status);
939 939
940 ASUS_HANDLE_INIT(brightness_set); 940 ASUS_HANDLE_INIT(brightness_set);
941 ASUS_HANDLE_INIT(brightness_get); 941 ASUS_HANDLE_INIT(brightness_get);
942 942
943 ASUS_HANDLE_INIT(lcd_switch); 943 ASUS_HANDLE_INIT(lcd_switch);
944 944
945 ASUS_HANDLE_INIT(display_set); 945 ASUS_HANDLE_INIT(display_set);
946 ASUS_HANDLE_INIT(display_get); 946 ASUS_HANDLE_INIT(display_get);
947 947
948 /* There is a lot of models with "ALSL", but a few get 948 /* There is a lot of models with "ALSL", but a few get
949 a real light sens, so we need to check it. */ 949 a real light sens, so we need to check it. */
950 if (!ASUS_HANDLE_INIT(ls_switch)) 950 if (!ASUS_HANDLE_INIT(ls_switch))
951 ASUS_HANDLE_INIT(ls_level); 951 ASUS_HANDLE_INIT(ls_level);
952 952
953 ASUS_HANDLE_INIT(gps_on); 953 ASUS_HANDLE_INIT(gps_on);
954 ASUS_HANDLE_INIT(gps_off); 954 ASUS_HANDLE_INIT(gps_off);
955 ASUS_HANDLE_INIT(gps_status); 955 ASUS_HANDLE_INIT(gps_status);
956 956
957 kfree(model); 957 kfree(model);
958 958
959 return AE_OK; 959 return AE_OK;
960 } 960 }
961 961
962 static int asus_hotk_check(void) 962 static int asus_hotk_check(void)
963 { 963 {
964 int result = 0; 964 int result = 0;
965 965
966 result = acpi_bus_get_status(hotk->device); 966 result = acpi_bus_get_status(hotk->device);
967 if (result) 967 if (result)
968 return result; 968 return result;
969 969
970 if (hotk->device->status.present) { 970 if (hotk->device->status.present) {
971 result = asus_hotk_get_info(); 971 result = asus_hotk_get_info();
972 } else { 972 } else {
973 printk(ASUS_ERR "Hotkey device not present, aborting\n"); 973 printk(ASUS_ERR "Hotkey device not present, aborting\n");
974 return -EINVAL; 974 return -EINVAL;
975 } 975 }
976 976
977 return result; 977 return result;
978 } 978 }
979 979
980 static int asus_hotk_found; 980 static int asus_hotk_found;
981 981
982 static int asus_hotk_add(struct acpi_device *device) 982 static int asus_hotk_add(struct acpi_device *device)
983 { 983 {
984 acpi_status status = AE_OK; 984 acpi_status status = AE_OK;
985 int result; 985 int result;
986 986
987 if (!device) 987 if (!device)
988 return -EINVAL; 988 return -EINVAL;
989 989
990 printk(ASUS_NOTICE "Asus Laptop Support version %s\n", 990 printk(ASUS_NOTICE "Asus Laptop Support version %s\n",
991 ASUS_LAPTOP_VERSION); 991 ASUS_LAPTOP_VERSION);
992 992
993 hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); 993 hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL);
994 if (!hotk) 994 if (!hotk)
995 return -ENOMEM; 995 return -ENOMEM;
996 996
997 hotk->handle = device->handle; 997 hotk->handle = device->handle;
998 strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); 998 strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME);
999 strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); 999 strcpy(acpi_device_class(device), ASUS_HOTK_CLASS);
1000 device->driver_data = hotk; 1000 device->driver_data = hotk;
1001 hotk->device = device; 1001 hotk->device = device;
1002 1002
1003 result = asus_hotk_check(); 1003 result = asus_hotk_check();
1004 if (result) 1004 if (result)
1005 goto end; 1005 goto end;
1006 1006
1007 asus_hotk_add_fs(); 1007 asus_hotk_add_fs();
1008 1008
1009 /* 1009 /*
1010 * We install the handler, it will receive the hotk in parameter, so, we 1010 * We install the handler, it will receive the hotk in parameter, so, we
1011 * could add other data to the hotk struct 1011 * could add other data to the hotk struct
1012 */ 1012 */
1013 status = acpi_install_notify_handler(hotk->handle, ACPI_ALL_NOTIFY, 1013 status = acpi_install_notify_handler(hotk->handle, ACPI_ALL_NOTIFY,
1014 asus_hotk_notify, hotk); 1014 asus_hotk_notify, hotk);
1015 if (ACPI_FAILURE(status)) 1015 if (ACPI_FAILURE(status))
1016 printk(ASUS_ERR "Error installing notify handler\n"); 1016 printk(ASUS_ERR "Error installing notify handler\n");
1017 1017
1018 asus_hotk_found = 1; 1018 asus_hotk_found = 1;
1019 1019
1020 /* WLED and BLED are on by default */ 1020 /* WLED and BLED are on by default */
1021 write_status(bt_switch_handle, 1, BT_ON); 1021 write_status(bt_switch_handle, 1, BT_ON);
1022 write_status(wl_switch_handle, 1, WL_ON); 1022 write_status(wl_switch_handle, 1, WL_ON);
1023 1023
1024 /* If the h/w switch is off, we need to check the real status */ 1024 /* If the h/w switch is off, we need to check the real status */
1025 write_status(NULL, read_status(BT_ON), BT_ON); 1025 write_status(NULL, read_status(BT_ON), BT_ON);
1026 write_status(NULL, read_status(WL_ON), WL_ON); 1026 write_status(NULL, read_status(WL_ON), WL_ON);
1027 1027
1028 /* LCD Backlight is on by default */ 1028 /* LCD Backlight is on by default */
1029 write_status(NULL, 1, LCD_ON); 1029 write_status(NULL, 1, LCD_ON);
1030 1030
1031 /* LED display is off by default */ 1031 /* LED display is off by default */
1032 hotk->ledd_status = 0xFFF; 1032 hotk->ledd_status = 0xFFF;
1033 1033
1034 /* Set initial values of light sensor and level */ 1034 /* Set initial values of light sensor and level */
1035 hotk->light_switch = 1; /* Default to light sensor disabled */ 1035 hotk->light_switch = 1; /* Default to light sensor disabled */
1036 hotk->light_level = 0; /* level 5 for sensor sensitivity */ 1036 hotk->light_level = 0; /* level 5 for sensor sensitivity */
1037 1037
1038 if (ls_switch_handle) 1038 if (ls_switch_handle)
1039 set_light_sens_switch(hotk->light_switch); 1039 set_light_sens_switch(hotk->light_switch);
1040 1040
1041 if (ls_level_handle) 1041 if (ls_level_handle)
1042 set_light_sens_level(hotk->light_level); 1042 set_light_sens_level(hotk->light_level);
1043 1043
1044 /* GPS is on by default */ 1044 /* GPS is on by default */
1045 write_status(NULL, 1, GPS_ON); 1045 write_status(NULL, 1, GPS_ON);
1046 1046
1047 end: 1047 end:
1048 if (result) { 1048 if (result) {
1049 kfree(hotk->name); 1049 kfree(hotk->name);
1050 kfree(hotk); 1050 kfree(hotk);
1051 } 1051 }
1052 1052
1053 return result; 1053 return result;
1054 } 1054 }
1055 1055
1056 static int asus_hotk_remove(struct acpi_device *device, int type) 1056 static int asus_hotk_remove(struct acpi_device *device, int type)
1057 { 1057 {
1058 acpi_status status = 0; 1058 acpi_status status = 0;
1059 1059
1060 if (!device || !acpi_driver_data(device)) 1060 if (!device || !acpi_driver_data(device))
1061 return -EINVAL; 1061 return -EINVAL;
1062 1062
1063 status = acpi_remove_notify_handler(hotk->handle, ACPI_ALL_NOTIFY, 1063 status = acpi_remove_notify_handler(hotk->handle, ACPI_ALL_NOTIFY,
1064 asus_hotk_notify); 1064 asus_hotk_notify);
1065 if (ACPI_FAILURE(status)) 1065 if (ACPI_FAILURE(status))
1066 printk(ASUS_ERR "Error removing notify handler\n"); 1066 printk(ASUS_ERR "Error removing notify handler\n");
1067 1067
1068 kfree(hotk->name); 1068 kfree(hotk->name);
1069 kfree(hotk); 1069 kfree(hotk);
1070 1070
1071 return 0; 1071 return 0;
1072 } 1072 }
1073 1073
1074 static void asus_backlight_exit(void) 1074 static void asus_backlight_exit(void)
1075 { 1075 {
1076 if (asus_backlight_device) 1076 if (asus_backlight_device)
1077 backlight_device_unregister(asus_backlight_device); 1077 backlight_device_unregister(asus_backlight_device);
1078 } 1078 }
1079 1079
1080 #define ASUS_LED_UNREGISTER(object) \ 1080 #define ASUS_LED_UNREGISTER(object) \
1081 if (object##_led.dev) \ 1081 if (object##_led.dev) \
1082 led_classdev_unregister(&object##_led) 1082 led_classdev_unregister(&object##_led)
1083 1083
1084 static void asus_led_exit(void) 1084 static void asus_led_exit(void)
1085 { 1085 {
1086 destroy_workqueue(led_workqueue); 1086 destroy_workqueue(led_workqueue);
1087 ASUS_LED_UNREGISTER(mled); 1087 ASUS_LED_UNREGISTER(mled);
1088 ASUS_LED_UNREGISTER(tled); 1088 ASUS_LED_UNREGISTER(tled);
1089 ASUS_LED_UNREGISTER(pled); 1089 ASUS_LED_UNREGISTER(pled);
1090 ASUS_LED_UNREGISTER(rled); 1090 ASUS_LED_UNREGISTER(rled);
1091 ASUS_LED_UNREGISTER(gled); 1091 ASUS_LED_UNREGISTER(gled);
1092 } 1092 }
1093 1093
1094 static void __exit asus_laptop_exit(void) 1094 static void __exit asus_laptop_exit(void)
1095 { 1095 {
1096 asus_backlight_exit(); 1096 asus_backlight_exit();
1097 asus_led_exit(); 1097 asus_led_exit();
1098 1098
1099 acpi_bus_unregister_driver(&asus_hotk_driver); 1099 acpi_bus_unregister_driver(&asus_hotk_driver);
1100 sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group); 1100 sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group);
1101 platform_device_unregister(asuspf_device); 1101 platform_device_unregister(asuspf_device);
1102 platform_driver_unregister(&asuspf_driver); 1102 platform_driver_unregister(&asuspf_driver);
1103 } 1103 }
1104 1104
1105 static int asus_backlight_init(struct device *dev) 1105 static int asus_backlight_init(struct device *dev)
1106 { 1106 {
1107 struct backlight_device *bd; 1107 struct backlight_device *bd;
1108 1108
1109 if (brightness_set_handle && lcd_switch_handle) { 1109 if (brightness_set_handle && lcd_switch_handle) {
1110 bd = backlight_device_register(ASUS_HOTK_FILE, dev, 1110 bd = backlight_device_register(ASUS_HOTK_FILE, dev,
1111 NULL, &asusbl_ops); 1111 NULL, &asusbl_ops);
1112 if (IS_ERR(bd)) { 1112 if (IS_ERR(bd)) {
1113 printk(ASUS_ERR 1113 printk(ASUS_ERR
1114 "Could not register asus backlight device\n"); 1114 "Could not register asus backlight device\n");
1115 asus_backlight_device = NULL; 1115 asus_backlight_device = NULL;
1116 return PTR_ERR(bd); 1116 return PTR_ERR(bd);
1117 } 1117 }
1118 1118
1119 asus_backlight_device = bd; 1119 asus_backlight_device = bd;
1120 1120
1121 bd->props.max_brightness = 15; 1121 bd->props.max_brightness = 15;
1122 bd->props.brightness = read_brightness(NULL); 1122 bd->props.brightness = read_brightness(NULL);
1123 bd->props.power = FB_BLANK_UNBLANK; 1123 bd->props.power = FB_BLANK_UNBLANK;
1124 backlight_update_status(bd); 1124 backlight_update_status(bd);
1125 } 1125 }
1126 return 0; 1126 return 0;
1127 } 1127 }
1128 1128
1129 static int asus_led_register(acpi_handle handle, 1129 static int asus_led_register(acpi_handle handle,
1130 struct led_classdev *ldev, struct device *dev) 1130 struct led_classdev *ldev, struct device *dev)
1131 { 1131 {
1132 if (!handle) 1132 if (!handle)
1133 return 0; 1133 return 0;
1134 1134
1135 return led_classdev_register(dev, ldev); 1135 return led_classdev_register(dev, ldev);
1136 } 1136 }
1137 1137
1138 #define ASUS_LED_REGISTER(object, device) \ 1138 #define ASUS_LED_REGISTER(object, device) \
1139 asus_led_register(object##_set_handle, &object##_led, device) 1139 asus_led_register(object##_set_handle, &object##_led, device)
1140 1140
1141 static int asus_led_init(struct device *dev) 1141 static int asus_led_init(struct device *dev)
1142 { 1142 {
1143 int rv; 1143 int rv;
1144 1144
1145 rv = ASUS_LED_REGISTER(mled, dev); 1145 rv = ASUS_LED_REGISTER(mled, dev);
1146 if (rv) 1146 if (rv)
1147 goto out; 1147 goto out;
1148 1148
1149 rv = ASUS_LED_REGISTER(tled, dev); 1149 rv = ASUS_LED_REGISTER(tled, dev);
1150 if (rv) 1150 if (rv)
1151 goto out1; 1151 goto out1;
1152 1152
1153 rv = ASUS_LED_REGISTER(rled, dev); 1153 rv = ASUS_LED_REGISTER(rled, dev);
1154 if (rv) 1154 if (rv)
1155 goto out2; 1155 goto out2;
1156 1156
1157 rv = ASUS_LED_REGISTER(pled, dev); 1157 rv = ASUS_LED_REGISTER(pled, dev);
1158 if (rv) 1158 if (rv)
1159 goto out3; 1159 goto out3;
1160 1160
1161 rv = ASUS_LED_REGISTER(gled, dev); 1161 rv = ASUS_LED_REGISTER(gled, dev);
1162 if (rv) 1162 if (rv)
1163 goto out4; 1163 goto out4;
1164 1164
1165 led_workqueue = create_singlethread_workqueue("led_workqueue"); 1165 led_workqueue = create_singlethread_workqueue("led_workqueue");
1166 if (!led_workqueue) 1166 if (!led_workqueue)
1167 goto out5; 1167 goto out5;
1168 1168
1169 return 0; 1169 return 0;
1170 out5: 1170 out5:
1171 rv = -ENOMEM; 1171 rv = -ENOMEM;
1172 ASUS_LED_UNREGISTER(gled); 1172 ASUS_LED_UNREGISTER(gled);
1173 out4: 1173 out4:
1174 ASUS_LED_UNREGISTER(pled); 1174 ASUS_LED_UNREGISTER(pled);
1175 out3: 1175 out3:
1176 ASUS_LED_UNREGISTER(rled); 1176 ASUS_LED_UNREGISTER(rled);
1177 out2: 1177 out2:
1178 ASUS_LED_UNREGISTER(tled); 1178 ASUS_LED_UNREGISTER(tled);
1179 out1: 1179 out1:
1180 ASUS_LED_UNREGISTER(mled); 1180 ASUS_LED_UNREGISTER(mled);
1181 out: 1181 out:
1182 return rv; 1182 return rv;
1183 } 1183 }
1184 1184
1185 static int __init asus_laptop_init(void) 1185 static int __init asus_laptop_init(void)
1186 { 1186 {
1187 struct device *dev; 1187 struct device *dev;
1188 int result; 1188 int result;
1189 1189
1190 if (acpi_disabled) 1190 if (acpi_disabled)
1191 return -ENODEV; 1191 return -ENODEV;
1192 1192
1193 result = acpi_bus_register_driver(&asus_hotk_driver); 1193 result = acpi_bus_register_driver(&asus_hotk_driver);
1194 if (result < 0) 1194 if (result < 0)
1195 return result; 1195 return result;
1196 1196
1197 /* 1197 /*
1198 * This is a bit of a kludge. We only want this module loaded 1198 * This is a bit of a kludge. We only want this module loaded
1199 * for ASUS systems, but there's currently no way to probe the 1199 * for ASUS systems, but there's currently no way to probe the
1200 * ACPI namespace for ASUS HIDs. So we just return failure if 1200 * ACPI namespace for ASUS HIDs. So we just return failure if
1201 * we didn't find one, which will cause the module to be 1201 * we didn't find one, which will cause the module to be
1202 * unloaded. 1202 * unloaded.
1203 */ 1203 */
1204 if (!asus_hotk_found) { 1204 if (!asus_hotk_found) {
1205 acpi_bus_unregister_driver(&asus_hotk_driver); 1205 acpi_bus_unregister_driver(&asus_hotk_driver);
1206 return -ENODEV; 1206 return -ENODEV;
1207 } 1207 }
1208 1208
1209 dev = acpi_get_physical_device(hotk->device->handle); 1209 dev = acpi_get_physical_device(hotk->device->handle);
1210 1210
1211 result = asus_backlight_init(dev); 1211 if (!acpi_video_backlight_support()) {
1212 if (result) 1212 result = asus_backlight_init(dev);
1213 goto fail_backlight; 1213 if (result)
1214 goto fail_backlight;
1215 } else
1216 printk(ASUS_INFO "Brightness ignored, must be controlled by "
1217 "ACPI video driver\n");
1214 1218
1215 result = asus_led_init(dev); 1219 result = asus_led_init(dev);
1216 if (result) 1220 if (result)
1217 goto fail_led; 1221 goto fail_led;
1218 1222
1219 /* Register platform stuff */ 1223 /* Register platform stuff */
1220 result = platform_driver_register(&asuspf_driver); 1224 result = platform_driver_register(&asuspf_driver);
1221 if (result) 1225 if (result)
1222 goto fail_platform_driver; 1226 goto fail_platform_driver;
1223 1227
1224 asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1); 1228 asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1);
1225 if (!asuspf_device) { 1229 if (!asuspf_device) {
1226 result = -ENOMEM; 1230 result = -ENOMEM;
1227 goto fail_platform_device1; 1231 goto fail_platform_device1;
1228 } 1232 }
1229 1233
1230 result = platform_device_add(asuspf_device); 1234 result = platform_device_add(asuspf_device);
1231 if (result) 1235 if (result)
1232 goto fail_platform_device2; 1236 goto fail_platform_device2;
1233 1237
1234 result = sysfs_create_group(&asuspf_device->dev.kobj, 1238 result = sysfs_create_group(&asuspf_device->dev.kobj,
1235 &asuspf_attribute_group); 1239 &asuspf_attribute_group);
1236 if (result) 1240 if (result)
1237 goto fail_sysfs; 1241 goto fail_sysfs;
1238 1242
1239 return 0; 1243 return 0;
1240 1244
1241 fail_sysfs: 1245 fail_sysfs:
1242 platform_device_del(asuspf_device); 1246 platform_device_del(asuspf_device);
1243 1247
1244 fail_platform_device2: 1248 fail_platform_device2:
1245 platform_device_put(asuspf_device); 1249 platform_device_put(asuspf_device);
1246 1250
1247 fail_platform_device1: 1251 fail_platform_device1:
1248 platform_driver_unregister(&asuspf_driver); 1252 platform_driver_unregister(&asuspf_driver);
1249 1253
1250 fail_platform_driver: 1254 fail_platform_driver:
1251 asus_led_exit(); 1255 asus_led_exit();
1252 1256
1253 fail_led: 1257 fail_led:
1254 asus_backlight_exit(); 1258 asus_backlight_exit();
1255 1259
1256 fail_backlight: 1260 fail_backlight:
1257 1261
1258 return result; 1262 return result;
1259 } 1263 }
1260 1264
1261 module_init(asus_laptop_init); 1265 module_init(asus_laptop_init);
1262 module_exit(asus_laptop_exit); 1266 module_exit(asus_laptop_exit);
1263 1267
drivers/misc/compal-laptop.c
1 /*-*-linux-c-*-*/ 1 /*-*-linux-c-*-*/
2 2
3 /* 3 /*
4 Copyright (C) 2008 Cezary Jackiewicz <cezary.jackiewicz (at) gmail.com> 4 Copyright (C) 2008 Cezary Jackiewicz <cezary.jackiewicz (at) gmail.com>
5 5
6 based on MSI driver 6 based on MSI driver
7 7
8 Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de> 8 Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
9 9
10 This program is free software; you can redistribute it and/or modify 10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by 11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or 12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version. 13 (at your option) any later version.
14 14
15 This program is distributed in the hope that it will be useful, but 15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of 16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details. 18 General Public License for more details.
19 19
20 You should have received a copy of the GNU General Public License 20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software 21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 02110-1301, USA. 23 02110-1301, USA.
24 */ 24 */
25 25
26 /* 26 /*
27 * comapl-laptop.c - Compal laptop support. 27 * comapl-laptop.c - Compal laptop support.
28 * 28 *
29 * This driver exports a few files in /sys/devices/platform/compal-laptop/: 29 * This driver exports a few files in /sys/devices/platform/compal-laptop/:
30 * 30 *
31 * wlan - wlan subsystem state: contains 0 or 1 (rw) 31 * wlan - wlan subsystem state: contains 0 or 1 (rw)
32 * 32 *
33 * bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw) 33 * bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw)
34 * 34 *
35 * raw - raw value taken from embedded controller register (ro) 35 * raw - raw value taken from embedded controller register (ro)
36 * 36 *
37 * In addition to these platform device attributes the driver 37 * In addition to these platform device attributes the driver
38 * registers itself in the Linux backlight control subsystem and is 38 * registers itself in the Linux backlight control subsystem and is
39 * available to userspace under /sys/class/backlight/compal-laptop/. 39 * available to userspace under /sys/class/backlight/compal-laptop/.
40 * 40 *
41 * This driver might work on other laptops produced by Compal. If you 41 * This driver might work on other laptops produced by Compal. If you
42 * want to try it you can pass force=1 as argument to the module which 42 * want to try it you can pass force=1 as argument to the module which
43 * will force it to load even when the DMI data doesn't identify the 43 * will force it to load even when the DMI data doesn't identify the
44 * laptop as FL9x. 44 * laptop as FL9x.
45 */ 45 */
46 46
47 #include <linux/module.h> 47 #include <linux/module.h>
48 #include <linux/kernel.h> 48 #include <linux/kernel.h>
49 #include <linux/init.h> 49 #include <linux/init.h>
50 #include <linux/acpi.h> 50 #include <linux/acpi.h>
51 #include <linux/dmi.h> 51 #include <linux/dmi.h>
52 #include <linux/backlight.h> 52 #include <linux/backlight.h>
53 #include <linux/platform_device.h> 53 #include <linux/platform_device.h>
54 #include <linux/autoconf.h> 54 #include <linux/autoconf.h>
55 55
56 #define COMPAL_DRIVER_VERSION "0.2.6" 56 #define COMPAL_DRIVER_VERSION "0.2.6"
57 57
58 #define COMPAL_LCD_LEVEL_MAX 8 58 #define COMPAL_LCD_LEVEL_MAX 8
59 59
60 #define COMPAL_EC_COMMAND_WIRELESS 0xBB 60 #define COMPAL_EC_COMMAND_WIRELESS 0xBB
61 #define COMPAL_EC_COMMAND_LCD_LEVEL 0xB9 61 #define COMPAL_EC_COMMAND_LCD_LEVEL 0xB9
62 62
63 #define KILLSWITCH_MASK 0x10 63 #define KILLSWITCH_MASK 0x10
64 #define WLAN_MASK 0x01 64 #define WLAN_MASK 0x01
65 #define BT_MASK 0x02 65 #define BT_MASK 0x02
66 66
67 static int force; 67 static int force;
68 module_param(force, bool, 0); 68 module_param(force, bool, 0);
69 MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); 69 MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
70 70
71 /* Hardware access */ 71 /* Hardware access */
72 72
73 static int set_lcd_level(int level) 73 static int set_lcd_level(int level)
74 { 74 {
75 if (level < 0 || level >= COMPAL_LCD_LEVEL_MAX) 75 if (level < 0 || level >= COMPAL_LCD_LEVEL_MAX)
76 return -EINVAL; 76 return -EINVAL;
77 77
78 ec_write(COMPAL_EC_COMMAND_LCD_LEVEL, level); 78 ec_write(COMPAL_EC_COMMAND_LCD_LEVEL, level);
79 79
80 return 0; 80 return 0;
81 } 81 }
82 82
83 static int get_lcd_level(void) 83 static int get_lcd_level(void)
84 { 84 {
85 u8 result; 85 u8 result;
86 86
87 ec_read(COMPAL_EC_COMMAND_LCD_LEVEL, &result); 87 ec_read(COMPAL_EC_COMMAND_LCD_LEVEL, &result);
88 88
89 return (int) result; 89 return (int) result;
90 } 90 }
91 91
92 static int set_wlan_state(int state) 92 static int set_wlan_state(int state)
93 { 93 {
94 u8 result, value; 94 u8 result, value;
95 95
96 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); 96 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
97 97
98 if ((result & KILLSWITCH_MASK) == 0) 98 if ((result & KILLSWITCH_MASK) == 0)
99 return -EINVAL; 99 return -EINVAL;
100 else { 100 else {
101 if (state) 101 if (state)
102 value = (u8) (result | WLAN_MASK); 102 value = (u8) (result | WLAN_MASK);
103 else 103 else
104 value = (u8) (result & ~WLAN_MASK); 104 value = (u8) (result & ~WLAN_MASK);
105 ec_write(COMPAL_EC_COMMAND_WIRELESS, value); 105 ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
106 } 106 }
107 107
108 return 0; 108 return 0;
109 } 109 }
110 110
111 static int set_bluetooth_state(int state) 111 static int set_bluetooth_state(int state)
112 { 112 {
113 u8 result, value; 113 u8 result, value;
114 114
115 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); 115 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
116 116
117 if ((result & KILLSWITCH_MASK) == 0) 117 if ((result & KILLSWITCH_MASK) == 0)
118 return -EINVAL; 118 return -EINVAL;
119 else { 119 else {
120 if (state) 120 if (state)
121 value = (u8) (result | BT_MASK); 121 value = (u8) (result | BT_MASK);
122 else 122 else
123 value = (u8) (result & ~BT_MASK); 123 value = (u8) (result & ~BT_MASK);
124 ec_write(COMPAL_EC_COMMAND_WIRELESS, value); 124 ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
125 } 125 }
126 126
127 return 0; 127 return 0;
128 } 128 }
129 129
130 static int get_wireless_state(int *wlan, int *bluetooth) 130 static int get_wireless_state(int *wlan, int *bluetooth)
131 { 131 {
132 u8 result; 132 u8 result;
133 133
134 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); 134 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
135 135
136 if (wlan) { 136 if (wlan) {
137 if ((result & KILLSWITCH_MASK) == 0) 137 if ((result & KILLSWITCH_MASK) == 0)
138 *wlan = 0; 138 *wlan = 0;
139 else 139 else
140 *wlan = result & WLAN_MASK; 140 *wlan = result & WLAN_MASK;
141 } 141 }
142 142
143 if (bluetooth) { 143 if (bluetooth) {
144 if ((result & KILLSWITCH_MASK) == 0) 144 if ((result & KILLSWITCH_MASK) == 0)
145 *bluetooth = 0; 145 *bluetooth = 0;
146 else 146 else
147 *bluetooth = (result & BT_MASK) >> 1; 147 *bluetooth = (result & BT_MASK) >> 1;
148 } 148 }
149 149
150 return 0; 150 return 0;
151 } 151 }
152 152
153 /* Backlight device stuff */ 153 /* Backlight device stuff */
154 154
155 static int bl_get_brightness(struct backlight_device *b) 155 static int bl_get_brightness(struct backlight_device *b)
156 { 156 {
157 return get_lcd_level(); 157 return get_lcd_level();
158 } 158 }
159 159
160 160
161 static int bl_update_status(struct backlight_device *b) 161 static int bl_update_status(struct backlight_device *b)
162 { 162 {
163 return set_lcd_level(b->props.brightness); 163 return set_lcd_level(b->props.brightness);
164 } 164 }
165 165
166 static struct backlight_ops compalbl_ops = { 166 static struct backlight_ops compalbl_ops = {
167 .get_brightness = bl_get_brightness, 167 .get_brightness = bl_get_brightness,
168 .update_status = bl_update_status, 168 .update_status = bl_update_status,
169 }; 169 };
170 170
171 static struct backlight_device *compalbl_device; 171 static struct backlight_device *compalbl_device;
172 172
173 /* Platform device */ 173 /* Platform device */
174 174
175 static ssize_t show_wlan(struct device *dev, 175 static ssize_t show_wlan(struct device *dev,
176 struct device_attribute *attr, char *buf) 176 struct device_attribute *attr, char *buf)
177 { 177 {
178 int ret, enabled; 178 int ret, enabled;
179 179
180 ret = get_wireless_state(&enabled, NULL); 180 ret = get_wireless_state(&enabled, NULL);
181 if (ret < 0) 181 if (ret < 0)
182 return ret; 182 return ret;
183 183
184 return sprintf(buf, "%i\n", enabled); 184 return sprintf(buf, "%i\n", enabled);
185 } 185 }
186 186
187 static ssize_t show_raw(struct device *dev, 187 static ssize_t show_raw(struct device *dev,
188 struct device_attribute *attr, char *buf) 188 struct device_attribute *attr, char *buf)
189 { 189 {
190 u8 result; 190 u8 result;
191 191
192 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); 192 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
193 193
194 return sprintf(buf, "%i\n", result); 194 return sprintf(buf, "%i\n", result);
195 } 195 }
196 196
197 static ssize_t show_bluetooth(struct device *dev, 197 static ssize_t show_bluetooth(struct device *dev,
198 struct device_attribute *attr, char *buf) 198 struct device_attribute *attr, char *buf)
199 { 199 {
200 int ret, enabled; 200 int ret, enabled;
201 201
202 ret = get_wireless_state(NULL, &enabled); 202 ret = get_wireless_state(NULL, &enabled);
203 if (ret < 0) 203 if (ret < 0)
204 return ret; 204 return ret;
205 205
206 return sprintf(buf, "%i\n", enabled); 206 return sprintf(buf, "%i\n", enabled);
207 } 207 }
208 208
209 static ssize_t store_wlan_state(struct device *dev, 209 static ssize_t store_wlan_state(struct device *dev,
210 struct device_attribute *attr, const char *buf, size_t count) 210 struct device_attribute *attr, const char *buf, size_t count)
211 { 211 {
212 int state, ret; 212 int state, ret;
213 213
214 if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1)) 214 if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
215 return -EINVAL; 215 return -EINVAL;
216 216
217 ret = set_wlan_state(state); 217 ret = set_wlan_state(state);
218 if (ret < 0) 218 if (ret < 0)
219 return ret; 219 return ret;
220 220
221 return count; 221 return count;
222 } 222 }
223 223
224 static ssize_t store_bluetooth_state(struct device *dev, 224 static ssize_t store_bluetooth_state(struct device *dev,
225 struct device_attribute *attr, const char *buf, size_t count) 225 struct device_attribute *attr, const char *buf, size_t count)
226 { 226 {
227 int state, ret; 227 int state, ret;
228 228
229 if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1)) 229 if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
230 return -EINVAL; 230 return -EINVAL;
231 231
232 ret = set_bluetooth_state(state); 232 ret = set_bluetooth_state(state);
233 if (ret < 0) 233 if (ret < 0)
234 return ret; 234 return ret;
235 235
236 return count; 236 return count;
237 } 237 }
238 238
239 static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state); 239 static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state);
240 static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state); 240 static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state);
241 static DEVICE_ATTR(raw, 0444, show_raw, NULL); 241 static DEVICE_ATTR(raw, 0444, show_raw, NULL);
242 242
243 static struct attribute *compal_attributes[] = { 243 static struct attribute *compal_attributes[] = {
244 &dev_attr_bluetooth.attr, 244 &dev_attr_bluetooth.attr,
245 &dev_attr_wlan.attr, 245 &dev_attr_wlan.attr,
246 &dev_attr_raw.attr, 246 &dev_attr_raw.attr,
247 NULL 247 NULL
248 }; 248 };
249 249
250 static struct attribute_group compal_attribute_group = { 250 static struct attribute_group compal_attribute_group = {
251 .attrs = compal_attributes 251 .attrs = compal_attributes
252 }; 252 };
253 253
254 static struct platform_driver compal_driver = { 254 static struct platform_driver compal_driver = {
255 .driver = { 255 .driver = {
256 .name = "compal-laptop", 256 .name = "compal-laptop",
257 .owner = THIS_MODULE, 257 .owner = THIS_MODULE,
258 } 258 }
259 }; 259 };
260 260
261 static struct platform_device *compal_device; 261 static struct platform_device *compal_device;
262 262
263 /* Initialization */ 263 /* Initialization */
264 264
265 static int dmi_check_cb(const struct dmi_system_id *id) 265 static int dmi_check_cb(const struct dmi_system_id *id)
266 { 266 {
267 printk(KERN_INFO "compal-laptop: Identified laptop model '%s'.\n", 267 printk(KERN_INFO "compal-laptop: Identified laptop model '%s'.\n",
268 id->ident); 268 id->ident);
269 269
270 return 0; 270 return 0;
271 } 271 }
272 272
273 static struct dmi_system_id __initdata compal_dmi_table[] = { 273 static struct dmi_system_id __initdata compal_dmi_table[] = {
274 { 274 {
275 .ident = "FL90/IFL90", 275 .ident = "FL90/IFL90",
276 .matches = { 276 .matches = {
277 DMI_MATCH(DMI_BOARD_NAME, "IFL90"), 277 DMI_MATCH(DMI_BOARD_NAME, "IFL90"),
278 DMI_MATCH(DMI_BOARD_VERSION, "IFT00"), 278 DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
279 }, 279 },
280 .callback = dmi_check_cb 280 .callback = dmi_check_cb
281 }, 281 },
282 { 282 {
283 .ident = "FL90/IFL90", 283 .ident = "FL90/IFL90",
284 .matches = { 284 .matches = {
285 DMI_MATCH(DMI_BOARD_NAME, "IFL90"), 285 DMI_MATCH(DMI_BOARD_NAME, "IFL90"),
286 DMI_MATCH(DMI_BOARD_VERSION, "REFERENCE"), 286 DMI_MATCH(DMI_BOARD_VERSION, "REFERENCE"),
287 }, 287 },
288 .callback = dmi_check_cb 288 .callback = dmi_check_cb
289 }, 289 },
290 { 290 {
291 .ident = "FL91/IFL91", 291 .ident = "FL91/IFL91",
292 .matches = { 292 .matches = {
293 DMI_MATCH(DMI_BOARD_NAME, "IFL91"), 293 DMI_MATCH(DMI_BOARD_NAME, "IFL91"),
294 DMI_MATCH(DMI_BOARD_VERSION, "IFT00"), 294 DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
295 }, 295 },
296 .callback = dmi_check_cb 296 .callback = dmi_check_cb
297 }, 297 },
298 { 298 {
299 .ident = "FL92/JFL92", 299 .ident = "FL92/JFL92",
300 .matches = { 300 .matches = {
301 DMI_MATCH(DMI_BOARD_NAME, "JFL92"), 301 DMI_MATCH(DMI_BOARD_NAME, "JFL92"),
302 DMI_MATCH(DMI_BOARD_VERSION, "IFT00"), 302 DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
303 }, 303 },
304 .callback = dmi_check_cb 304 .callback = dmi_check_cb
305 }, 305 },
306 { 306 {
307 .ident = "FT00/IFT00", 307 .ident = "FT00/IFT00",
308 .matches = { 308 .matches = {
309 DMI_MATCH(DMI_BOARD_NAME, "IFT00"), 309 DMI_MATCH(DMI_BOARD_NAME, "IFT00"),
310 DMI_MATCH(DMI_BOARD_VERSION, "IFT00"), 310 DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
311 }, 311 },
312 .callback = dmi_check_cb 312 .callback = dmi_check_cb
313 }, 313 },
314 { } 314 { }
315 }; 315 };
316 316
317 static int __init compal_init(void) 317 static int __init compal_init(void)
318 { 318 {
319 int ret; 319 int ret;
320 320
321 if (acpi_disabled) 321 if (acpi_disabled)
322 return -ENODEV; 322 return -ENODEV;
323 323
324 if (!force && !dmi_check_system(compal_dmi_table)) 324 if (!force && !dmi_check_system(compal_dmi_table))
325 return -ENODEV; 325 return -ENODEV;
326 326
327 /* Register backlight stuff */ 327 /* Register backlight stuff */
328 328
329 compalbl_device = backlight_device_register("compal-laptop", NULL, NULL, 329 if (!acpi_video_backlight_support()) {
330 &compalbl_ops); 330 compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
331 if (IS_ERR(compalbl_device)) 331 &compalbl_ops);
332 return PTR_ERR(compalbl_device); 332 if (IS_ERR(compalbl_device))
333 return PTR_ERR(compalbl_device);
333 334
334 compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1; 335 compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
336 }
335 337
336 ret = platform_driver_register(&compal_driver); 338 ret = platform_driver_register(&compal_driver);
337 if (ret) 339 if (ret)
338 goto fail_backlight; 340 goto fail_backlight;
339 341
340 /* Register platform stuff */ 342 /* Register platform stuff */
341 343
342 compal_device = platform_device_alloc("compal-laptop", -1); 344 compal_device = platform_device_alloc("compal-laptop", -1);
343 if (!compal_device) { 345 if (!compal_device) {
344 ret = -ENOMEM; 346 ret = -ENOMEM;
345 goto fail_platform_driver; 347 goto fail_platform_driver;
346 } 348 }
347 349
348 ret = platform_device_add(compal_device); 350 ret = platform_device_add(compal_device);
349 if (ret) 351 if (ret)
350 goto fail_platform_device1; 352 goto fail_platform_device1;
351 353
352 ret = sysfs_create_group(&compal_device->dev.kobj, 354 ret = sysfs_create_group(&compal_device->dev.kobj,
353 &compal_attribute_group); 355 &compal_attribute_group);
354 if (ret) 356 if (ret)
355 goto fail_platform_device2; 357 goto fail_platform_device2;
356 358
357 printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION 359 printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION
358 " successfully loaded.\n"); 360 " successfully loaded.\n");
359 361
360 return 0; 362 return 0;
361 363
362 fail_platform_device2: 364 fail_platform_device2:
363 365
364 platform_device_del(compal_device); 366 platform_device_del(compal_device);
365 367
366 fail_platform_device1: 368 fail_platform_device1:
367 369
368 platform_device_put(compal_device); 370 platform_device_put(compal_device);
369 371
370 fail_platform_driver: 372 fail_platform_driver:
371 373
372 platform_driver_unregister(&compal_driver); 374 platform_driver_unregister(&compal_driver);
373 375
374 fail_backlight: 376 fail_backlight:
375 377
376 backlight_device_unregister(compalbl_device); 378 backlight_device_unregister(compalbl_device);
377 379
378 return ret; 380 return ret;
379 } 381 }
380 382
381 static void __exit compal_cleanup(void) 383 static void __exit compal_cleanup(void)
382 { 384 {
383 385
384 sysfs_remove_group(&compal_device->dev.kobj, &compal_attribute_group); 386 sysfs_remove_group(&compal_device->dev.kobj, &compal_attribute_group);
385 platform_device_unregister(compal_device); 387 platform_device_unregister(compal_device);
386 platform_driver_unregister(&compal_driver); 388 platform_driver_unregister(&compal_driver);
387 backlight_device_unregister(compalbl_device); 389 backlight_device_unregister(compalbl_device);
388 390
389 printk(KERN_INFO "compal-laptop: driver unloaded.\n"); 391 printk(KERN_INFO "compal-laptop: driver unloaded.\n");
390 } 392 }
391 393
392 module_init(compal_init); 394 module_init(compal_init);
393 module_exit(compal_cleanup); 395 module_exit(compal_cleanup);
394 396
395 MODULE_AUTHOR("Cezary Jackiewicz"); 397 MODULE_AUTHOR("Cezary Jackiewicz");
396 MODULE_DESCRIPTION("Compal Laptop Support"); 398 MODULE_DESCRIPTION("Compal Laptop Support");
397 MODULE_VERSION(COMPAL_DRIVER_VERSION); 399 MODULE_VERSION(COMPAL_DRIVER_VERSION);
398 MODULE_LICENSE("GPL"); 400 MODULE_LICENSE("GPL");
399 401
400 MODULE_ALIAS("dmi:*:rnIFL90:rvrIFT00:*"); 402 MODULE_ALIAS("dmi:*:rnIFL90:rvrIFT00:*");
401 MODULE_ALIAS("dmi:*:rnIFL90:rvrREFERENCE:*"); 403 MODULE_ALIAS("dmi:*:rnIFL90:rvrREFERENCE:*");
402 MODULE_ALIAS("dmi:*:rnIFL91:rvrIFT00:*"); 404 MODULE_ALIAS("dmi:*:rnIFL91:rvrIFT00:*");
403 MODULE_ALIAS("dmi:*:rnJFL92:rvrIFT00:*"); 405 MODULE_ALIAS("dmi:*:rnJFL92:rvrIFT00:*");
404 MODULE_ALIAS("dmi:*:rnIFT00:rvrIFT00:*"); 406 MODULE_ALIAS("dmi:*:rnIFT00:rvrIFT00:*");
405 407
drivers/misc/eeepc-laptop.c
1 /* 1 /*
2 * eepc-laptop.c - Asus Eee PC extras 2 * eepc-laptop.c - Asus Eee PC extras
3 * 3 *
4 * Based on asus_acpi.c as patched for the Eee PC by Asus: 4 * Based on asus_acpi.c as patched for the Eee PC by Asus:
5 * ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar 5 * ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
6 * Based on eee.c from eeepc-linux 6 * Based on eee.c from eeepc-linux
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 */ 17 */
18 18
19 #include <linux/kernel.h> 19 #include <linux/kernel.h>
20 #include <linux/module.h> 20 #include <linux/module.h>
21 #include <linux/init.h> 21 #include <linux/init.h>
22 #include <linux/types.h> 22 #include <linux/types.h>
23 #include <linux/platform_device.h> 23 #include <linux/platform_device.h>
24 #include <linux/backlight.h> 24 #include <linux/backlight.h>
25 #include <linux/fb.h> 25 #include <linux/fb.h>
26 #include <linux/hwmon.h> 26 #include <linux/hwmon.h>
27 #include <linux/hwmon-sysfs.h> 27 #include <linux/hwmon-sysfs.h>
28 #include <acpi/acpi_drivers.h> 28 #include <acpi/acpi_drivers.h>
29 #include <acpi/acpi_bus.h> 29 #include <acpi/acpi_bus.h>
30 #include <linux/uaccess.h> 30 #include <linux/uaccess.h>
31 #include <linux/input.h> 31 #include <linux/input.h>
32 #include <linux/rfkill.h> 32 #include <linux/rfkill.h>
33 33
34 #define EEEPC_LAPTOP_VERSION "0.1" 34 #define EEEPC_LAPTOP_VERSION "0.1"
35 35
36 #define EEEPC_HOTK_NAME "Eee PC Hotkey Driver" 36 #define EEEPC_HOTK_NAME "Eee PC Hotkey Driver"
37 #define EEEPC_HOTK_FILE "eeepc" 37 #define EEEPC_HOTK_FILE "eeepc"
38 #define EEEPC_HOTK_CLASS "hotkey" 38 #define EEEPC_HOTK_CLASS "hotkey"
39 #define EEEPC_HOTK_DEVICE_NAME "Hotkey" 39 #define EEEPC_HOTK_DEVICE_NAME "Hotkey"
40 #define EEEPC_HOTK_HID "ASUS010" 40 #define EEEPC_HOTK_HID "ASUS010"
41 41
42 #define EEEPC_LOG EEEPC_HOTK_FILE ": " 42 #define EEEPC_LOG EEEPC_HOTK_FILE ": "
43 #define EEEPC_ERR KERN_ERR EEEPC_LOG 43 #define EEEPC_ERR KERN_ERR EEEPC_LOG
44 #define EEEPC_WARNING KERN_WARNING EEEPC_LOG 44 #define EEEPC_WARNING KERN_WARNING EEEPC_LOG
45 #define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG 45 #define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG
46 #define EEEPC_INFO KERN_INFO EEEPC_LOG 46 #define EEEPC_INFO KERN_INFO EEEPC_LOG
47 47
48 /* 48 /*
49 * Definitions for Asus EeePC 49 * Definitions for Asus EeePC
50 */ 50 */
51 #define NOTIFY_WLAN_ON 0x10 51 #define NOTIFY_WLAN_ON 0x10
52 #define NOTIFY_BRN_MIN 0x20 52 #define NOTIFY_BRN_MIN 0x20
53 #define NOTIFY_BRN_MAX 0x2f 53 #define NOTIFY_BRN_MAX 0x2f
54 54
55 enum { 55 enum {
56 DISABLE_ASL_WLAN = 0x0001, 56 DISABLE_ASL_WLAN = 0x0001,
57 DISABLE_ASL_BLUETOOTH = 0x0002, 57 DISABLE_ASL_BLUETOOTH = 0x0002,
58 DISABLE_ASL_IRDA = 0x0004, 58 DISABLE_ASL_IRDA = 0x0004,
59 DISABLE_ASL_CAMERA = 0x0008, 59 DISABLE_ASL_CAMERA = 0x0008,
60 DISABLE_ASL_TV = 0x0010, 60 DISABLE_ASL_TV = 0x0010,
61 DISABLE_ASL_GPS = 0x0020, 61 DISABLE_ASL_GPS = 0x0020,
62 DISABLE_ASL_DISPLAYSWITCH = 0x0040, 62 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
63 DISABLE_ASL_MODEM = 0x0080, 63 DISABLE_ASL_MODEM = 0x0080,
64 DISABLE_ASL_CARDREADER = 0x0100 64 DISABLE_ASL_CARDREADER = 0x0100
65 }; 65 };
66 66
67 enum { 67 enum {
68 CM_ASL_WLAN = 0, 68 CM_ASL_WLAN = 0,
69 CM_ASL_BLUETOOTH, 69 CM_ASL_BLUETOOTH,
70 CM_ASL_IRDA, 70 CM_ASL_IRDA,
71 CM_ASL_1394, 71 CM_ASL_1394,
72 CM_ASL_CAMERA, 72 CM_ASL_CAMERA,
73 CM_ASL_TV, 73 CM_ASL_TV,
74 CM_ASL_GPS, 74 CM_ASL_GPS,
75 CM_ASL_DVDROM, 75 CM_ASL_DVDROM,
76 CM_ASL_DISPLAYSWITCH, 76 CM_ASL_DISPLAYSWITCH,
77 CM_ASL_PANELBRIGHT, 77 CM_ASL_PANELBRIGHT,
78 CM_ASL_BIOSFLASH, 78 CM_ASL_BIOSFLASH,
79 CM_ASL_ACPIFLASH, 79 CM_ASL_ACPIFLASH,
80 CM_ASL_CPUFV, 80 CM_ASL_CPUFV,
81 CM_ASL_CPUTEMPERATURE, 81 CM_ASL_CPUTEMPERATURE,
82 CM_ASL_FANCPU, 82 CM_ASL_FANCPU,
83 CM_ASL_FANCHASSIS, 83 CM_ASL_FANCHASSIS,
84 CM_ASL_USBPORT1, 84 CM_ASL_USBPORT1,
85 CM_ASL_USBPORT2, 85 CM_ASL_USBPORT2,
86 CM_ASL_USBPORT3, 86 CM_ASL_USBPORT3,
87 CM_ASL_MODEM, 87 CM_ASL_MODEM,
88 CM_ASL_CARDREADER, 88 CM_ASL_CARDREADER,
89 CM_ASL_LID 89 CM_ASL_LID
90 }; 90 };
91 91
92 static const char *cm_getv[] = { 92 static const char *cm_getv[] = {
93 "WLDG", NULL, NULL, NULL, 93 "WLDG", NULL, NULL, NULL,
94 "CAMG", NULL, NULL, NULL, 94 "CAMG", NULL, NULL, NULL,
95 NULL, "PBLG", NULL, NULL, 95 NULL, "PBLG", NULL, NULL,
96 "CFVG", NULL, NULL, NULL, 96 "CFVG", NULL, NULL, NULL,
97 "USBG", NULL, NULL, "MODG", 97 "USBG", NULL, NULL, "MODG",
98 "CRDG", "LIDG" 98 "CRDG", "LIDG"
99 }; 99 };
100 100
101 static const char *cm_setv[] = { 101 static const char *cm_setv[] = {
102 "WLDS", NULL, NULL, NULL, 102 "WLDS", NULL, NULL, NULL,
103 "CAMS", NULL, NULL, NULL, 103 "CAMS", NULL, NULL, NULL,
104 "SDSP", "PBLS", "HDPS", NULL, 104 "SDSP", "PBLS", "HDPS", NULL,
105 "CFVS", NULL, NULL, NULL, 105 "CFVS", NULL, NULL, NULL,
106 "USBG", NULL, NULL, "MODS", 106 "USBG", NULL, NULL, "MODS",
107 "CRDS", NULL 107 "CRDS", NULL
108 }; 108 };
109 109
110 #define EEEPC_EC "\\_SB.PCI0.SBRG.EC0." 110 #define EEEPC_EC "\\_SB.PCI0.SBRG.EC0."
111 111
112 #define EEEPC_EC_FAN_PWM EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */ 112 #define EEEPC_EC_FAN_PWM EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */
113 #define EEEPC_EC_SC02 0x63 113 #define EEEPC_EC_SC02 0x63
114 #define EEEPC_EC_FAN_HRPM EEEPC_EC "SC05" /* High byte, fan speed (RPM) */ 114 #define EEEPC_EC_FAN_HRPM EEEPC_EC "SC05" /* High byte, fan speed (RPM) */
115 #define EEEPC_EC_FAN_LRPM EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */ 115 #define EEEPC_EC_FAN_LRPM EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */
116 #define EEEPC_EC_FAN_CTRL EEEPC_EC "SFB3" /* Byte containing SF25 */ 116 #define EEEPC_EC_FAN_CTRL EEEPC_EC "SFB3" /* Byte containing SF25 */
117 #define EEEPC_EC_SFB3 0xD3 117 #define EEEPC_EC_SFB3 0xD3
118 118
119 /* 119 /*
120 * This is the main structure, we can use it to store useful information 120 * This is the main structure, we can use it to store useful information
121 * about the hotk device 121 * about the hotk device
122 */ 122 */
123 struct eeepc_hotk { 123 struct eeepc_hotk {
124 struct acpi_device *device; /* the device we are in */ 124 struct acpi_device *device; /* the device we are in */
125 acpi_handle handle; /* the handle of the hotk device */ 125 acpi_handle handle; /* the handle of the hotk device */
126 u32 cm_supported; /* the control methods supported 126 u32 cm_supported; /* the control methods supported
127 by this BIOS */ 127 by this BIOS */
128 uint init_flag; /* Init flags */ 128 uint init_flag; /* Init flags */
129 u16 event_count[128]; /* count for each event */ 129 u16 event_count[128]; /* count for each event */
130 struct input_dev *inputdev; 130 struct input_dev *inputdev;
131 u16 *keycode_map; 131 u16 *keycode_map;
132 struct rfkill *eeepc_wlan_rfkill; 132 struct rfkill *eeepc_wlan_rfkill;
133 struct rfkill *eeepc_bluetooth_rfkill; 133 struct rfkill *eeepc_bluetooth_rfkill;
134 }; 134 };
135 135
136 /* The actual device the driver binds to */ 136 /* The actual device the driver binds to */
137 static struct eeepc_hotk *ehotk; 137 static struct eeepc_hotk *ehotk;
138 138
139 /* Platform device/driver */ 139 /* Platform device/driver */
140 static struct platform_driver platform_driver = { 140 static struct platform_driver platform_driver = {
141 .driver = { 141 .driver = {
142 .name = EEEPC_HOTK_FILE, 142 .name = EEEPC_HOTK_FILE,
143 .owner = THIS_MODULE, 143 .owner = THIS_MODULE,
144 } 144 }
145 }; 145 };
146 146
147 static struct platform_device *platform_device; 147 static struct platform_device *platform_device;
148 148
149 struct key_entry { 149 struct key_entry {
150 char type; 150 char type;
151 u8 code; 151 u8 code;
152 u16 keycode; 152 u16 keycode;
153 }; 153 };
154 154
155 enum { KE_KEY, KE_END }; 155 enum { KE_KEY, KE_END };
156 156
157 static struct key_entry eeepc_keymap[] = { 157 static struct key_entry eeepc_keymap[] = {
158 /* Sleep already handled via generic ACPI code */ 158 /* Sleep already handled via generic ACPI code */
159 {KE_KEY, 0x10, KEY_WLAN }, 159 {KE_KEY, 0x10, KEY_WLAN },
160 {KE_KEY, 0x12, KEY_PROG1 }, 160 {KE_KEY, 0x12, KEY_PROG1 },
161 {KE_KEY, 0x13, KEY_MUTE }, 161 {KE_KEY, 0x13, KEY_MUTE },
162 {KE_KEY, 0x14, KEY_VOLUMEDOWN }, 162 {KE_KEY, 0x14, KEY_VOLUMEDOWN },
163 {KE_KEY, 0x15, KEY_VOLUMEUP }, 163 {KE_KEY, 0x15, KEY_VOLUMEUP },
164 {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, 164 {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
165 {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, 165 {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
166 {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, 166 {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
167 {KE_END, 0}, 167 {KE_END, 0},
168 }; 168 };
169 169
170 /* 170 /*
171 * The hotkey driver declaration 171 * The hotkey driver declaration
172 */ 172 */
173 static int eeepc_hotk_add(struct acpi_device *device); 173 static int eeepc_hotk_add(struct acpi_device *device);
174 static int eeepc_hotk_remove(struct acpi_device *device, int type); 174 static int eeepc_hotk_remove(struct acpi_device *device, int type);
175 175
176 static const struct acpi_device_id eeepc_device_ids[] = { 176 static const struct acpi_device_id eeepc_device_ids[] = {
177 {EEEPC_HOTK_HID, 0}, 177 {EEEPC_HOTK_HID, 0},
178 {"", 0}, 178 {"", 0},
179 }; 179 };
180 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids); 180 MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
181 181
182 static struct acpi_driver eeepc_hotk_driver = { 182 static struct acpi_driver eeepc_hotk_driver = {
183 .name = EEEPC_HOTK_NAME, 183 .name = EEEPC_HOTK_NAME,
184 .class = EEEPC_HOTK_CLASS, 184 .class = EEEPC_HOTK_CLASS,
185 .ids = eeepc_device_ids, 185 .ids = eeepc_device_ids,
186 .ops = { 186 .ops = {
187 .add = eeepc_hotk_add, 187 .add = eeepc_hotk_add,
188 .remove = eeepc_hotk_remove, 188 .remove = eeepc_hotk_remove,
189 }, 189 },
190 }; 190 };
191 191
192 /* The backlight device /sys/class/backlight */ 192 /* The backlight device /sys/class/backlight */
193 static struct backlight_device *eeepc_backlight_device; 193 static struct backlight_device *eeepc_backlight_device;
194 194
195 /* The hwmon device */ 195 /* The hwmon device */
196 static struct device *eeepc_hwmon_device; 196 static struct device *eeepc_hwmon_device;
197 197
198 /* 198 /*
199 * The backlight class declaration 199 * The backlight class declaration
200 */ 200 */
201 static int read_brightness(struct backlight_device *bd); 201 static int read_brightness(struct backlight_device *bd);
202 static int update_bl_status(struct backlight_device *bd); 202 static int update_bl_status(struct backlight_device *bd);
203 static struct backlight_ops eeepcbl_ops = { 203 static struct backlight_ops eeepcbl_ops = {
204 .get_brightness = read_brightness, 204 .get_brightness = read_brightness,
205 .update_status = update_bl_status, 205 .update_status = update_bl_status,
206 }; 206 };
207 207
208 MODULE_AUTHOR("Corentin Chary, Eric Cooper"); 208 MODULE_AUTHOR("Corentin Chary, Eric Cooper");
209 MODULE_DESCRIPTION(EEEPC_HOTK_NAME); 209 MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
210 MODULE_LICENSE("GPL"); 210 MODULE_LICENSE("GPL");
211 211
212 /* 212 /*
213 * ACPI Helpers 213 * ACPI Helpers
214 */ 214 */
215 static int write_acpi_int(acpi_handle handle, const char *method, int val, 215 static int write_acpi_int(acpi_handle handle, const char *method, int val,
216 struct acpi_buffer *output) 216 struct acpi_buffer *output)
217 { 217 {
218 struct acpi_object_list params; 218 struct acpi_object_list params;
219 union acpi_object in_obj; 219 union acpi_object in_obj;
220 acpi_status status; 220 acpi_status status;
221 221
222 params.count = 1; 222 params.count = 1;
223 params.pointer = &in_obj; 223 params.pointer = &in_obj;
224 in_obj.type = ACPI_TYPE_INTEGER; 224 in_obj.type = ACPI_TYPE_INTEGER;
225 in_obj.integer.value = val; 225 in_obj.integer.value = val;
226 226
227 status = acpi_evaluate_object(handle, (char *)method, &params, output); 227 status = acpi_evaluate_object(handle, (char *)method, &params, output);
228 return (status == AE_OK ? 0 : -1); 228 return (status == AE_OK ? 0 : -1);
229 } 229 }
230 230
231 static int read_acpi_int(acpi_handle handle, const char *method, int *val) 231 static int read_acpi_int(acpi_handle handle, const char *method, int *val)
232 { 232 {
233 acpi_status status; 233 acpi_status status;
234 unsigned long long result; 234 unsigned long long result;
235 235
236 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result); 236 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
237 if (ACPI_FAILURE(status)) { 237 if (ACPI_FAILURE(status)) {
238 *val = -1; 238 *val = -1;
239 return -1; 239 return -1;
240 } else { 240 } else {
241 *val = result; 241 *val = result;
242 return 0; 242 return 0;
243 } 243 }
244 } 244 }
245 245
246 static int set_acpi(int cm, int value) 246 static int set_acpi(int cm, int value)
247 { 247 {
248 if (ehotk->cm_supported & (0x1 << cm)) { 248 if (ehotk->cm_supported & (0x1 << cm)) {
249 const char *method = cm_setv[cm]; 249 const char *method = cm_setv[cm];
250 if (method == NULL) 250 if (method == NULL)
251 return -ENODEV; 251 return -ENODEV;
252 if (write_acpi_int(ehotk->handle, method, value, NULL)) 252 if (write_acpi_int(ehotk->handle, method, value, NULL))
253 printk(EEEPC_WARNING "Error writing %s\n", method); 253 printk(EEEPC_WARNING "Error writing %s\n", method);
254 } 254 }
255 return 0; 255 return 0;
256 } 256 }
257 257
258 static int get_acpi(int cm) 258 static int get_acpi(int cm)
259 { 259 {
260 int value = -1; 260 int value = -1;
261 if ((ehotk->cm_supported & (0x1 << cm))) { 261 if ((ehotk->cm_supported & (0x1 << cm))) {
262 const char *method = cm_getv[cm]; 262 const char *method = cm_getv[cm];
263 if (method == NULL) 263 if (method == NULL)
264 return -ENODEV; 264 return -ENODEV;
265 if (read_acpi_int(ehotk->handle, method, &value)) 265 if (read_acpi_int(ehotk->handle, method, &value))
266 printk(EEEPC_WARNING "Error reading %s\n", method); 266 printk(EEEPC_WARNING "Error reading %s\n", method);
267 } 267 }
268 return value; 268 return value;
269 } 269 }
270 270
271 /* 271 /*
272 * Backlight 272 * Backlight
273 */ 273 */
274 static int read_brightness(struct backlight_device *bd) 274 static int read_brightness(struct backlight_device *bd)
275 { 275 {
276 return get_acpi(CM_ASL_PANELBRIGHT); 276 return get_acpi(CM_ASL_PANELBRIGHT);
277 } 277 }
278 278
279 static int set_brightness(struct backlight_device *bd, int value) 279 static int set_brightness(struct backlight_device *bd, int value)
280 { 280 {
281 value = max(0, min(15, value)); 281 value = max(0, min(15, value));
282 return set_acpi(CM_ASL_PANELBRIGHT, value); 282 return set_acpi(CM_ASL_PANELBRIGHT, value);
283 } 283 }
284 284
285 static int update_bl_status(struct backlight_device *bd) 285 static int update_bl_status(struct backlight_device *bd)
286 { 286 {
287 return set_brightness(bd, bd->props.brightness); 287 return set_brightness(bd, bd->props.brightness);
288 } 288 }
289 289
290 /* 290 /*
291 * Rfkill helpers 291 * Rfkill helpers
292 */ 292 */
293 293
294 static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state) 294 static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state)
295 { 295 {
296 if (state == RFKILL_STATE_SOFT_BLOCKED) 296 if (state == RFKILL_STATE_SOFT_BLOCKED)
297 return set_acpi(CM_ASL_WLAN, 0); 297 return set_acpi(CM_ASL_WLAN, 0);
298 else 298 else
299 return set_acpi(CM_ASL_WLAN, 1); 299 return set_acpi(CM_ASL_WLAN, 1);
300 } 300 }
301 301
302 static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state) 302 static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state)
303 { 303 {
304 if (get_acpi(CM_ASL_WLAN) == 1) 304 if (get_acpi(CM_ASL_WLAN) == 1)
305 *state = RFKILL_STATE_UNBLOCKED; 305 *state = RFKILL_STATE_UNBLOCKED;
306 else 306 else
307 *state = RFKILL_STATE_SOFT_BLOCKED; 307 *state = RFKILL_STATE_SOFT_BLOCKED;
308 return 0; 308 return 0;
309 } 309 }
310 310
311 static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state) 311 static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state)
312 { 312 {
313 if (state == RFKILL_STATE_SOFT_BLOCKED) 313 if (state == RFKILL_STATE_SOFT_BLOCKED)
314 return set_acpi(CM_ASL_BLUETOOTH, 0); 314 return set_acpi(CM_ASL_BLUETOOTH, 0);
315 else 315 else
316 return set_acpi(CM_ASL_BLUETOOTH, 1); 316 return set_acpi(CM_ASL_BLUETOOTH, 1);
317 } 317 }
318 318
319 static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state) 319 static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state)
320 { 320 {
321 if (get_acpi(CM_ASL_BLUETOOTH) == 1) 321 if (get_acpi(CM_ASL_BLUETOOTH) == 1)
322 *state = RFKILL_STATE_UNBLOCKED; 322 *state = RFKILL_STATE_UNBLOCKED;
323 else 323 else
324 *state = RFKILL_STATE_SOFT_BLOCKED; 324 *state = RFKILL_STATE_SOFT_BLOCKED;
325 return 0; 325 return 0;
326 } 326 }
327 327
328 /* 328 /*
329 * Sys helpers 329 * Sys helpers
330 */ 330 */
331 static int parse_arg(const char *buf, unsigned long count, int *val) 331 static int parse_arg(const char *buf, unsigned long count, int *val)
332 { 332 {
333 if (!count) 333 if (!count)
334 return 0; 334 return 0;
335 if (sscanf(buf, "%i", val) != 1) 335 if (sscanf(buf, "%i", val) != 1)
336 return -EINVAL; 336 return -EINVAL;
337 return count; 337 return count;
338 } 338 }
339 339
340 static ssize_t store_sys_acpi(int cm, const char *buf, size_t count) 340 static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
341 { 341 {
342 int rv, value; 342 int rv, value;
343 343
344 rv = parse_arg(buf, count, &value); 344 rv = parse_arg(buf, count, &value);
345 if (rv > 0) 345 if (rv > 0)
346 set_acpi(cm, value); 346 set_acpi(cm, value);
347 return rv; 347 return rv;
348 } 348 }
349 349
350 static ssize_t show_sys_acpi(int cm, char *buf) 350 static ssize_t show_sys_acpi(int cm, char *buf)
351 { 351 {
352 return sprintf(buf, "%d\n", get_acpi(cm)); 352 return sprintf(buf, "%d\n", get_acpi(cm));
353 } 353 }
354 354
355 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ 355 #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
356 static ssize_t show_##_name(struct device *dev, \ 356 static ssize_t show_##_name(struct device *dev, \
357 struct device_attribute *attr, \ 357 struct device_attribute *attr, \
358 char *buf) \ 358 char *buf) \
359 { \ 359 { \
360 return show_sys_acpi(_cm, buf); \ 360 return show_sys_acpi(_cm, buf); \
361 } \ 361 } \
362 static ssize_t store_##_name(struct device *dev, \ 362 static ssize_t store_##_name(struct device *dev, \
363 struct device_attribute *attr, \ 363 struct device_attribute *attr, \
364 const char *buf, size_t count) \ 364 const char *buf, size_t count) \
365 { \ 365 { \
366 return store_sys_acpi(_cm, buf, count); \ 366 return store_sys_acpi(_cm, buf, count); \
367 } \ 367 } \
368 static struct device_attribute dev_attr_##_name = { \ 368 static struct device_attribute dev_attr_##_name = { \
369 .attr = { \ 369 .attr = { \
370 .name = __stringify(_name), \ 370 .name = __stringify(_name), \
371 .mode = 0644 }, \ 371 .mode = 0644 }, \
372 .show = show_##_name, \ 372 .show = show_##_name, \
373 .store = store_##_name, \ 373 .store = store_##_name, \
374 } 374 }
375 375
376 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); 376 EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
377 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); 377 EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
378 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); 378 EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
379 379
380 static struct attribute *platform_attributes[] = { 380 static struct attribute *platform_attributes[] = {
381 &dev_attr_camera.attr, 381 &dev_attr_camera.attr,
382 &dev_attr_cardr.attr, 382 &dev_attr_cardr.attr,
383 &dev_attr_disp.attr, 383 &dev_attr_disp.attr,
384 NULL 384 NULL
385 }; 385 };
386 386
387 static struct attribute_group platform_attribute_group = { 387 static struct attribute_group platform_attribute_group = {
388 .attrs = platform_attributes 388 .attrs = platform_attributes
389 }; 389 };
390 390
391 /* 391 /*
392 * Hotkey functions 392 * Hotkey functions
393 */ 393 */
394 static struct key_entry *eepc_get_entry_by_scancode(int code) 394 static struct key_entry *eepc_get_entry_by_scancode(int code)
395 { 395 {
396 struct key_entry *key; 396 struct key_entry *key;
397 397
398 for (key = eeepc_keymap; key->type != KE_END; key++) 398 for (key = eeepc_keymap; key->type != KE_END; key++)
399 if (code == key->code) 399 if (code == key->code)
400 return key; 400 return key;
401 401
402 return NULL; 402 return NULL;
403 } 403 }
404 404
405 static struct key_entry *eepc_get_entry_by_keycode(int code) 405 static struct key_entry *eepc_get_entry_by_keycode(int code)
406 { 406 {
407 struct key_entry *key; 407 struct key_entry *key;
408 408
409 for (key = eeepc_keymap; key->type != KE_END; key++) 409 for (key = eeepc_keymap; key->type != KE_END; key++)
410 if (code == key->keycode && key->type == KE_KEY) 410 if (code == key->keycode && key->type == KE_KEY)
411 return key; 411 return key;
412 412
413 return NULL; 413 return NULL;
414 } 414 }
415 415
416 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode) 416 static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
417 { 417 {
418 struct key_entry *key = eepc_get_entry_by_scancode(scancode); 418 struct key_entry *key = eepc_get_entry_by_scancode(scancode);
419 419
420 if (key && key->type == KE_KEY) { 420 if (key && key->type == KE_KEY) {
421 *keycode = key->keycode; 421 *keycode = key->keycode;
422 return 0; 422 return 0;
423 } 423 }
424 424
425 return -EINVAL; 425 return -EINVAL;
426 } 426 }
427 427
428 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) 428 static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
429 { 429 {
430 struct key_entry *key; 430 struct key_entry *key;
431 int old_keycode; 431 int old_keycode;
432 432
433 if (keycode < 0 || keycode > KEY_MAX) 433 if (keycode < 0 || keycode > KEY_MAX)
434 return -EINVAL; 434 return -EINVAL;
435 435
436 key = eepc_get_entry_by_scancode(scancode); 436 key = eepc_get_entry_by_scancode(scancode);
437 if (key && key->type == KE_KEY) { 437 if (key && key->type == KE_KEY) {
438 old_keycode = key->keycode; 438 old_keycode = key->keycode;
439 key->keycode = keycode; 439 key->keycode = keycode;
440 set_bit(keycode, dev->keybit); 440 set_bit(keycode, dev->keybit);
441 if (!eepc_get_entry_by_keycode(old_keycode)) 441 if (!eepc_get_entry_by_keycode(old_keycode))
442 clear_bit(old_keycode, dev->keybit); 442 clear_bit(old_keycode, dev->keybit);
443 return 0; 443 return 0;
444 } 444 }
445 445
446 return -EINVAL; 446 return -EINVAL;
447 } 447 }
448 448
449 static int eeepc_hotk_check(void) 449 static int eeepc_hotk_check(void)
450 { 450 {
451 const struct key_entry *key; 451 const struct key_entry *key;
452 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 452 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
453 int result; 453 int result;
454 454
455 result = acpi_bus_get_status(ehotk->device); 455 result = acpi_bus_get_status(ehotk->device);
456 if (result) 456 if (result)
457 return result; 457 return result;
458 if (ehotk->device->status.present) { 458 if (ehotk->device->status.present) {
459 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, 459 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
460 &buffer)) { 460 &buffer)) {
461 printk(EEEPC_ERR "Hotkey initialization failed\n"); 461 printk(EEEPC_ERR "Hotkey initialization failed\n");
462 return -ENODEV; 462 return -ENODEV;
463 } else { 463 } else {
464 printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n", 464 printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n",
465 ehotk->init_flag); 465 ehotk->init_flag);
466 } 466 }
467 /* get control methods supported */ 467 /* get control methods supported */
468 if (read_acpi_int(ehotk->handle, "CMSG" 468 if (read_acpi_int(ehotk->handle, "CMSG"
469 , &ehotk->cm_supported)) { 469 , &ehotk->cm_supported)) {
470 printk(EEEPC_ERR 470 printk(EEEPC_ERR
471 "Get control methods supported failed\n"); 471 "Get control methods supported failed\n");
472 return -ENODEV; 472 return -ENODEV;
473 } else { 473 } else {
474 printk(EEEPC_INFO 474 printk(EEEPC_INFO
475 "Get control methods supported: 0x%x\n", 475 "Get control methods supported: 0x%x\n",
476 ehotk->cm_supported); 476 ehotk->cm_supported);
477 } 477 }
478 ehotk->inputdev = input_allocate_device(); 478 ehotk->inputdev = input_allocate_device();
479 if (!ehotk->inputdev) { 479 if (!ehotk->inputdev) {
480 printk(EEEPC_INFO "Unable to allocate input device\n"); 480 printk(EEEPC_INFO "Unable to allocate input device\n");
481 return 0; 481 return 0;
482 } 482 }
483 ehotk->inputdev->name = "Asus EeePC extra buttons"; 483 ehotk->inputdev->name = "Asus EeePC extra buttons";
484 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0"; 484 ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0";
485 ehotk->inputdev->id.bustype = BUS_HOST; 485 ehotk->inputdev->id.bustype = BUS_HOST;
486 ehotk->inputdev->getkeycode = eeepc_getkeycode; 486 ehotk->inputdev->getkeycode = eeepc_getkeycode;
487 ehotk->inputdev->setkeycode = eeepc_setkeycode; 487 ehotk->inputdev->setkeycode = eeepc_setkeycode;
488 488
489 for (key = eeepc_keymap; key->type != KE_END; key++) { 489 for (key = eeepc_keymap; key->type != KE_END; key++) {
490 switch (key->type) { 490 switch (key->type) {
491 case KE_KEY: 491 case KE_KEY:
492 set_bit(EV_KEY, ehotk->inputdev->evbit); 492 set_bit(EV_KEY, ehotk->inputdev->evbit);
493 set_bit(key->keycode, ehotk->inputdev->keybit); 493 set_bit(key->keycode, ehotk->inputdev->keybit);
494 break; 494 break;
495 } 495 }
496 } 496 }
497 result = input_register_device(ehotk->inputdev); 497 result = input_register_device(ehotk->inputdev);
498 if (result) { 498 if (result) {
499 printk(EEEPC_INFO "Unable to register input device\n"); 499 printk(EEEPC_INFO "Unable to register input device\n");
500 input_free_device(ehotk->inputdev); 500 input_free_device(ehotk->inputdev);
501 return 0; 501 return 0;
502 } 502 }
503 } else { 503 } else {
504 printk(EEEPC_ERR "Hotkey device not present, aborting\n"); 504 printk(EEEPC_ERR "Hotkey device not present, aborting\n");
505 return -EINVAL; 505 return -EINVAL;
506 } 506 }
507 return 0; 507 return 0;
508 } 508 }
509 509
510 static void notify_brn(void) 510 static void notify_brn(void)
511 { 511 {
512 struct backlight_device *bd = eeepc_backlight_device; 512 struct backlight_device *bd = eeepc_backlight_device;
513 bd->props.brightness = read_brightness(bd); 513 bd->props.brightness = read_brightness(bd);
514 } 514 }
515 515
516 static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) 516 static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
517 { 517 {
518 static struct key_entry *key; 518 static struct key_entry *key;
519 if (!ehotk) 519 if (!ehotk)
520 return; 520 return;
521 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) 521 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
522 notify_brn(); 522 notify_brn();
523 acpi_bus_generate_proc_event(ehotk->device, event, 523 acpi_bus_generate_proc_event(ehotk->device, event,
524 ehotk->event_count[event % 128]++); 524 ehotk->event_count[event % 128]++);
525 if (ehotk->inputdev) { 525 if (ehotk->inputdev) {
526 key = eepc_get_entry_by_scancode(event); 526 key = eepc_get_entry_by_scancode(event);
527 if (key) { 527 if (key) {
528 switch (key->type) { 528 switch (key->type) {
529 case KE_KEY: 529 case KE_KEY:
530 input_report_key(ehotk->inputdev, key->keycode, 530 input_report_key(ehotk->inputdev, key->keycode,
531 1); 531 1);
532 input_sync(ehotk->inputdev); 532 input_sync(ehotk->inputdev);
533 input_report_key(ehotk->inputdev, key->keycode, 533 input_report_key(ehotk->inputdev, key->keycode,
534 0); 534 0);
535 input_sync(ehotk->inputdev); 535 input_sync(ehotk->inputdev);
536 break; 536 break;
537 } 537 }
538 } 538 }
539 } 539 }
540 } 540 }
541 541
542 static int eeepc_hotk_add(struct acpi_device *device) 542 static int eeepc_hotk_add(struct acpi_device *device)
543 { 543 {
544 acpi_status status = AE_OK; 544 acpi_status status = AE_OK;
545 int result; 545 int result;
546 546
547 if (!device) 547 if (!device)
548 return -EINVAL; 548 return -EINVAL;
549 printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n"); 549 printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n");
550 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); 550 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
551 if (!ehotk) 551 if (!ehotk)
552 return -ENOMEM; 552 return -ENOMEM;
553 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; 553 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
554 ehotk->handle = device->handle; 554 ehotk->handle = device->handle;
555 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME); 555 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
556 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS); 556 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
557 device->driver_data = ehotk; 557 device->driver_data = ehotk;
558 ehotk->device = device; 558 ehotk->device = device;
559 result = eeepc_hotk_check(); 559 result = eeepc_hotk_check();
560 if (result) 560 if (result)
561 goto end; 561 goto end;
562 status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, 562 status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
563 eeepc_hotk_notify, ehotk); 563 eeepc_hotk_notify, ehotk);
564 if (ACPI_FAILURE(status)) 564 if (ACPI_FAILURE(status))
565 printk(EEEPC_ERR "Error installing notify handler\n"); 565 printk(EEEPC_ERR "Error installing notify handler\n");
566 566
567 if (get_acpi(CM_ASL_WLAN) != -1) { 567 if (get_acpi(CM_ASL_WLAN) != -1) {
568 ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, 568 ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev,
569 RFKILL_TYPE_WLAN); 569 RFKILL_TYPE_WLAN);
570 570
571 if (!ehotk->eeepc_wlan_rfkill) 571 if (!ehotk->eeepc_wlan_rfkill)
572 goto end; 572 goto end;
573 573
574 ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; 574 ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
575 ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; 575 ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
576 ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; 576 ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
577 if (get_acpi(CM_ASL_WLAN) == 1) 577 if (get_acpi(CM_ASL_WLAN) == 1)
578 ehotk->eeepc_wlan_rfkill->state = 578 ehotk->eeepc_wlan_rfkill->state =
579 RFKILL_STATE_UNBLOCKED; 579 RFKILL_STATE_UNBLOCKED;
580 else 580 else
581 ehotk->eeepc_wlan_rfkill->state = 581 ehotk->eeepc_wlan_rfkill->state =
582 RFKILL_STATE_SOFT_BLOCKED; 582 RFKILL_STATE_SOFT_BLOCKED;
583 rfkill_register(ehotk->eeepc_wlan_rfkill); 583 rfkill_register(ehotk->eeepc_wlan_rfkill);
584 } 584 }
585 585
586 if (get_acpi(CM_ASL_BLUETOOTH) != -1) { 586 if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
587 ehotk->eeepc_bluetooth_rfkill = 587 ehotk->eeepc_bluetooth_rfkill =
588 rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); 588 rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
589 589
590 if (!ehotk->eeepc_bluetooth_rfkill) 590 if (!ehotk->eeepc_bluetooth_rfkill)
591 goto end; 591 goto end;
592 592
593 ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; 593 ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
594 ehotk->eeepc_bluetooth_rfkill->toggle_radio = 594 ehotk->eeepc_bluetooth_rfkill->toggle_radio =
595 eeepc_bluetooth_rfkill_set; 595 eeepc_bluetooth_rfkill_set;
596 ehotk->eeepc_bluetooth_rfkill->get_state = 596 ehotk->eeepc_bluetooth_rfkill->get_state =
597 eeepc_bluetooth_rfkill_state; 597 eeepc_bluetooth_rfkill_state;
598 if (get_acpi(CM_ASL_BLUETOOTH) == 1) 598 if (get_acpi(CM_ASL_BLUETOOTH) == 1)
599 ehotk->eeepc_bluetooth_rfkill->state = 599 ehotk->eeepc_bluetooth_rfkill->state =
600 RFKILL_STATE_UNBLOCKED; 600 RFKILL_STATE_UNBLOCKED;
601 else 601 else
602 ehotk->eeepc_bluetooth_rfkill->state = 602 ehotk->eeepc_bluetooth_rfkill->state =
603 RFKILL_STATE_SOFT_BLOCKED; 603 RFKILL_STATE_SOFT_BLOCKED;
604 rfkill_register(ehotk->eeepc_bluetooth_rfkill); 604 rfkill_register(ehotk->eeepc_bluetooth_rfkill);
605 } 605 }
606 606
607 end: 607 end:
608 if (result) { 608 if (result) {
609 kfree(ehotk); 609 kfree(ehotk);
610 ehotk = NULL; 610 ehotk = NULL;
611 } 611 }
612 return result; 612 return result;
613 } 613 }
614 614
615 static int eeepc_hotk_remove(struct acpi_device *device, int type) 615 static int eeepc_hotk_remove(struct acpi_device *device, int type)
616 { 616 {
617 acpi_status status = 0; 617 acpi_status status = 0;
618 618
619 if (!device || !acpi_driver_data(device)) 619 if (!device || !acpi_driver_data(device))
620 return -EINVAL; 620 return -EINVAL;
621 status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, 621 status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
622 eeepc_hotk_notify); 622 eeepc_hotk_notify);
623 if (ACPI_FAILURE(status)) 623 if (ACPI_FAILURE(status))
624 printk(EEEPC_ERR "Error removing notify handler\n"); 624 printk(EEEPC_ERR "Error removing notify handler\n");
625 kfree(ehotk); 625 kfree(ehotk);
626 return 0; 626 return 0;
627 } 627 }
628 628
629 /* 629 /*
630 * Hwmon 630 * Hwmon
631 */ 631 */
632 static int eeepc_get_fan_pwm(void) 632 static int eeepc_get_fan_pwm(void)
633 { 633 {
634 int value = 0; 634 int value = 0;
635 635
636 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value); 636 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
637 value = value * 255 / 100; 637 value = value * 255 / 100;
638 return (value); 638 return (value);
639 } 639 }
640 640
641 static void eeepc_set_fan_pwm(int value) 641 static void eeepc_set_fan_pwm(int value)
642 { 642 {
643 value = SENSORS_LIMIT(value, 0, 255); 643 value = SENSORS_LIMIT(value, 0, 255);
644 value = value * 100 / 255; 644 value = value * 100 / 255;
645 ec_write(EEEPC_EC_SC02, value); 645 ec_write(EEEPC_EC_SC02, value);
646 } 646 }
647 647
648 static int eeepc_get_fan_rpm(void) 648 static int eeepc_get_fan_rpm(void)
649 { 649 {
650 int high = 0; 650 int high = 0;
651 int low = 0; 651 int low = 0;
652 652
653 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high); 653 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
654 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low); 654 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
655 return (high << 8 | low); 655 return (high << 8 | low);
656 } 656 }
657 657
658 static int eeepc_get_fan_ctrl(void) 658 static int eeepc_get_fan_ctrl(void)
659 { 659 {
660 int value = 0; 660 int value = 0;
661 661
662 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); 662 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
663 return ((value & 0x02 ? 1 : 0)); 663 return ((value & 0x02 ? 1 : 0));
664 } 664 }
665 665
666 static void eeepc_set_fan_ctrl(int manual) 666 static void eeepc_set_fan_ctrl(int manual)
667 { 667 {
668 int value = 0; 668 int value = 0;
669 669
670 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); 670 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
671 if (manual) 671 if (manual)
672 value |= 0x02; 672 value |= 0x02;
673 else 673 else
674 value &= ~0x02; 674 value &= ~0x02;
675 ec_write(EEEPC_EC_SFB3, value); 675 ec_write(EEEPC_EC_SFB3, value);
676 } 676 }
677 677
678 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count) 678 static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
679 { 679 {
680 int rv, value; 680 int rv, value;
681 681
682 rv = parse_arg(buf, count, &value); 682 rv = parse_arg(buf, count, &value);
683 if (rv > 0) 683 if (rv > 0)
684 set(value); 684 set(value);
685 return rv; 685 return rv;
686 } 686 }
687 687
688 static ssize_t show_sys_hwmon(int (*get)(void), char *buf) 688 static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
689 { 689 {
690 return sprintf(buf, "%d\n", get()); 690 return sprintf(buf, "%d\n", get());
691 } 691 }
692 692
693 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \ 693 #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
694 static ssize_t show_##_name(struct device *dev, \ 694 static ssize_t show_##_name(struct device *dev, \
695 struct device_attribute *attr, \ 695 struct device_attribute *attr, \
696 char *buf) \ 696 char *buf) \
697 { \ 697 { \
698 return show_sys_hwmon(_set, buf); \ 698 return show_sys_hwmon(_set, buf); \
699 } \ 699 } \
700 static ssize_t store_##_name(struct device *dev, \ 700 static ssize_t store_##_name(struct device *dev, \
701 struct device_attribute *attr, \ 701 struct device_attribute *attr, \
702 const char *buf, size_t count) \ 702 const char *buf, size_t count) \
703 { \ 703 { \
704 return store_sys_hwmon(_get, buf, count); \ 704 return store_sys_hwmon(_get, buf, count); \
705 } \ 705 } \
706 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0); 706 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
707 707
708 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL); 708 EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
709 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, 709 EEEPC_CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR,
710 eeepc_get_fan_pwm, eeepc_set_fan_pwm); 710 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
711 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, 711 EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
712 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl); 712 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
713 713
714 static ssize_t 714 static ssize_t
715 show_name(struct device *dev, struct device_attribute *attr, char *buf) 715 show_name(struct device *dev, struct device_attribute *attr, char *buf)
716 { 716 {
717 return sprintf(buf, "eeepc\n"); 717 return sprintf(buf, "eeepc\n");
718 } 718 }
719 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); 719 static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
720 720
721 static struct attribute *hwmon_attributes[] = { 721 static struct attribute *hwmon_attributes[] = {
722 &sensor_dev_attr_pwm1.dev_attr.attr, 722 &sensor_dev_attr_pwm1.dev_attr.attr,
723 &sensor_dev_attr_fan1_input.dev_attr.attr, 723 &sensor_dev_attr_fan1_input.dev_attr.attr,
724 &sensor_dev_attr_pwm1_enable.dev_attr.attr, 724 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
725 &sensor_dev_attr_name.dev_attr.attr, 725 &sensor_dev_attr_name.dev_attr.attr,
726 NULL 726 NULL
727 }; 727 };
728 728
729 static struct attribute_group hwmon_attribute_group = { 729 static struct attribute_group hwmon_attribute_group = {
730 .attrs = hwmon_attributes 730 .attrs = hwmon_attributes
731 }; 731 };
732 732
733 /* 733 /*
734 * exit/init 734 * exit/init
735 */ 735 */
736 static void eeepc_backlight_exit(void) 736 static void eeepc_backlight_exit(void)
737 { 737 {
738 if (eeepc_backlight_device) 738 if (eeepc_backlight_device)
739 backlight_device_unregister(eeepc_backlight_device); 739 backlight_device_unregister(eeepc_backlight_device);
740 if (ehotk->inputdev) 740 if (ehotk->inputdev)
741 input_unregister_device(ehotk->inputdev); 741 input_unregister_device(ehotk->inputdev);
742 if (ehotk->eeepc_wlan_rfkill) 742 if (ehotk->eeepc_wlan_rfkill)
743 rfkill_unregister(ehotk->eeepc_wlan_rfkill); 743 rfkill_unregister(ehotk->eeepc_wlan_rfkill);
744 if (ehotk->eeepc_bluetooth_rfkill) 744 if (ehotk->eeepc_bluetooth_rfkill)
745 rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); 745 rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
746 eeepc_backlight_device = NULL; 746 eeepc_backlight_device = NULL;
747 } 747 }
748 748
749 static void eeepc_hwmon_exit(void) 749 static void eeepc_hwmon_exit(void)
750 { 750 {
751 struct device *hwmon; 751 struct device *hwmon;
752 752
753 hwmon = eeepc_hwmon_device; 753 hwmon = eeepc_hwmon_device;
754 if (!hwmon) 754 if (!hwmon)
755 return ; 755 return ;
756 sysfs_remove_group(&hwmon->kobj, 756 sysfs_remove_group(&hwmon->kobj,
757 &hwmon_attribute_group); 757 &hwmon_attribute_group);
758 hwmon_device_unregister(hwmon); 758 hwmon_device_unregister(hwmon);
759 eeepc_hwmon_device = NULL; 759 eeepc_hwmon_device = NULL;
760 } 760 }
761 761
762 static void __exit eeepc_laptop_exit(void) 762 static void __exit eeepc_laptop_exit(void)
763 { 763 {
764 eeepc_backlight_exit(); 764 eeepc_backlight_exit();
765 eeepc_hwmon_exit(); 765 eeepc_hwmon_exit();
766 acpi_bus_unregister_driver(&eeepc_hotk_driver); 766 acpi_bus_unregister_driver(&eeepc_hotk_driver);
767 sysfs_remove_group(&platform_device->dev.kobj, 767 sysfs_remove_group(&platform_device->dev.kobj,
768 &platform_attribute_group); 768 &platform_attribute_group);
769 platform_device_unregister(platform_device); 769 platform_device_unregister(platform_device);
770 platform_driver_unregister(&platform_driver); 770 platform_driver_unregister(&platform_driver);
771 } 771 }
772 772
773 static int eeepc_backlight_init(struct device *dev) 773 static int eeepc_backlight_init(struct device *dev)
774 { 774 {
775 struct backlight_device *bd; 775 struct backlight_device *bd;
776 776
777 bd = backlight_device_register(EEEPC_HOTK_FILE, dev, 777 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
778 NULL, &eeepcbl_ops); 778 NULL, &eeepcbl_ops);
779 if (IS_ERR(bd)) { 779 if (IS_ERR(bd)) {
780 printk(EEEPC_ERR 780 printk(EEEPC_ERR
781 "Could not register eeepc backlight device\n"); 781 "Could not register eeepc backlight device\n");
782 eeepc_backlight_device = NULL; 782 eeepc_backlight_device = NULL;
783 return PTR_ERR(bd); 783 return PTR_ERR(bd);
784 } 784 }
785 eeepc_backlight_device = bd; 785 eeepc_backlight_device = bd;
786 bd->props.max_brightness = 15; 786 bd->props.max_brightness = 15;
787 bd->props.brightness = read_brightness(NULL); 787 bd->props.brightness = read_brightness(NULL);
788 bd->props.power = FB_BLANK_UNBLANK; 788 bd->props.power = FB_BLANK_UNBLANK;
789 backlight_update_status(bd); 789 backlight_update_status(bd);
790 return 0; 790 return 0;
791 } 791 }
792 792
793 static int eeepc_hwmon_init(struct device *dev) 793 static int eeepc_hwmon_init(struct device *dev)
794 { 794 {
795 struct device *hwmon; 795 struct device *hwmon;
796 int result; 796 int result;
797 797
798 hwmon = hwmon_device_register(dev); 798 hwmon = hwmon_device_register(dev);
799 if (IS_ERR(hwmon)) { 799 if (IS_ERR(hwmon)) {
800 printk(EEEPC_ERR 800 printk(EEEPC_ERR
801 "Could not register eeepc hwmon device\n"); 801 "Could not register eeepc hwmon device\n");
802 eeepc_hwmon_device = NULL; 802 eeepc_hwmon_device = NULL;
803 return PTR_ERR(hwmon); 803 return PTR_ERR(hwmon);
804 } 804 }
805 eeepc_hwmon_device = hwmon; 805 eeepc_hwmon_device = hwmon;
806 result = sysfs_create_group(&hwmon->kobj, 806 result = sysfs_create_group(&hwmon->kobj,
807 &hwmon_attribute_group); 807 &hwmon_attribute_group);
808 if (result) 808 if (result)
809 eeepc_hwmon_exit(); 809 eeepc_hwmon_exit();
810 return result; 810 return result;
811 } 811 }
812 812
813 static int __init eeepc_laptop_init(void) 813 static int __init eeepc_laptop_init(void)
814 { 814 {
815 struct device *dev; 815 struct device *dev;
816 int result; 816 int result;
817 817
818 if (acpi_disabled) 818 if (acpi_disabled)
819 return -ENODEV; 819 return -ENODEV;
820 result = acpi_bus_register_driver(&eeepc_hotk_driver); 820 result = acpi_bus_register_driver(&eeepc_hotk_driver);
821 if (result < 0) 821 if (result < 0)
822 return result; 822 return result;
823 if (!ehotk) { 823 if (!ehotk) {
824 acpi_bus_unregister_driver(&eeepc_hotk_driver); 824 acpi_bus_unregister_driver(&eeepc_hotk_driver);
825 return -ENODEV; 825 return -ENODEV;
826 } 826 }
827 dev = acpi_get_physical_device(ehotk->device->handle); 827 dev = acpi_get_physical_device(ehotk->device->handle);
828 result = eeepc_backlight_init(dev); 828
829 if (result) 829 if (!acpi_video_backlight_support()) {
830 goto fail_backlight; 830 result = eeepc_backlight_init(dev);
831 if (result)
832 goto fail_backlight;
833 } else
834 printk(EEEPC_INFO "Backlight controlled by ACPI video "
835 "driver\n");
836
831 result = eeepc_hwmon_init(dev); 837 result = eeepc_hwmon_init(dev);
832 if (result) 838 if (result)
833 goto fail_hwmon; 839 goto fail_hwmon;
834 /* Register platform stuff */ 840 /* Register platform stuff */
835 result = platform_driver_register(&platform_driver); 841 result = platform_driver_register(&platform_driver);
836 if (result) 842 if (result)
837 goto fail_platform_driver; 843 goto fail_platform_driver;
838 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1); 844 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
839 if (!platform_device) { 845 if (!platform_device) {
840 result = -ENOMEM; 846 result = -ENOMEM;
841 goto fail_platform_device1; 847 goto fail_platform_device1;
842 } 848 }
843 result = platform_device_add(platform_device); 849 result = platform_device_add(platform_device);
844 if (result) 850 if (result)
845 goto fail_platform_device2; 851 goto fail_platform_device2;
846 result = sysfs_create_group(&platform_device->dev.kobj, 852 result = sysfs_create_group(&platform_device->dev.kobj,
847 &platform_attribute_group); 853 &platform_attribute_group);
848 if (result) 854 if (result)
849 goto fail_sysfs; 855 goto fail_sysfs;
850 return 0; 856 return 0;
851 fail_sysfs: 857 fail_sysfs:
852 platform_device_del(platform_device); 858 platform_device_del(platform_device);
853 fail_platform_device2: 859 fail_platform_device2:
854 platform_device_put(platform_device); 860 platform_device_put(platform_device);
855 fail_platform_device1: 861 fail_platform_device1:
856 platform_driver_unregister(&platform_driver); 862 platform_driver_unregister(&platform_driver);
857 fail_platform_driver: 863 fail_platform_driver:
858 eeepc_hwmon_exit(); 864 eeepc_hwmon_exit();
859 fail_hwmon: 865 fail_hwmon:
860 eeepc_backlight_exit(); 866 eeepc_backlight_exit();
861 fail_backlight: 867 fail_backlight:
862 return result; 868 return result;
863 } 869 }
864 870
865 module_init(eeepc_laptop_init); 871 module_init(eeepc_laptop_init);
866 module_exit(eeepc_laptop_exit); 872 module_exit(eeepc_laptop_exit);
867 873
drivers/misc/fujitsu-laptop.c
1 /*-*-linux-c-*-*/ 1 /*-*-linux-c-*-*/
2 2
3 /* 3 /*
4 Copyright (C) 2007,2008 Jonathan Woithe <jwoithe@physics.adelaide.edu.au> 4 Copyright (C) 2007,2008 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
5 Copyright (C) 2008 Peter Gruber <nokos@gmx.net> 5 Copyright (C) 2008 Peter Gruber <nokos@gmx.net>
6 Based on earlier work: 6 Based on earlier work:
7 Copyright (C) 2003 Shane Spencer <shane@bogomip.com> 7 Copyright (C) 2003 Shane Spencer <shane@bogomip.com>
8 Adrian Yee <brewt-fujitsu@brewt.org> 8 Adrian Yee <brewt-fujitsu@brewt.org>
9 9
10 Templated from msi-laptop.c and thinkpad_acpi.c which is copyright 10 Templated from msi-laptop.c and thinkpad_acpi.c which is copyright
11 by its respective authors. 11 by its respective authors.
12 12
13 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by 14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or 15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version. 16 (at your option) any later version.
17 17
18 This program is distributed in the hope that it will be useful, but 18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of 19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details. 21 General Public License for more details.
22 22
23 You should have received a copy of the GNU General Public License 23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA. 26 02110-1301, USA.
27 */ 27 */
28 28
29 /* 29 /*
30 * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional 30 * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional
31 * features made available on a range of Fujitsu laptops including the 31 * features made available on a range of Fujitsu laptops including the
32 * P2xxx/P5xxx/S6xxx/S7xxx series. 32 * P2xxx/P5xxx/S6xxx/S7xxx series.
33 * 33 *
34 * This driver exports a few files in /sys/devices/platform/fujitsu-laptop/; 34 * This driver exports a few files in /sys/devices/platform/fujitsu-laptop/;
35 * others may be added at a later date. 35 * others may be added at a later date.
36 * 36 *
37 * lcd_level - Screen brightness: contains a single integer in the 37 * lcd_level - Screen brightness: contains a single integer in the
38 * range 0..7. (rw) 38 * range 0..7. (rw)
39 * 39 *
40 * In addition to these platform device attributes the driver 40 * In addition to these platform device attributes the driver
41 * registers itself in the Linux backlight control subsystem and is 41 * registers itself in the Linux backlight control subsystem and is
42 * available to userspace under /sys/class/backlight/fujitsu-laptop/. 42 * available to userspace under /sys/class/backlight/fujitsu-laptop/.
43 * 43 *
44 * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are 44 * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are
45 * also supported by this driver. 45 * also supported by this driver.
46 * 46 *
47 * This driver has been tested on a Fujitsu Lifebook S6410, S7020 and 47 * This driver has been tested on a Fujitsu Lifebook S6410, S7020 and
48 * P8010. It should work on most P-series and S-series Lifebooks, but 48 * P8010. It should work on most P-series and S-series Lifebooks, but
49 * YMMV. 49 * YMMV.
50 * 50 *
51 * The module parameter use_alt_lcd_levels switches between different ACPI 51 * The module parameter use_alt_lcd_levels switches between different ACPI
52 * brightness controls which are used by different Fujitsu laptops. In most 52 * brightness controls which are used by different Fujitsu laptops. In most
53 * cases the correct method is automatically detected. "use_alt_lcd_levels=1" 53 * cases the correct method is automatically detected. "use_alt_lcd_levels=1"
54 * is applicable for a Fujitsu Lifebook S6410 if autodetection fails. 54 * is applicable for a Fujitsu Lifebook S6410 if autodetection fails.
55 * 55 *
56 */ 56 */
57 57
58 #include <linux/module.h> 58 #include <linux/module.h>
59 #include <linux/kernel.h> 59 #include <linux/kernel.h>
60 #include <linux/init.h> 60 #include <linux/init.h>
61 #include <linux/acpi.h> 61 #include <linux/acpi.h>
62 #include <linux/dmi.h> 62 #include <linux/dmi.h>
63 #include <linux/backlight.h> 63 #include <linux/backlight.h>
64 #include <linux/input.h> 64 #include <linux/input.h>
65 #include <linux/kfifo.h> 65 #include <linux/kfifo.h>
66 #include <linux/video_output.h> 66 #include <linux/video_output.h>
67 #include <linux/platform_device.h> 67 #include <linux/platform_device.h>
68 68
69 #define FUJITSU_DRIVER_VERSION "0.4.3" 69 #define FUJITSU_DRIVER_VERSION "0.4.3"
70 70
71 #define FUJITSU_LCD_N_LEVELS 8 71 #define FUJITSU_LCD_N_LEVELS 8
72 72
73 #define ACPI_FUJITSU_CLASS "fujitsu" 73 #define ACPI_FUJITSU_CLASS "fujitsu"
74 #define ACPI_FUJITSU_HID "FUJ02B1" 74 #define ACPI_FUJITSU_HID "FUJ02B1"
75 #define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI brightness driver" 75 #define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI brightness driver"
76 #define ACPI_FUJITSU_DEVICE_NAME "Fujitsu FUJ02B1" 76 #define ACPI_FUJITSU_DEVICE_NAME "Fujitsu FUJ02B1"
77 #define ACPI_FUJITSU_HOTKEY_HID "FUJ02E3" 77 #define ACPI_FUJITSU_HOTKEY_HID "FUJ02E3"
78 #define ACPI_FUJITSU_HOTKEY_DRIVER_NAME "Fujitsu laptop FUJ02E3 ACPI hotkeys driver" 78 #define ACPI_FUJITSU_HOTKEY_DRIVER_NAME "Fujitsu laptop FUJ02E3 ACPI hotkeys driver"
79 #define ACPI_FUJITSU_HOTKEY_DEVICE_NAME "Fujitsu FUJ02E3" 79 #define ACPI_FUJITSU_HOTKEY_DEVICE_NAME "Fujitsu FUJ02E3"
80 80
81 #define ACPI_FUJITSU_NOTIFY_CODE1 0x80 81 #define ACPI_FUJITSU_NOTIFY_CODE1 0x80
82 82
83 #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 83 #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
84 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 84 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
85 85
86 /* Hotkey details */ 86 /* Hotkey details */
87 #define KEY1_CODE 0x410 /* codes for the keys in the GIRB register */ 87 #define KEY1_CODE 0x410 /* codes for the keys in the GIRB register */
88 #define KEY2_CODE 0x411 88 #define KEY2_CODE 0x411
89 #define KEY3_CODE 0x412 89 #define KEY3_CODE 0x412
90 #define KEY4_CODE 0x413 90 #define KEY4_CODE 0x413
91 91
92 #define MAX_HOTKEY_RINGBUFFER_SIZE 100 92 #define MAX_HOTKEY_RINGBUFFER_SIZE 100
93 #define RINGBUFFERSIZE 40 93 #define RINGBUFFERSIZE 40
94 94
95 /* Debugging */ 95 /* Debugging */
96 #define FUJLAPTOP_LOG ACPI_FUJITSU_HID ": " 96 #define FUJLAPTOP_LOG ACPI_FUJITSU_HID ": "
97 #define FUJLAPTOP_ERR KERN_ERR FUJLAPTOP_LOG 97 #define FUJLAPTOP_ERR KERN_ERR FUJLAPTOP_LOG
98 #define FUJLAPTOP_NOTICE KERN_NOTICE FUJLAPTOP_LOG 98 #define FUJLAPTOP_NOTICE KERN_NOTICE FUJLAPTOP_LOG
99 #define FUJLAPTOP_INFO KERN_INFO FUJLAPTOP_LOG 99 #define FUJLAPTOP_INFO KERN_INFO FUJLAPTOP_LOG
100 #define FUJLAPTOP_DEBUG KERN_DEBUG FUJLAPTOP_LOG 100 #define FUJLAPTOP_DEBUG KERN_DEBUG FUJLAPTOP_LOG
101 101
102 #define FUJLAPTOP_DBG_ALL 0xffff 102 #define FUJLAPTOP_DBG_ALL 0xffff
103 #define FUJLAPTOP_DBG_ERROR 0x0001 103 #define FUJLAPTOP_DBG_ERROR 0x0001
104 #define FUJLAPTOP_DBG_WARN 0x0002 104 #define FUJLAPTOP_DBG_WARN 0x0002
105 #define FUJLAPTOP_DBG_INFO 0x0004 105 #define FUJLAPTOP_DBG_INFO 0x0004
106 #define FUJLAPTOP_DBG_TRACE 0x0008 106 #define FUJLAPTOP_DBG_TRACE 0x0008
107 107
108 #define dbg_printk(a_dbg_level, format, arg...) \ 108 #define dbg_printk(a_dbg_level, format, arg...) \
109 do { if (dbg_level & a_dbg_level) \ 109 do { if (dbg_level & a_dbg_level) \
110 printk(FUJLAPTOP_DEBUG "%s: " format, __func__ , ## arg); \ 110 printk(FUJLAPTOP_DEBUG "%s: " format, __func__ , ## arg); \
111 } while (0) 111 } while (0)
112 #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG 112 #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
113 #define vdbg_printk(a_dbg_level, format, arg...) \ 113 #define vdbg_printk(a_dbg_level, format, arg...) \
114 dbg_printk(a_dbg_level, format, ## arg) 114 dbg_printk(a_dbg_level, format, ## arg)
115 #else 115 #else
116 #define vdbg_printk(a_dbg_level, format, arg...) 116 #define vdbg_printk(a_dbg_level, format, arg...)
117 #endif 117 #endif
118 118
119 /* Device controlling the backlight and associated keys */ 119 /* Device controlling the backlight and associated keys */
120 struct fujitsu_t { 120 struct fujitsu_t {
121 acpi_handle acpi_handle; 121 acpi_handle acpi_handle;
122 struct acpi_device *dev; 122 struct acpi_device *dev;
123 struct input_dev *input; 123 struct input_dev *input;
124 char phys[32]; 124 char phys[32];
125 struct backlight_device *bl_device; 125 struct backlight_device *bl_device;
126 struct platform_device *pf_device; 126 struct platform_device *pf_device;
127 int keycode1, keycode2, keycode3, keycode4; 127 int keycode1, keycode2, keycode3, keycode4;
128 128
129 unsigned int max_brightness; 129 unsigned int max_brightness;
130 unsigned int brightness_changed; 130 unsigned int brightness_changed;
131 unsigned int brightness_level; 131 unsigned int brightness_level;
132 }; 132 };
133 133
134 static struct fujitsu_t *fujitsu; 134 static struct fujitsu_t *fujitsu;
135 static int use_alt_lcd_levels = -1; 135 static int use_alt_lcd_levels = -1;
136 static int disable_brightness_keys = -1; 136 static int disable_brightness_keys = -1;
137 static int disable_brightness_adjust = -1; 137 static int disable_brightness_adjust = -1;
138 138
139 /* Device used to access other hotkeys on the laptop */ 139 /* Device used to access other hotkeys on the laptop */
140 struct fujitsu_hotkey_t { 140 struct fujitsu_hotkey_t {
141 acpi_handle acpi_handle; 141 acpi_handle acpi_handle;
142 struct acpi_device *dev; 142 struct acpi_device *dev;
143 struct input_dev *input; 143 struct input_dev *input;
144 char phys[32]; 144 char phys[32];
145 struct platform_device *pf_device; 145 struct platform_device *pf_device;
146 struct kfifo *fifo; 146 struct kfifo *fifo;
147 spinlock_t fifo_lock; 147 spinlock_t fifo_lock;
148 148
149 unsigned int irb; /* info about the pressed buttons */ 149 unsigned int irb; /* info about the pressed buttons */
150 }; 150 };
151 151
152 static struct fujitsu_hotkey_t *fujitsu_hotkey; 152 static struct fujitsu_hotkey_t *fujitsu_hotkey;
153 153
154 static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, 154 static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
155 void *data); 155 void *data);
156 156
157 #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG 157 #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
158 static u32 dbg_level = 0x03; 158 static u32 dbg_level = 0x03;
159 #endif 159 #endif
160 160
161 static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data); 161 static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data);
162 162
163 /* Hardware access for LCD brightness control */ 163 /* Hardware access for LCD brightness control */
164 164
165 static int set_lcd_level(int level) 165 static int set_lcd_level(int level)
166 { 166 {
167 acpi_status status = AE_OK; 167 acpi_status status = AE_OK;
168 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 168 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
169 struct acpi_object_list arg_list = { 1, &arg0 }; 169 struct acpi_object_list arg_list = { 1, &arg0 };
170 acpi_handle handle = NULL; 170 acpi_handle handle = NULL;
171 171
172 vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBLL [%d]\n", 172 vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBLL [%d]\n",
173 level); 173 level);
174 174
175 if (level < 0 || level >= fujitsu->max_brightness) 175 if (level < 0 || level >= fujitsu->max_brightness)
176 return -EINVAL; 176 return -EINVAL;
177 177
178 if (!fujitsu) 178 if (!fujitsu)
179 return -EINVAL; 179 return -EINVAL;
180 180
181 status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle); 181 status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle);
182 if (ACPI_FAILURE(status)) { 182 if (ACPI_FAILURE(status)) {
183 vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n"); 183 vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n");
184 return -ENODEV; 184 return -ENODEV;
185 } 185 }
186 186
187 arg0.integer.value = level; 187 arg0.integer.value = level;
188 188
189 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); 189 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
190 if (ACPI_FAILURE(status)) 190 if (ACPI_FAILURE(status))
191 return -ENODEV; 191 return -ENODEV;
192 192
193 return 0; 193 return 0;
194 } 194 }
195 195
196 static int set_lcd_level_alt(int level) 196 static int set_lcd_level_alt(int level)
197 { 197 {
198 acpi_status status = AE_OK; 198 acpi_status status = AE_OK;
199 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 199 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
200 struct acpi_object_list arg_list = { 1, &arg0 }; 200 struct acpi_object_list arg_list = { 1, &arg0 };
201 acpi_handle handle = NULL; 201 acpi_handle handle = NULL;
202 202
203 vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBL2 [%d]\n", 203 vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBL2 [%d]\n",
204 level); 204 level);
205 205
206 if (level < 0 || level >= fujitsu->max_brightness) 206 if (level < 0 || level >= fujitsu->max_brightness)
207 return -EINVAL; 207 return -EINVAL;
208 208
209 if (!fujitsu) 209 if (!fujitsu)
210 return -EINVAL; 210 return -EINVAL;
211 211
212 status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle); 212 status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle);
213 if (ACPI_FAILURE(status)) { 213 if (ACPI_FAILURE(status)) {
214 vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n"); 214 vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n");
215 return -ENODEV; 215 return -ENODEV;
216 } 216 }
217 217
218 arg0.integer.value = level; 218 arg0.integer.value = level;
219 219
220 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); 220 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
221 if (ACPI_FAILURE(status)) 221 if (ACPI_FAILURE(status))
222 return -ENODEV; 222 return -ENODEV;
223 223
224 return 0; 224 return 0;
225 } 225 }
226 226
227 static int get_lcd_level(void) 227 static int get_lcd_level(void)
228 { 228 {
229 unsigned long long state = 0; 229 unsigned long long state = 0;
230 acpi_status status = AE_OK; 230 acpi_status status = AE_OK;
231 231
232 vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n"); 232 vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n");
233 233
234 status = 234 status =
235 acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state); 235 acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
236 if (status < 0) 236 if (status < 0)
237 return status; 237 return status;
238 238
239 fujitsu->brightness_level = state & 0x0fffffff; 239 fujitsu->brightness_level = state & 0x0fffffff;
240 240
241 if (state & 0x80000000) 241 if (state & 0x80000000)
242 fujitsu->brightness_changed = 1; 242 fujitsu->brightness_changed = 1;
243 else 243 else
244 fujitsu->brightness_changed = 0; 244 fujitsu->brightness_changed = 0;
245 245
246 return fujitsu->brightness_level; 246 return fujitsu->brightness_level;
247 } 247 }
248 248
249 static int get_max_brightness(void) 249 static int get_max_brightness(void)
250 { 250 {
251 unsigned long long state = 0; 251 unsigned long long state = 0;
252 acpi_status status = AE_OK; 252 acpi_status status = AE_OK;
253 253
254 vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n"); 254 vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n");
255 255
256 status = 256 status =
257 acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state); 257 acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state);
258 if (status < 0) 258 if (status < 0)
259 return status; 259 return status;
260 260
261 fujitsu->max_brightness = state; 261 fujitsu->max_brightness = state;
262 262
263 return fujitsu->max_brightness; 263 return fujitsu->max_brightness;
264 } 264 }
265 265
266 static int get_lcd_level_alt(void) 266 static int get_lcd_level_alt(void)
267 { 267 {
268 unsigned long long state = 0; 268 unsigned long long state = 0;
269 acpi_status status = AE_OK; 269 acpi_status status = AE_OK;
270 270
271 vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n"); 271 vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n");
272 272
273 status = 273 status =
274 acpi_evaluate_integer(fujitsu->acpi_handle, "GBLS", NULL, &state); 274 acpi_evaluate_integer(fujitsu->acpi_handle, "GBLS", NULL, &state);
275 if (status < 0) 275 if (status < 0)
276 return status; 276 return status;
277 277
278 fujitsu->brightness_level = state & 0x0fffffff; 278 fujitsu->brightness_level = state & 0x0fffffff;
279 279
280 if (state & 0x80000000) 280 if (state & 0x80000000)
281 fujitsu->brightness_changed = 1; 281 fujitsu->brightness_changed = 1;
282 else 282 else
283 fujitsu->brightness_changed = 0; 283 fujitsu->brightness_changed = 0;
284 284
285 return fujitsu->brightness_level; 285 return fujitsu->brightness_level;
286 } 286 }
287 287
288 /* Backlight device stuff */ 288 /* Backlight device stuff */
289 289
290 static int bl_get_brightness(struct backlight_device *b) 290 static int bl_get_brightness(struct backlight_device *b)
291 { 291 {
292 if (use_alt_lcd_levels) 292 if (use_alt_lcd_levels)
293 return get_lcd_level_alt(); 293 return get_lcd_level_alt();
294 else 294 else
295 return get_lcd_level(); 295 return get_lcd_level();
296 } 296 }
297 297
298 static int bl_update_status(struct backlight_device *b) 298 static int bl_update_status(struct backlight_device *b)
299 { 299 {
300 if (use_alt_lcd_levels) 300 if (use_alt_lcd_levels)
301 return set_lcd_level_alt(b->props.brightness); 301 return set_lcd_level_alt(b->props.brightness);
302 else 302 else
303 return set_lcd_level(b->props.brightness); 303 return set_lcd_level(b->props.brightness);
304 } 304 }
305 305
306 static struct backlight_ops fujitsubl_ops = { 306 static struct backlight_ops fujitsubl_ops = {
307 .get_brightness = bl_get_brightness, 307 .get_brightness = bl_get_brightness,
308 .update_status = bl_update_status, 308 .update_status = bl_update_status,
309 }; 309 };
310 310
311 /* Platform LCD brightness device */ 311 /* Platform LCD brightness device */
312 312
313 static ssize_t 313 static ssize_t
314 show_max_brightness(struct device *dev, 314 show_max_brightness(struct device *dev,
315 struct device_attribute *attr, char *buf) 315 struct device_attribute *attr, char *buf)
316 { 316 {
317 317
318 int ret; 318 int ret;
319 319
320 ret = get_max_brightness(); 320 ret = get_max_brightness();
321 if (ret < 0) 321 if (ret < 0)
322 return ret; 322 return ret;
323 323
324 return sprintf(buf, "%i\n", ret); 324 return sprintf(buf, "%i\n", ret);
325 } 325 }
326 326
327 static ssize_t 327 static ssize_t
328 show_brightness_changed(struct device *dev, 328 show_brightness_changed(struct device *dev,
329 struct device_attribute *attr, char *buf) 329 struct device_attribute *attr, char *buf)
330 { 330 {
331 331
332 int ret; 332 int ret;
333 333
334 ret = fujitsu->brightness_changed; 334 ret = fujitsu->brightness_changed;
335 if (ret < 0) 335 if (ret < 0)
336 return ret; 336 return ret;
337 337
338 return sprintf(buf, "%i\n", ret); 338 return sprintf(buf, "%i\n", ret);
339 } 339 }
340 340
341 static ssize_t show_lcd_level(struct device *dev, 341 static ssize_t show_lcd_level(struct device *dev,
342 struct device_attribute *attr, char *buf) 342 struct device_attribute *attr, char *buf)
343 { 343 {
344 344
345 int ret; 345 int ret;
346 346
347 if (use_alt_lcd_levels) 347 if (use_alt_lcd_levels)
348 ret = get_lcd_level_alt(); 348 ret = get_lcd_level_alt();
349 else 349 else
350 ret = get_lcd_level(); 350 ret = get_lcd_level();
351 if (ret < 0) 351 if (ret < 0)
352 return ret; 352 return ret;
353 353
354 return sprintf(buf, "%i\n", ret); 354 return sprintf(buf, "%i\n", ret);
355 } 355 }
356 356
357 static ssize_t store_lcd_level(struct device *dev, 357 static ssize_t store_lcd_level(struct device *dev,
358 struct device_attribute *attr, const char *buf, 358 struct device_attribute *attr, const char *buf,
359 size_t count) 359 size_t count)
360 { 360 {
361 361
362 int level, ret; 362 int level, ret;
363 363
364 if (sscanf(buf, "%i", &level) != 1 364 if (sscanf(buf, "%i", &level) != 1
365 || (level < 0 || level >= fujitsu->max_brightness)) 365 || (level < 0 || level >= fujitsu->max_brightness))
366 return -EINVAL; 366 return -EINVAL;
367 367
368 if (use_alt_lcd_levels) 368 if (use_alt_lcd_levels)
369 ret = set_lcd_level_alt(level); 369 ret = set_lcd_level_alt(level);
370 else 370 else
371 ret = set_lcd_level(level); 371 ret = set_lcd_level(level);
372 if (ret < 0) 372 if (ret < 0)
373 return ret; 373 return ret;
374 374
375 if (use_alt_lcd_levels) 375 if (use_alt_lcd_levels)
376 ret = get_lcd_level_alt(); 376 ret = get_lcd_level_alt();
377 else 377 else
378 ret = get_lcd_level(); 378 ret = get_lcd_level();
379 if (ret < 0) 379 if (ret < 0)
380 return ret; 380 return ret;
381 381
382 return count; 382 return count;
383 } 383 }
384 384
385 /* Hardware access for hotkey device */ 385 /* Hardware access for hotkey device */
386 386
387 static int get_irb(void) 387 static int get_irb(void)
388 { 388 {
389 unsigned long long state = 0; 389 unsigned long long state = 0;
390 acpi_status status = AE_OK; 390 acpi_status status = AE_OK;
391 391
392 vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n"); 392 vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n");
393 393
394 status = 394 status =
395 acpi_evaluate_integer(fujitsu_hotkey->acpi_handle, "GIRB", NULL, 395 acpi_evaluate_integer(fujitsu_hotkey->acpi_handle, "GIRB", NULL,
396 &state); 396 &state);
397 if (status < 0) 397 if (status < 0)
398 return status; 398 return status;
399 399
400 fujitsu_hotkey->irb = state; 400 fujitsu_hotkey->irb = state;
401 401
402 return fujitsu_hotkey->irb; 402 return fujitsu_hotkey->irb;
403 } 403 }
404 404
405 static ssize_t 405 static ssize_t
406 ignore_store(struct device *dev, 406 ignore_store(struct device *dev,
407 struct device_attribute *attr, const char *buf, size_t count) 407 struct device_attribute *attr, const char *buf, size_t count)
408 { 408 {
409 return count; 409 return count;
410 } 410 }
411 411
412 static DEVICE_ATTR(max_brightness, 0444, show_max_brightness, ignore_store); 412 static DEVICE_ATTR(max_brightness, 0444, show_max_brightness, ignore_store);
413 static DEVICE_ATTR(brightness_changed, 0444, show_brightness_changed, 413 static DEVICE_ATTR(brightness_changed, 0444, show_brightness_changed,
414 ignore_store); 414 ignore_store);
415 static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); 415 static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
416 416
417 static struct attribute *fujitsupf_attributes[] = { 417 static struct attribute *fujitsupf_attributes[] = {
418 &dev_attr_brightness_changed.attr, 418 &dev_attr_brightness_changed.attr,
419 &dev_attr_max_brightness.attr, 419 &dev_attr_max_brightness.attr,
420 &dev_attr_lcd_level.attr, 420 &dev_attr_lcd_level.attr,
421 NULL 421 NULL
422 }; 422 };
423 423
424 static struct attribute_group fujitsupf_attribute_group = { 424 static struct attribute_group fujitsupf_attribute_group = {
425 .attrs = fujitsupf_attributes 425 .attrs = fujitsupf_attributes
426 }; 426 };
427 427
428 static struct platform_driver fujitsupf_driver = { 428 static struct platform_driver fujitsupf_driver = {
429 .driver = { 429 .driver = {
430 .name = "fujitsu-laptop", 430 .name = "fujitsu-laptop",
431 .owner = THIS_MODULE, 431 .owner = THIS_MODULE,
432 } 432 }
433 }; 433 };
434 434
435 static void dmi_check_cb_common(const struct dmi_system_id *id) 435 static void dmi_check_cb_common(const struct dmi_system_id *id)
436 { 436 {
437 acpi_handle handle; 437 acpi_handle handle;
438 int have_blnf; 438 int have_blnf;
439 printk(KERN_INFO "fujitsu-laptop: Identified laptop model '%s'.\n", 439 printk(KERN_INFO "fujitsu-laptop: Identified laptop model '%s'.\n",
440 id->ident); 440 id->ident);
441 have_blnf = ACPI_SUCCESS 441 have_blnf = ACPI_SUCCESS
442 (acpi_get_handle(NULL, "\\_SB.PCI0.GFX0.LCD.BLNF", &handle)); 442 (acpi_get_handle(NULL, "\\_SB.PCI0.GFX0.LCD.BLNF", &handle));
443 if (use_alt_lcd_levels == -1) { 443 if (use_alt_lcd_levels == -1) {
444 vdbg_printk(FUJLAPTOP_DBG_TRACE, "auto-detecting usealt\n"); 444 vdbg_printk(FUJLAPTOP_DBG_TRACE, "auto-detecting usealt\n");
445 use_alt_lcd_levels = 1; 445 use_alt_lcd_levels = 1;
446 } 446 }
447 if (disable_brightness_keys == -1) { 447 if (disable_brightness_keys == -1) {
448 vdbg_printk(FUJLAPTOP_DBG_TRACE, 448 vdbg_printk(FUJLAPTOP_DBG_TRACE,
449 "auto-detecting disable_keys\n"); 449 "auto-detecting disable_keys\n");
450 disable_brightness_keys = have_blnf ? 1 : 0; 450 disable_brightness_keys = have_blnf ? 1 : 0;
451 } 451 }
452 if (disable_brightness_adjust == -1) { 452 if (disable_brightness_adjust == -1) {
453 vdbg_printk(FUJLAPTOP_DBG_TRACE, 453 vdbg_printk(FUJLAPTOP_DBG_TRACE,
454 "auto-detecting disable_adjust\n"); 454 "auto-detecting disable_adjust\n");
455 disable_brightness_adjust = have_blnf ? 0 : 1; 455 disable_brightness_adjust = have_blnf ? 0 : 1;
456 } 456 }
457 } 457 }
458 458
459 static int dmi_check_cb_s6410(const struct dmi_system_id *id) 459 static int dmi_check_cb_s6410(const struct dmi_system_id *id)
460 { 460 {
461 dmi_check_cb_common(id); 461 dmi_check_cb_common(id);
462 fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ 462 fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */
463 fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */ 463 fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */
464 return 0; 464 return 0;
465 } 465 }
466 466
467 static int dmi_check_cb_s6420(const struct dmi_system_id *id) 467 static int dmi_check_cb_s6420(const struct dmi_system_id *id)
468 { 468 {
469 dmi_check_cb_common(id); 469 dmi_check_cb_common(id);
470 fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ 470 fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */
471 fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */ 471 fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */
472 return 0; 472 return 0;
473 } 473 }
474 474
475 static int dmi_check_cb_p8010(const struct dmi_system_id *id) 475 static int dmi_check_cb_p8010(const struct dmi_system_id *id)
476 { 476 {
477 dmi_check_cb_common(id); 477 dmi_check_cb_common(id);
478 fujitsu->keycode1 = KEY_HELP; /* "Support" */ 478 fujitsu->keycode1 = KEY_HELP; /* "Support" */
479 fujitsu->keycode3 = KEY_SWITCHVIDEOMODE; /* "Presentation" */ 479 fujitsu->keycode3 = KEY_SWITCHVIDEOMODE; /* "Presentation" */
480 fujitsu->keycode4 = KEY_WWW; /* "Internet" */ 480 fujitsu->keycode4 = KEY_WWW; /* "Internet" */
481 return 0; 481 return 0;
482 } 482 }
483 483
484 static struct dmi_system_id fujitsu_dmi_table[] = { 484 static struct dmi_system_id fujitsu_dmi_table[] = {
485 { 485 {
486 .ident = "Fujitsu Siemens S6410", 486 .ident = "Fujitsu Siemens S6410",
487 .matches = { 487 .matches = {
488 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 488 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
489 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"), 489 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"),
490 }, 490 },
491 .callback = dmi_check_cb_s6410}, 491 .callback = dmi_check_cb_s6410},
492 { 492 {
493 .ident = "Fujitsu Siemens S6420", 493 .ident = "Fujitsu Siemens S6420",
494 .matches = { 494 .matches = {
495 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 495 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
496 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6420"), 496 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6420"),
497 }, 497 },
498 .callback = dmi_check_cb_s6420}, 498 .callback = dmi_check_cb_s6420},
499 { 499 {
500 .ident = "Fujitsu LifeBook P8010", 500 .ident = "Fujitsu LifeBook P8010",
501 .matches = { 501 .matches = {
502 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 502 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
503 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P8010"), 503 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P8010"),
504 }, 504 },
505 .callback = dmi_check_cb_p8010}, 505 .callback = dmi_check_cb_p8010},
506 {} 506 {}
507 }; 507 };
508 508
509 /* ACPI device for LCD brightness control */ 509 /* ACPI device for LCD brightness control */
510 510
511 static int acpi_fujitsu_add(struct acpi_device *device) 511 static int acpi_fujitsu_add(struct acpi_device *device)
512 { 512 {
513 acpi_status status; 513 acpi_status status;
514 acpi_handle handle; 514 acpi_handle handle;
515 int result = 0; 515 int result = 0;
516 int state = 0; 516 int state = 0;
517 struct input_dev *input; 517 struct input_dev *input;
518 int error; 518 int error;
519 519
520 if (!device) 520 if (!device)
521 return -EINVAL; 521 return -EINVAL;
522 522
523 fujitsu->acpi_handle = device->handle; 523 fujitsu->acpi_handle = device->handle;
524 sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME); 524 sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME);
525 sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); 525 sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
526 device->driver_data = fujitsu; 526 device->driver_data = fujitsu;
527 527
528 status = acpi_install_notify_handler(device->handle, 528 status = acpi_install_notify_handler(device->handle,
529 ACPI_DEVICE_NOTIFY, 529 ACPI_DEVICE_NOTIFY,
530 acpi_fujitsu_notify, fujitsu); 530 acpi_fujitsu_notify, fujitsu);
531 531
532 if (ACPI_FAILURE(status)) { 532 if (ACPI_FAILURE(status)) {
533 printk(KERN_ERR "Error installing notify handler\n"); 533 printk(KERN_ERR "Error installing notify handler\n");
534 error = -ENODEV; 534 error = -ENODEV;
535 goto err_stop; 535 goto err_stop;
536 } 536 }
537 537
538 fujitsu->input = input = input_allocate_device(); 538 fujitsu->input = input = input_allocate_device();
539 if (!input) { 539 if (!input) {
540 error = -ENOMEM; 540 error = -ENOMEM;
541 goto err_uninstall_notify; 541 goto err_uninstall_notify;
542 } 542 }
543 543
544 snprintf(fujitsu->phys, sizeof(fujitsu->phys), 544 snprintf(fujitsu->phys, sizeof(fujitsu->phys),
545 "%s/video/input0", acpi_device_hid(device)); 545 "%s/video/input0", acpi_device_hid(device));
546 546
547 input->name = acpi_device_name(device); 547 input->name = acpi_device_name(device);
548 input->phys = fujitsu->phys; 548 input->phys = fujitsu->phys;
549 input->id.bustype = BUS_HOST; 549 input->id.bustype = BUS_HOST;
550 input->id.product = 0x06; 550 input->id.product = 0x06;
551 input->dev.parent = &device->dev; 551 input->dev.parent = &device->dev;
552 input->evbit[0] = BIT(EV_KEY); 552 input->evbit[0] = BIT(EV_KEY);
553 set_bit(KEY_BRIGHTNESSUP, input->keybit); 553 set_bit(KEY_BRIGHTNESSUP, input->keybit);
554 set_bit(KEY_BRIGHTNESSDOWN, input->keybit); 554 set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
555 set_bit(KEY_UNKNOWN, input->keybit); 555 set_bit(KEY_UNKNOWN, input->keybit);
556 556
557 error = input_register_device(input); 557 error = input_register_device(input);
558 if (error) 558 if (error)
559 goto err_free_input_dev; 559 goto err_free_input_dev;
560 560
561 result = acpi_bus_get_power(fujitsu->acpi_handle, &state); 561 result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
562 if (result) { 562 if (result) {
563 printk(KERN_ERR "Error reading power state\n"); 563 printk(KERN_ERR "Error reading power state\n");
564 goto end; 564 goto end;
565 } 565 }
566 566
567 printk(KERN_INFO PREFIX "%s [%s] (%s)\n", 567 printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
568 acpi_device_name(device), acpi_device_bid(device), 568 acpi_device_name(device), acpi_device_bid(device),
569 !device->power.state ? "on" : "off"); 569 !device->power.state ? "on" : "off");
570 570
571 fujitsu->dev = device; 571 fujitsu->dev = device;
572 572
573 if (ACPI_SUCCESS 573 if (ACPI_SUCCESS
574 (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) { 574 (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) {
575 vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); 575 vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n");
576 if (ACPI_FAILURE 576 if (ACPI_FAILURE
577 (acpi_evaluate_object 577 (acpi_evaluate_object
578 (device->handle, METHOD_NAME__INI, NULL, NULL))) 578 (device->handle, METHOD_NAME__INI, NULL, NULL)))
579 printk(KERN_ERR "_INI Method failed\n"); 579 printk(KERN_ERR "_INI Method failed\n");
580 } 580 }
581 581
582 /* do config (detect defaults) */ 582 /* do config (detect defaults) */
583 use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0; 583 use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0;
584 disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0; 584 disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0;
585 disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0; 585 disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0;
586 vdbg_printk(FUJLAPTOP_DBG_INFO, 586 vdbg_printk(FUJLAPTOP_DBG_INFO,
587 "config: [alt interface: %d], [key disable: %d], [adjust disable: %d]\n", 587 "config: [alt interface: %d], [key disable: %d], [adjust disable: %d]\n",
588 use_alt_lcd_levels, disable_brightness_keys, 588 use_alt_lcd_levels, disable_brightness_keys,
589 disable_brightness_adjust); 589 disable_brightness_adjust);
590 590
591 if (get_max_brightness() <= 0) 591 if (get_max_brightness() <= 0)
592 fujitsu->max_brightness = FUJITSU_LCD_N_LEVELS; 592 fujitsu->max_brightness = FUJITSU_LCD_N_LEVELS;
593 if (use_alt_lcd_levels) 593 if (use_alt_lcd_levels)
594 get_lcd_level_alt(); 594 get_lcd_level_alt();
595 else 595 else
596 get_lcd_level(); 596 get_lcd_level();
597 597
598 return result; 598 return result;
599 599
600 end: 600 end:
601 err_free_input_dev: 601 err_free_input_dev:
602 input_free_device(input); 602 input_free_device(input);
603 err_uninstall_notify: 603 err_uninstall_notify:
604 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, 604 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
605 acpi_fujitsu_notify); 605 acpi_fujitsu_notify);
606 err_stop: 606 err_stop:
607 607
608 return result; 608 return result;
609 } 609 }
610 610
611 static int acpi_fujitsu_remove(struct acpi_device *device, int type) 611 static int acpi_fujitsu_remove(struct acpi_device *device, int type)
612 { 612 {
613 acpi_status status; 613 acpi_status status;
614 struct fujitsu_t *fujitsu = NULL; 614 struct fujitsu_t *fujitsu = NULL;
615 615
616 if (!device || !acpi_driver_data(device)) 616 if (!device || !acpi_driver_data(device))
617 return -EINVAL; 617 return -EINVAL;
618 618
619 fujitsu = acpi_driver_data(device); 619 fujitsu = acpi_driver_data(device);
620 620
621 status = acpi_remove_notify_handler(fujitsu->acpi_handle, 621 status = acpi_remove_notify_handler(fujitsu->acpi_handle,
622 ACPI_DEVICE_NOTIFY, 622 ACPI_DEVICE_NOTIFY,
623 acpi_fujitsu_notify); 623 acpi_fujitsu_notify);
624 624
625 if (!device || !acpi_driver_data(device)) 625 if (!device || !acpi_driver_data(device))
626 return -EINVAL; 626 return -EINVAL;
627 627
628 fujitsu->acpi_handle = NULL; 628 fujitsu->acpi_handle = NULL;
629 629
630 return 0; 630 return 0;
631 } 631 }
632 632
633 /* Brightness notify */ 633 /* Brightness notify */
634 634
635 static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) 635 static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
636 { 636 {
637 struct input_dev *input; 637 struct input_dev *input;
638 int keycode; 638 int keycode;
639 int oldb, newb; 639 int oldb, newb;
640 640
641 input = fujitsu->input; 641 input = fujitsu->input;
642 642
643 switch (event) { 643 switch (event) {
644 case ACPI_FUJITSU_NOTIFY_CODE1: 644 case ACPI_FUJITSU_NOTIFY_CODE1:
645 keycode = 0; 645 keycode = 0;
646 oldb = fujitsu->brightness_level; 646 oldb = fujitsu->brightness_level;
647 get_lcd_level(); /* the alt version always yields changed */ 647 get_lcd_level(); /* the alt version always yields changed */
648 newb = fujitsu->brightness_level; 648 newb = fujitsu->brightness_level;
649 649
650 vdbg_printk(FUJLAPTOP_DBG_TRACE, 650 vdbg_printk(FUJLAPTOP_DBG_TRACE,
651 "brightness button event [%i -> %i (%i)]\n", 651 "brightness button event [%i -> %i (%i)]\n",
652 oldb, newb, fujitsu->brightness_changed); 652 oldb, newb, fujitsu->brightness_changed);
653 653
654 if (oldb == newb && fujitsu->brightness_changed) { 654 if (oldb == newb && fujitsu->brightness_changed) {
655 keycode = 0; 655 keycode = 0;
656 if (disable_brightness_keys != 1) { 656 if (disable_brightness_keys != 1) {
657 if (oldb == 0) { 657 if (oldb == 0) {
658 acpi_bus_generate_proc_event 658 acpi_bus_generate_proc_event
659 (fujitsu->dev, 659 (fujitsu->dev,
660 ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 660 ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
661 0); 661 0);
662 keycode = KEY_BRIGHTNESSDOWN; 662 keycode = KEY_BRIGHTNESSDOWN;
663 } else if (oldb == 663 } else if (oldb ==
664 (fujitsu->max_brightness) - 1) { 664 (fujitsu->max_brightness) - 1) {
665 acpi_bus_generate_proc_event 665 acpi_bus_generate_proc_event
666 (fujitsu->dev, 666 (fujitsu->dev,
667 ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 667 ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
668 0); 668 0);
669 keycode = KEY_BRIGHTNESSUP; 669 keycode = KEY_BRIGHTNESSUP;
670 } 670 }
671 } 671 }
672 } else if (oldb < newb) { 672 } else if (oldb < newb) {
673 if (disable_brightness_adjust != 1) { 673 if (disable_brightness_adjust != 1) {
674 if (use_alt_lcd_levels) 674 if (use_alt_lcd_levels)
675 set_lcd_level_alt(newb); 675 set_lcd_level_alt(newb);
676 else 676 else
677 set_lcd_level(newb); 677 set_lcd_level(newb);
678 } 678 }
679 if (disable_brightness_keys != 1) { 679 if (disable_brightness_keys != 1) {
680 acpi_bus_generate_proc_event(fujitsu->dev, 680 acpi_bus_generate_proc_event(fujitsu->dev,
681 ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0); 681 ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0);
682 keycode = KEY_BRIGHTNESSUP; 682 keycode = KEY_BRIGHTNESSUP;
683 } 683 }
684 } else if (oldb > newb) { 684 } else if (oldb > newb) {
685 if (disable_brightness_adjust != 1) { 685 if (disable_brightness_adjust != 1) {
686 if (use_alt_lcd_levels) 686 if (use_alt_lcd_levels)
687 set_lcd_level_alt(newb); 687 set_lcd_level_alt(newb);
688 else 688 else
689 set_lcd_level(newb); 689 set_lcd_level(newb);
690 } 690 }
691 if (disable_brightness_keys != 1) { 691 if (disable_brightness_keys != 1) {
692 acpi_bus_generate_proc_event(fujitsu->dev, 692 acpi_bus_generate_proc_event(fujitsu->dev,
693 ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0); 693 ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0);
694 keycode = KEY_BRIGHTNESSDOWN; 694 keycode = KEY_BRIGHTNESSDOWN;
695 } 695 }
696 } else { 696 } else {
697 keycode = KEY_UNKNOWN; 697 keycode = KEY_UNKNOWN;
698 } 698 }
699 break; 699 break;
700 default: 700 default:
701 keycode = KEY_UNKNOWN; 701 keycode = KEY_UNKNOWN;
702 vdbg_printk(FUJLAPTOP_DBG_WARN, 702 vdbg_printk(FUJLAPTOP_DBG_WARN,
703 "unsupported event [0x%x]\n", event); 703 "unsupported event [0x%x]\n", event);
704 break; 704 break;
705 } 705 }
706 706
707 if (keycode != 0) { 707 if (keycode != 0) {
708 input_report_key(input, keycode, 1); 708 input_report_key(input, keycode, 1);
709 input_sync(input); 709 input_sync(input);
710 input_report_key(input, keycode, 0); 710 input_report_key(input, keycode, 0);
711 input_sync(input); 711 input_sync(input);
712 } 712 }
713 713
714 return; 714 return;
715 } 715 }
716 716
717 /* ACPI device for hotkey handling */ 717 /* ACPI device for hotkey handling */
718 718
719 static int acpi_fujitsu_hotkey_add(struct acpi_device *device) 719 static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
720 { 720 {
721 acpi_status status; 721 acpi_status status;
722 acpi_handle handle; 722 acpi_handle handle;
723 int result = 0; 723 int result = 0;
724 int state = 0; 724 int state = 0;
725 struct input_dev *input; 725 struct input_dev *input;
726 int error; 726 int error;
727 int i; 727 int i;
728 728
729 if (!device) 729 if (!device)
730 return -EINVAL; 730 return -EINVAL;
731 731
732 fujitsu_hotkey->acpi_handle = device->handle; 732 fujitsu_hotkey->acpi_handle = device->handle;
733 sprintf(acpi_device_name(device), "%s", 733 sprintf(acpi_device_name(device), "%s",
734 ACPI_FUJITSU_HOTKEY_DEVICE_NAME); 734 ACPI_FUJITSU_HOTKEY_DEVICE_NAME);
735 sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); 735 sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
736 device->driver_data = fujitsu_hotkey; 736 device->driver_data = fujitsu_hotkey;
737 737
738 status = acpi_install_notify_handler(device->handle, 738 status = acpi_install_notify_handler(device->handle,
739 ACPI_DEVICE_NOTIFY, 739 ACPI_DEVICE_NOTIFY,
740 acpi_fujitsu_hotkey_notify, 740 acpi_fujitsu_hotkey_notify,
741 fujitsu_hotkey); 741 fujitsu_hotkey);
742 742
743 if (ACPI_FAILURE(status)) { 743 if (ACPI_FAILURE(status)) {
744 printk(KERN_ERR "Error installing notify handler\n"); 744 printk(KERN_ERR "Error installing notify handler\n");
745 error = -ENODEV; 745 error = -ENODEV;
746 goto err_stop; 746 goto err_stop;
747 } 747 }
748 748
749 /* kfifo */ 749 /* kfifo */
750 spin_lock_init(&fujitsu_hotkey->fifo_lock); 750 spin_lock_init(&fujitsu_hotkey->fifo_lock);
751 fujitsu_hotkey->fifo = 751 fujitsu_hotkey->fifo =
752 kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL, 752 kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL,
753 &fujitsu_hotkey->fifo_lock); 753 &fujitsu_hotkey->fifo_lock);
754 if (IS_ERR(fujitsu_hotkey->fifo)) { 754 if (IS_ERR(fujitsu_hotkey->fifo)) {
755 printk(KERN_ERR "kfifo_alloc failed\n"); 755 printk(KERN_ERR "kfifo_alloc failed\n");
756 error = PTR_ERR(fujitsu_hotkey->fifo); 756 error = PTR_ERR(fujitsu_hotkey->fifo);
757 goto err_stop; 757 goto err_stop;
758 } 758 }
759 759
760 fujitsu_hotkey->input = input = input_allocate_device(); 760 fujitsu_hotkey->input = input = input_allocate_device();
761 if (!input) { 761 if (!input) {
762 error = -ENOMEM; 762 error = -ENOMEM;
763 goto err_uninstall_notify; 763 goto err_uninstall_notify;
764 } 764 }
765 765
766 snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys), 766 snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys),
767 "%s/video/input0", acpi_device_hid(device)); 767 "%s/video/input0", acpi_device_hid(device));
768 768
769 input->name = acpi_device_name(device); 769 input->name = acpi_device_name(device);
770 input->phys = fujitsu_hotkey->phys; 770 input->phys = fujitsu_hotkey->phys;
771 input->id.bustype = BUS_HOST; 771 input->id.bustype = BUS_HOST;
772 input->id.product = 0x06; 772 input->id.product = 0x06;
773 input->dev.parent = &device->dev; 773 input->dev.parent = &device->dev;
774 input->evbit[0] = BIT(EV_KEY); 774 input->evbit[0] = BIT(EV_KEY);
775 set_bit(fujitsu->keycode1, input->keybit); 775 set_bit(fujitsu->keycode1, input->keybit);
776 set_bit(fujitsu->keycode2, input->keybit); 776 set_bit(fujitsu->keycode2, input->keybit);
777 set_bit(fujitsu->keycode3, input->keybit); 777 set_bit(fujitsu->keycode3, input->keybit);
778 set_bit(fujitsu->keycode4, input->keybit); 778 set_bit(fujitsu->keycode4, input->keybit);
779 set_bit(KEY_UNKNOWN, input->keybit); 779 set_bit(KEY_UNKNOWN, input->keybit);
780 780
781 error = input_register_device(input); 781 error = input_register_device(input);
782 if (error) 782 if (error)
783 goto err_free_input_dev; 783 goto err_free_input_dev;
784 784
785 result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state); 785 result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state);
786 if (result) { 786 if (result) {
787 printk(KERN_ERR "Error reading power state\n"); 787 printk(KERN_ERR "Error reading power state\n");
788 goto end; 788 goto end;
789 } 789 }
790 790
791 printk(KERN_INFO PREFIX "%s [%s] (%s)\n", 791 printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
792 acpi_device_name(device), acpi_device_bid(device), 792 acpi_device_name(device), acpi_device_bid(device),
793 !device->power.state ? "on" : "off"); 793 !device->power.state ? "on" : "off");
794 794
795 fujitsu_hotkey->dev = device; 795 fujitsu_hotkey->dev = device;
796 796
797 if (ACPI_SUCCESS 797 if (ACPI_SUCCESS
798 (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) { 798 (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) {
799 vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); 799 vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n");
800 if (ACPI_FAILURE 800 if (ACPI_FAILURE
801 (acpi_evaluate_object 801 (acpi_evaluate_object
802 (device->handle, METHOD_NAME__INI, NULL, NULL))) 802 (device->handle, METHOD_NAME__INI, NULL, NULL)))
803 printk(KERN_ERR "_INI Method failed\n"); 803 printk(KERN_ERR "_INI Method failed\n");
804 } 804 }
805 805
806 i = 0; /* Discard hotkey ringbuffer */ 806 i = 0; /* Discard hotkey ringbuffer */
807 while (get_irb() != 0 && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) ; 807 while (get_irb() != 0 && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) ;
808 vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i); 808 vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);
809 809
810 return result; 810 return result;
811 811
812 end: 812 end:
813 err_free_input_dev: 813 err_free_input_dev:
814 input_free_device(input); 814 input_free_device(input);
815 err_uninstall_notify: 815 err_uninstall_notify:
816 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, 816 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
817 acpi_fujitsu_hotkey_notify); 817 acpi_fujitsu_hotkey_notify);
818 kfifo_free(fujitsu_hotkey->fifo); 818 kfifo_free(fujitsu_hotkey->fifo);
819 err_stop: 819 err_stop:
820 820
821 return result; 821 return result;
822 } 822 }
823 823
824 static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) 824 static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
825 { 825 {
826 acpi_status status; 826 acpi_status status;
827 struct fujitsu_hotkey_t *fujitsu_hotkey = NULL; 827 struct fujitsu_hotkey_t *fujitsu_hotkey = NULL;
828 828
829 if (!device || !acpi_driver_data(device)) 829 if (!device || !acpi_driver_data(device))
830 return -EINVAL; 830 return -EINVAL;
831 831
832 fujitsu_hotkey = acpi_driver_data(device); 832 fujitsu_hotkey = acpi_driver_data(device);
833 833
834 status = acpi_remove_notify_handler(fujitsu_hotkey->acpi_handle, 834 status = acpi_remove_notify_handler(fujitsu_hotkey->acpi_handle,
835 ACPI_DEVICE_NOTIFY, 835 ACPI_DEVICE_NOTIFY,
836 acpi_fujitsu_hotkey_notify); 836 acpi_fujitsu_hotkey_notify);
837 837
838 fujitsu_hotkey->acpi_handle = NULL; 838 fujitsu_hotkey->acpi_handle = NULL;
839 839
840 kfifo_free(fujitsu_hotkey->fifo); 840 kfifo_free(fujitsu_hotkey->fifo);
841 841
842 return 0; 842 return 0;
843 } 843 }
844 844
845 static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, 845 static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
846 void *data) 846 void *data)
847 { 847 {
848 struct input_dev *input; 848 struct input_dev *input;
849 int keycode, keycode_r; 849 int keycode, keycode_r;
850 unsigned int irb = 1; 850 unsigned int irb = 1;
851 int i, status; 851 int i, status;
852 852
853 input = fujitsu_hotkey->input; 853 input = fujitsu_hotkey->input;
854 854
855 vdbg_printk(FUJLAPTOP_DBG_TRACE, "Hotkey event\n"); 855 vdbg_printk(FUJLAPTOP_DBG_TRACE, "Hotkey event\n");
856 856
857 switch (event) { 857 switch (event) {
858 case ACPI_FUJITSU_NOTIFY_CODE1: 858 case ACPI_FUJITSU_NOTIFY_CODE1:
859 i = 0; 859 i = 0;
860 while ((irb = get_irb()) != 0 860 while ((irb = get_irb()) != 0
861 && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) { 861 && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) {
862 vdbg_printk(FUJLAPTOP_DBG_TRACE, "GIRB result [%x]\n", 862 vdbg_printk(FUJLAPTOP_DBG_TRACE, "GIRB result [%x]\n",
863 irb); 863 irb);
864 864
865 switch (irb & 0x4ff) { 865 switch (irb & 0x4ff) {
866 case KEY1_CODE: 866 case KEY1_CODE:
867 keycode = fujitsu->keycode1; 867 keycode = fujitsu->keycode1;
868 break; 868 break;
869 case KEY2_CODE: 869 case KEY2_CODE:
870 keycode = fujitsu->keycode2; 870 keycode = fujitsu->keycode2;
871 break; 871 break;
872 case KEY3_CODE: 872 case KEY3_CODE:
873 keycode = fujitsu->keycode3; 873 keycode = fujitsu->keycode3;
874 break; 874 break;
875 case KEY4_CODE: 875 case KEY4_CODE:
876 keycode = fujitsu->keycode4; 876 keycode = fujitsu->keycode4;
877 break; 877 break;
878 case 0: 878 case 0:
879 keycode = 0; 879 keycode = 0;
880 break; 880 break;
881 default: 881 default:
882 vdbg_printk(FUJLAPTOP_DBG_WARN, 882 vdbg_printk(FUJLAPTOP_DBG_WARN,
883 "Unknown GIRB result [%x]\n", irb); 883 "Unknown GIRB result [%x]\n", irb);
884 keycode = -1; 884 keycode = -1;
885 break; 885 break;
886 } 886 }
887 if (keycode > 0) { 887 if (keycode > 0) {
888 vdbg_printk(FUJLAPTOP_DBG_TRACE, 888 vdbg_printk(FUJLAPTOP_DBG_TRACE,
889 "Push keycode into ringbuffer [%d]\n", 889 "Push keycode into ringbuffer [%d]\n",
890 keycode); 890 keycode);
891 status = kfifo_put(fujitsu_hotkey->fifo, 891 status = kfifo_put(fujitsu_hotkey->fifo,
892 (unsigned char *)&keycode, 892 (unsigned char *)&keycode,
893 sizeof(keycode)); 893 sizeof(keycode));
894 if (status != sizeof(keycode)) { 894 if (status != sizeof(keycode)) {
895 vdbg_printk(FUJLAPTOP_DBG_WARN, 895 vdbg_printk(FUJLAPTOP_DBG_WARN,
896 "Could not push keycode [0x%x]\n", 896 "Could not push keycode [0x%x]\n",
897 keycode); 897 keycode);
898 } else { 898 } else {
899 input_report_key(input, keycode, 1); 899 input_report_key(input, keycode, 1);
900 input_sync(input); 900 input_sync(input);
901 } 901 }
902 } else if (keycode == 0) { 902 } else if (keycode == 0) {
903 while ((status = 903 while ((status =
904 kfifo_get 904 kfifo_get
905 (fujitsu_hotkey->fifo, (unsigned char *) 905 (fujitsu_hotkey->fifo, (unsigned char *)
906 &keycode_r, 906 &keycode_r,
907 sizeof 907 sizeof
908 (keycode_r))) == sizeof(keycode_r)) { 908 (keycode_r))) == sizeof(keycode_r)) {
909 input_report_key(input, keycode_r, 0); 909 input_report_key(input, keycode_r, 0);
910 input_sync(input); 910 input_sync(input);
911 vdbg_printk(FUJLAPTOP_DBG_TRACE, 911 vdbg_printk(FUJLAPTOP_DBG_TRACE,
912 "Pop keycode from ringbuffer [%d]\n", 912 "Pop keycode from ringbuffer [%d]\n",
913 keycode_r); 913 keycode_r);
914 } 914 }
915 } 915 }
916 } 916 }
917 917
918 break; 918 break;
919 default: 919 default:
920 keycode = KEY_UNKNOWN; 920 keycode = KEY_UNKNOWN;
921 vdbg_printk(FUJLAPTOP_DBG_WARN, 921 vdbg_printk(FUJLAPTOP_DBG_WARN,
922 "Unsupported event [0x%x]\n", event); 922 "Unsupported event [0x%x]\n", event);
923 input_report_key(input, keycode, 1); 923 input_report_key(input, keycode, 1);
924 input_sync(input); 924 input_sync(input);
925 input_report_key(input, keycode, 0); 925 input_report_key(input, keycode, 0);
926 input_sync(input); 926 input_sync(input);
927 break; 927 break;
928 } 928 }
929 929
930 return; 930 return;
931 } 931 }
932 932
933 /* Initialization */ 933 /* Initialization */
934 934
935 static const struct acpi_device_id fujitsu_device_ids[] = { 935 static const struct acpi_device_id fujitsu_device_ids[] = {
936 {ACPI_FUJITSU_HID, 0}, 936 {ACPI_FUJITSU_HID, 0},
937 {"", 0}, 937 {"", 0},
938 }; 938 };
939 939
940 static struct acpi_driver acpi_fujitsu_driver = { 940 static struct acpi_driver acpi_fujitsu_driver = {
941 .name = ACPI_FUJITSU_DRIVER_NAME, 941 .name = ACPI_FUJITSU_DRIVER_NAME,
942 .class = ACPI_FUJITSU_CLASS, 942 .class = ACPI_FUJITSU_CLASS,
943 .ids = fujitsu_device_ids, 943 .ids = fujitsu_device_ids,
944 .ops = { 944 .ops = {
945 .add = acpi_fujitsu_add, 945 .add = acpi_fujitsu_add,
946 .remove = acpi_fujitsu_remove, 946 .remove = acpi_fujitsu_remove,
947 }, 947 },
948 }; 948 };
949 949
950 static const struct acpi_device_id fujitsu_hotkey_device_ids[] = { 950 static const struct acpi_device_id fujitsu_hotkey_device_ids[] = {
951 {ACPI_FUJITSU_HOTKEY_HID, 0}, 951 {ACPI_FUJITSU_HOTKEY_HID, 0},
952 {"", 0}, 952 {"", 0},
953 }; 953 };
954 954
955 static struct acpi_driver acpi_fujitsu_hotkey_driver = { 955 static struct acpi_driver acpi_fujitsu_hotkey_driver = {
956 .name = ACPI_FUJITSU_HOTKEY_DRIVER_NAME, 956 .name = ACPI_FUJITSU_HOTKEY_DRIVER_NAME,
957 .class = ACPI_FUJITSU_CLASS, 957 .class = ACPI_FUJITSU_CLASS,
958 .ids = fujitsu_hotkey_device_ids, 958 .ids = fujitsu_hotkey_device_ids,
959 .ops = { 959 .ops = {
960 .add = acpi_fujitsu_hotkey_add, 960 .add = acpi_fujitsu_hotkey_add,
961 .remove = acpi_fujitsu_hotkey_remove, 961 .remove = acpi_fujitsu_hotkey_remove,
962 }, 962 },
963 }; 963 };
964 964
965 static int __init fujitsu_init(void) 965 static int __init fujitsu_init(void)
966 { 966 {
967 int ret, result, max_brightness; 967 int ret, result, max_brightness;
968 968
969 if (acpi_disabled) 969 if (acpi_disabled)
970 return -ENODEV; 970 return -ENODEV;
971 971
972 fujitsu = kmalloc(sizeof(struct fujitsu_t), GFP_KERNEL); 972 fujitsu = kmalloc(sizeof(struct fujitsu_t), GFP_KERNEL);
973 if (!fujitsu) 973 if (!fujitsu)
974 return -ENOMEM; 974 return -ENOMEM;
975 memset(fujitsu, 0, sizeof(struct fujitsu_t)); 975 memset(fujitsu, 0, sizeof(struct fujitsu_t));
976 fujitsu->keycode1 = KEY_PROG1; 976 fujitsu->keycode1 = KEY_PROG1;
977 fujitsu->keycode2 = KEY_PROG2; 977 fujitsu->keycode2 = KEY_PROG2;
978 fujitsu->keycode3 = KEY_PROG3; 978 fujitsu->keycode3 = KEY_PROG3;
979 fujitsu->keycode4 = KEY_PROG4; 979 fujitsu->keycode4 = KEY_PROG4;
980 dmi_check_system(fujitsu_dmi_table); 980 dmi_check_system(fujitsu_dmi_table);
981 981
982 result = acpi_bus_register_driver(&acpi_fujitsu_driver); 982 result = acpi_bus_register_driver(&acpi_fujitsu_driver);
983 if (result < 0) { 983 if (result < 0) {
984 ret = -ENODEV; 984 ret = -ENODEV;
985 goto fail_acpi; 985 goto fail_acpi;
986 } 986 }
987 987
988 /* Register platform stuff */ 988 /* Register platform stuff */
989 989
990 fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1); 990 fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1);
991 if (!fujitsu->pf_device) { 991 if (!fujitsu->pf_device) {
992 ret = -ENOMEM; 992 ret = -ENOMEM;
993 goto fail_platform_driver; 993 goto fail_platform_driver;
994 } 994 }
995 995
996 ret = platform_device_add(fujitsu->pf_device); 996 ret = platform_device_add(fujitsu->pf_device);
997 if (ret) 997 if (ret)
998 goto fail_platform_device1; 998 goto fail_platform_device1;
999 999
1000 ret = 1000 ret =
1001 sysfs_create_group(&fujitsu->pf_device->dev.kobj, 1001 sysfs_create_group(&fujitsu->pf_device->dev.kobj,
1002 &fujitsupf_attribute_group); 1002 &fujitsupf_attribute_group);
1003 if (ret) 1003 if (ret)
1004 goto fail_platform_device2; 1004 goto fail_platform_device2;
1005 1005
1006 /* Register backlight stuff */ 1006 /* Register backlight stuff */
1007 1007
1008 fujitsu->bl_device = 1008 if (!acpi_video_backlight_support()) {
1009 backlight_device_register("fujitsu-laptop", NULL, NULL, 1009 fujitsu->bl_device =
1010 &fujitsubl_ops); 1010 backlight_device_register("fujitsu-laptop", NULL, NULL,
1011 if (IS_ERR(fujitsu->bl_device)) 1011 &fujitsubl_ops);
1012 return PTR_ERR(fujitsu->bl_device); 1012 if (IS_ERR(fujitsu->bl_device))
1013 return PTR_ERR(fujitsu->bl_device);
1014 max_brightness = fujitsu->max_brightness;
1015 fujitsu->bl_device->props.max_brightness = max_brightness - 1;
1016 fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
1017 }
1013 1018
1014 max_brightness = fujitsu->max_brightness;
1015
1016 fujitsu->bl_device->props.max_brightness = max_brightness - 1;
1017 fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
1018
1019 ret = platform_driver_register(&fujitsupf_driver); 1019 ret = platform_driver_register(&fujitsupf_driver);
1020 if (ret) 1020 if (ret)
1021 goto fail_backlight; 1021 goto fail_backlight;
1022 1022
1023 /* Register hotkey driver */ 1023 /* Register hotkey driver */
1024 1024
1025 fujitsu_hotkey = kmalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL); 1025 fujitsu_hotkey = kmalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL);
1026 if (!fujitsu_hotkey) { 1026 if (!fujitsu_hotkey) {
1027 ret = -ENOMEM; 1027 ret = -ENOMEM;
1028 goto fail_hotkey; 1028 goto fail_hotkey;
1029 } 1029 }
1030 memset(fujitsu_hotkey, 0, sizeof(struct fujitsu_hotkey_t)); 1030 memset(fujitsu_hotkey, 0, sizeof(struct fujitsu_hotkey_t));
1031 1031
1032 result = acpi_bus_register_driver(&acpi_fujitsu_hotkey_driver); 1032 result = acpi_bus_register_driver(&acpi_fujitsu_hotkey_driver);
1033 if (result < 0) { 1033 if (result < 0) {
1034 ret = -ENODEV; 1034 ret = -ENODEV;
1035 goto fail_hotkey1; 1035 goto fail_hotkey1;
1036 } 1036 }
1037 1037
1038 printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION 1038 printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION
1039 " successfully loaded.\n"); 1039 " successfully loaded.\n");
1040 1040
1041 return 0; 1041 return 0;
1042 1042
1043 fail_hotkey1: 1043 fail_hotkey1:
1044 1044
1045 kfree(fujitsu_hotkey); 1045 kfree(fujitsu_hotkey);
1046 1046
1047 fail_hotkey: 1047 fail_hotkey:
1048 1048
1049 platform_driver_unregister(&fujitsupf_driver); 1049 platform_driver_unregister(&fujitsupf_driver);
1050 1050
1051 fail_backlight: 1051 fail_backlight:
1052 1052
1053 backlight_device_unregister(fujitsu->bl_device); 1053 if (fujitsu->bl_device)
1054 backlight_device_unregister(fujitsu->bl_device);
1054 1055
1055 fail_platform_device2: 1056 fail_platform_device2:
1056 1057
1057 platform_device_del(fujitsu->pf_device); 1058 platform_device_del(fujitsu->pf_device);
1058 1059
1059 fail_platform_device1: 1060 fail_platform_device1:
1060 1061
1061 platform_device_put(fujitsu->pf_device); 1062 platform_device_put(fujitsu->pf_device);
1062 1063
1063 fail_platform_driver: 1064 fail_platform_driver:
1064 1065
1065 acpi_bus_unregister_driver(&acpi_fujitsu_driver); 1066 acpi_bus_unregister_driver(&acpi_fujitsu_driver);
1066 1067
1067 fail_acpi: 1068 fail_acpi:
1068 1069
1069 kfree(fujitsu); 1070 kfree(fujitsu);
1070 1071
1071 return ret; 1072 return ret;
1072 } 1073 }
1073 1074
1074 static void __exit fujitsu_cleanup(void) 1075 static void __exit fujitsu_cleanup(void)
1075 { 1076 {
1076 sysfs_remove_group(&fujitsu->pf_device->dev.kobj, 1077 sysfs_remove_group(&fujitsu->pf_device->dev.kobj,
1077 &fujitsupf_attribute_group); 1078 &fujitsupf_attribute_group);
1078 platform_device_unregister(fujitsu->pf_device); 1079 platform_device_unregister(fujitsu->pf_device);
1079 platform_driver_unregister(&fujitsupf_driver); 1080 platform_driver_unregister(&fujitsupf_driver);
1080 backlight_device_unregister(fujitsu->bl_device); 1081 if (fujitsu->bl_device)
1082 backlight_device_unregister(fujitsu->bl_device);
1081 1083
1082 acpi_bus_unregister_driver(&acpi_fujitsu_driver); 1084 acpi_bus_unregister_driver(&acpi_fujitsu_driver);
1083 1085
1084 kfree(fujitsu); 1086 kfree(fujitsu);
1085 1087
1086 acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver); 1088 acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver);
1087 1089
1088 kfree(fujitsu_hotkey); 1090 kfree(fujitsu_hotkey);
1089 1091
1090 printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); 1092 printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n");
1091 } 1093 }
1092 1094
1093 module_init(fujitsu_init); 1095 module_init(fujitsu_init);
1094 module_exit(fujitsu_cleanup); 1096 module_exit(fujitsu_cleanup);
1095 1097
1096 module_param(use_alt_lcd_levels, uint, 0644); 1098 module_param(use_alt_lcd_levels, uint, 0644);
1097 MODULE_PARM_DESC(use_alt_lcd_levels, 1099 MODULE_PARM_DESC(use_alt_lcd_levels,
1098 "Use alternative interface for lcd_levels (needed for Lifebook s6410)."); 1100 "Use alternative interface for lcd_levels (needed for Lifebook s6410).");
1099 module_param(disable_brightness_keys, uint, 0644); 1101 module_param(disable_brightness_keys, uint, 0644);
1100 MODULE_PARM_DESC(disable_brightness_keys, 1102 MODULE_PARM_DESC(disable_brightness_keys,
1101 "Disable brightness keys (eg. if they are already handled by the generic ACPI_VIDEO device)."); 1103 "Disable brightness keys (eg. if they are already handled by the generic ACPI_VIDEO device).");
1102 module_param(disable_brightness_adjust, uint, 0644); 1104 module_param(disable_brightness_adjust, uint, 0644);
1103 MODULE_PARM_DESC(disable_brightness_adjust, "Disable brightness adjustment ."); 1105 MODULE_PARM_DESC(disable_brightness_adjust, "Disable brightness adjustment .");
1104 #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG 1106 #ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
1105 module_param_named(debug, dbg_level, uint, 0644); 1107 module_param_named(debug, dbg_level, uint, 0644);
1106 MODULE_PARM_DESC(debug, "Sets debug level bit-mask"); 1108 MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
1107 #endif 1109 #endif
1108 1110
1109 MODULE_AUTHOR("Jonathan Woithe, Peter Gruber"); 1111 MODULE_AUTHOR("Jonathan Woithe, Peter Gruber");
1110 MODULE_DESCRIPTION("Fujitsu laptop extras support"); 1112 MODULE_DESCRIPTION("Fujitsu laptop extras support");
1111 MODULE_VERSION(FUJITSU_DRIVER_VERSION); 1113 MODULE_VERSION(FUJITSU_DRIVER_VERSION);
1112 MODULE_LICENSE("GPL"); 1114 MODULE_LICENSE("GPL");
1113 1115
1114 MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*"); 1116 MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*");
1115 MODULE_ALIAS("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*"); 1117 MODULE_ALIAS("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*");
1116 1118
1117 static struct pnp_device_id pnp_ids[] = { 1119 static struct pnp_device_id pnp_ids[] = {
1118 {.id = "FUJ02bf"}, 1120 {.id = "FUJ02bf"},
1119 {.id = "FUJ02B1"}, 1121 {.id = "FUJ02B1"},
1120 {.id = "FUJ02E3"}, 1122 {.id = "FUJ02E3"},
drivers/misc/msi-laptop.c
1 /*-*-linux-c-*-*/ 1 /*-*-linux-c-*-*/
2 2
3 /* 3 /*
4 Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de> 4 Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
5 5
6 This program is free software; you can redistribute it and/or modify 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 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 8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version. 9 (at your option) any later version.
10 10
11 This program is distributed in the hope that it will be useful, but 11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of 12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details. 14 General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 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 17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA. 19 02110-1301, USA.
20 */ 20 */
21 21
22 /* 22 /*
23 * msi-laptop.c - MSI S270 laptop support. This laptop is sold under 23 * msi-laptop.c - MSI S270 laptop support. This laptop is sold under
24 * various brands, including "Cytron/TCM/Medion/Tchibo MD96100". 24 * various brands, including "Cytron/TCM/Medion/Tchibo MD96100".
25 * 25 *
26 * Driver also supports S271, S420 models. 26 * Driver also supports S271, S420 models.
27 * 27 *
28 * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/: 28 * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/:
29 * 29 *
30 * lcd_level - Screen brightness: contains a single integer in the 30 * lcd_level - Screen brightness: contains a single integer in the
31 * range 0..8. (rw) 31 * range 0..8. (rw)
32 * 32 *
33 * auto_brightness - Enable automatic brightness control: contains 33 * auto_brightness - Enable automatic brightness control: contains
34 * either 0 or 1. If set to 1 the hardware adjusts the screen 34 * either 0 or 1. If set to 1 the hardware adjusts the screen
35 * brightness automatically when the power cord is 35 * brightness automatically when the power cord is
36 * plugged/unplugged. (rw) 36 * plugged/unplugged. (rw)
37 * 37 *
38 * wlan - WLAN subsystem enabled: contains either 0 or 1. (ro) 38 * wlan - WLAN subsystem enabled: contains either 0 or 1. (ro)
39 * 39 *
40 * bluetooth - Bluetooth subsystem enabled: contains either 0 or 1 40 * bluetooth - Bluetooth subsystem enabled: contains either 0 or 1
41 * Please note that this file is constantly 0 if no Bluetooth 41 * Please note that this file is constantly 0 if no Bluetooth
42 * hardware is available. (ro) 42 * hardware is available. (ro)
43 * 43 *
44 * In addition to these platform device attributes the driver 44 * In addition to these platform device attributes the driver
45 * registers itself in the Linux backlight control subsystem and is 45 * registers itself in the Linux backlight control subsystem and is
46 * available to userspace under /sys/class/backlight/msi-laptop-bl/. 46 * available to userspace under /sys/class/backlight/msi-laptop-bl/.
47 * 47 *
48 * This driver might work on other laptops produced by MSI. If you 48 * This driver might work on other laptops produced by MSI. If you
49 * want to try it you can pass force=1 as argument to the module which 49 * want to try it you can pass force=1 as argument to the module which
50 * will force it to load even when the DMI data doesn't identify the 50 * will force it to load even when the DMI data doesn't identify the
51 * laptop as MSI S270. YMMV. 51 * laptop as MSI S270. YMMV.
52 */ 52 */
53 53
54 #include <linux/module.h> 54 #include <linux/module.h>
55 #include <linux/kernel.h> 55 #include <linux/kernel.h>
56 #include <linux/init.h> 56 #include <linux/init.h>
57 #include <linux/acpi.h> 57 #include <linux/acpi.h>
58 #include <linux/dmi.h> 58 #include <linux/dmi.h>
59 #include <linux/backlight.h> 59 #include <linux/backlight.h>
60 #include <linux/platform_device.h> 60 #include <linux/platform_device.h>
61 61
62 #define MSI_DRIVER_VERSION "0.5" 62 #define MSI_DRIVER_VERSION "0.5"
63 63
64 #define MSI_LCD_LEVEL_MAX 9 64 #define MSI_LCD_LEVEL_MAX 9
65 65
66 #define MSI_EC_COMMAND_WIRELESS 0x10 66 #define MSI_EC_COMMAND_WIRELESS 0x10
67 #define MSI_EC_COMMAND_LCD_LEVEL 0x11 67 #define MSI_EC_COMMAND_LCD_LEVEL 0x11
68 68
69 static int force; 69 static int force;
70 module_param(force, bool, 0); 70 module_param(force, bool, 0);
71 MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); 71 MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
72 72
73 static int auto_brightness; 73 static int auto_brightness;
74 module_param(auto_brightness, int, 0); 74 module_param(auto_brightness, int, 0);
75 MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)"); 75 MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)");
76 76
77 /* Hardware access */ 77 /* Hardware access */
78 78
79 static int set_lcd_level(int level) 79 static int set_lcd_level(int level)
80 { 80 {
81 u8 buf[2]; 81 u8 buf[2];
82 82
83 if (level < 0 || level >= MSI_LCD_LEVEL_MAX) 83 if (level < 0 || level >= MSI_LCD_LEVEL_MAX)
84 return -EINVAL; 84 return -EINVAL;
85 85
86 buf[0] = 0x80; 86 buf[0] = 0x80;
87 buf[1] = (u8) (level*31); 87 buf[1] = (u8) (level*31);
88 88
89 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0, 1); 89 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0, 1);
90 } 90 }
91 91
92 static int get_lcd_level(void) 92 static int get_lcd_level(void)
93 { 93 {
94 u8 wdata = 0, rdata; 94 u8 wdata = 0, rdata;
95 int result; 95 int result;
96 96
97 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1, 1); 97 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1, 1);
98 if (result < 0) 98 if (result < 0)
99 return result; 99 return result;
100 100
101 return (int) rdata / 31; 101 return (int) rdata / 31;
102 } 102 }
103 103
104 static int get_auto_brightness(void) 104 static int get_auto_brightness(void)
105 { 105 {
106 u8 wdata = 4, rdata; 106 u8 wdata = 4, rdata;
107 int result; 107 int result;
108 108
109 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1, 1); 109 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1, 1);
110 if (result < 0) 110 if (result < 0)
111 return result; 111 return result;
112 112
113 return !!(rdata & 8); 113 return !!(rdata & 8);
114 } 114 }
115 115
116 static int set_auto_brightness(int enable) 116 static int set_auto_brightness(int enable)
117 { 117 {
118 u8 wdata[2], rdata; 118 u8 wdata[2], rdata;
119 int result; 119 int result;
120 120
121 wdata[0] = 4; 121 wdata[0] = 4;
122 122
123 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1, 1); 123 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1, 1);
124 if (result < 0) 124 if (result < 0)
125 return result; 125 return result;
126 126
127 wdata[0] = 0x84; 127 wdata[0] = 0x84;
128 wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); 128 wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0);
129 129
130 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1); 130 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1);
131 } 131 }
132 132
133 static int get_wireless_state(int *wlan, int *bluetooth) 133 static int get_wireless_state(int *wlan, int *bluetooth)
134 { 134 {
135 u8 wdata = 0, rdata; 135 u8 wdata = 0, rdata;
136 int result; 136 int result;
137 137
138 result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1, 1); 138 result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1, 1);
139 if (result < 0) 139 if (result < 0)
140 return -1; 140 return -1;
141 141
142 if (wlan) 142 if (wlan)
143 *wlan = !!(rdata & 8); 143 *wlan = !!(rdata & 8);
144 144
145 if (bluetooth) 145 if (bluetooth)
146 *bluetooth = !!(rdata & 128); 146 *bluetooth = !!(rdata & 128);
147 147
148 return 0; 148 return 0;
149 } 149 }
150 150
151 /* Backlight device stuff */ 151 /* Backlight device stuff */
152 152
153 static int bl_get_brightness(struct backlight_device *b) 153 static int bl_get_brightness(struct backlight_device *b)
154 { 154 {
155 return get_lcd_level(); 155 return get_lcd_level();
156 } 156 }
157 157
158 158
159 static int bl_update_status(struct backlight_device *b) 159 static int bl_update_status(struct backlight_device *b)
160 { 160 {
161 return set_lcd_level(b->props.brightness); 161 return set_lcd_level(b->props.brightness);
162 } 162 }
163 163
164 static struct backlight_ops msibl_ops = { 164 static struct backlight_ops msibl_ops = {
165 .get_brightness = bl_get_brightness, 165 .get_brightness = bl_get_brightness,
166 .update_status = bl_update_status, 166 .update_status = bl_update_status,
167 }; 167 };
168 168
169 static struct backlight_device *msibl_device; 169 static struct backlight_device *msibl_device;
170 170
171 /* Platform device */ 171 /* Platform device */
172 172
173 static ssize_t show_wlan(struct device *dev, 173 static ssize_t show_wlan(struct device *dev,
174 struct device_attribute *attr, char *buf) 174 struct device_attribute *attr, char *buf)
175 { 175 {
176 176
177 int ret, enabled; 177 int ret, enabled;
178 178
179 ret = get_wireless_state(&enabled, NULL); 179 ret = get_wireless_state(&enabled, NULL);
180 if (ret < 0) 180 if (ret < 0)
181 return ret; 181 return ret;
182 182
183 return sprintf(buf, "%i\n", enabled); 183 return sprintf(buf, "%i\n", enabled);
184 } 184 }
185 185
186 static ssize_t show_bluetooth(struct device *dev, 186 static ssize_t show_bluetooth(struct device *dev,
187 struct device_attribute *attr, char *buf) 187 struct device_attribute *attr, char *buf)
188 { 188 {
189 189
190 int ret, enabled; 190 int ret, enabled;
191 191
192 ret = get_wireless_state(NULL, &enabled); 192 ret = get_wireless_state(NULL, &enabled);
193 if (ret < 0) 193 if (ret < 0)
194 return ret; 194 return ret;
195 195
196 return sprintf(buf, "%i\n", enabled); 196 return sprintf(buf, "%i\n", enabled);
197 } 197 }
198 198
199 static ssize_t show_lcd_level(struct device *dev, 199 static ssize_t show_lcd_level(struct device *dev,
200 struct device_attribute *attr, char *buf) 200 struct device_attribute *attr, char *buf)
201 { 201 {
202 202
203 int ret; 203 int ret;
204 204
205 ret = get_lcd_level(); 205 ret = get_lcd_level();
206 if (ret < 0) 206 if (ret < 0)
207 return ret; 207 return ret;
208 208
209 return sprintf(buf, "%i\n", ret); 209 return sprintf(buf, "%i\n", ret);
210 } 210 }
211 211
212 static ssize_t store_lcd_level(struct device *dev, 212 static ssize_t store_lcd_level(struct device *dev,
213 struct device_attribute *attr, const char *buf, size_t count) 213 struct device_attribute *attr, const char *buf, size_t count)
214 { 214 {
215 215
216 int level, ret; 216 int level, ret;
217 217
218 if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX)) 218 if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX))
219 return -EINVAL; 219 return -EINVAL;
220 220
221 ret = set_lcd_level(level); 221 ret = set_lcd_level(level);
222 if (ret < 0) 222 if (ret < 0)
223 return ret; 223 return ret;
224 224
225 return count; 225 return count;
226 } 226 }
227 227
228 static ssize_t show_auto_brightness(struct device *dev, 228 static ssize_t show_auto_brightness(struct device *dev,
229 struct device_attribute *attr, char *buf) 229 struct device_attribute *attr, char *buf)
230 { 230 {
231 231
232 int ret; 232 int ret;
233 233
234 ret = get_auto_brightness(); 234 ret = get_auto_brightness();
235 if (ret < 0) 235 if (ret < 0)
236 return ret; 236 return ret;
237 237
238 return sprintf(buf, "%i\n", ret); 238 return sprintf(buf, "%i\n", ret);
239 } 239 }
240 240
241 static ssize_t store_auto_brightness(struct device *dev, 241 static ssize_t store_auto_brightness(struct device *dev,
242 struct device_attribute *attr, const char *buf, size_t count) 242 struct device_attribute *attr, const char *buf, size_t count)
243 { 243 {
244 244
245 int enable, ret; 245 int enable, ret;
246 246
247 if (sscanf(buf, "%i", &enable) != 1 || (enable != (enable & 1))) 247 if (sscanf(buf, "%i", &enable) != 1 || (enable != (enable & 1)))
248 return -EINVAL; 248 return -EINVAL;
249 249
250 ret = set_auto_brightness(enable); 250 ret = set_auto_brightness(enable);
251 if (ret < 0) 251 if (ret < 0)
252 return ret; 252 return ret;
253 253
254 return count; 254 return count;
255 } 255 }
256 256
257 static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); 257 static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
258 static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness); 258 static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness);
259 static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL); 259 static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL);
260 static DEVICE_ATTR(wlan, 0444, show_wlan, NULL); 260 static DEVICE_ATTR(wlan, 0444, show_wlan, NULL);
261 261
262 static struct attribute *msipf_attributes[] = { 262 static struct attribute *msipf_attributes[] = {
263 &dev_attr_lcd_level.attr, 263 &dev_attr_lcd_level.attr,
264 &dev_attr_auto_brightness.attr, 264 &dev_attr_auto_brightness.attr,
265 &dev_attr_bluetooth.attr, 265 &dev_attr_bluetooth.attr,
266 &dev_attr_wlan.attr, 266 &dev_attr_wlan.attr,
267 NULL 267 NULL
268 }; 268 };
269 269
270 static struct attribute_group msipf_attribute_group = { 270 static struct attribute_group msipf_attribute_group = {
271 .attrs = msipf_attributes 271 .attrs = msipf_attributes
272 }; 272 };
273 273
274 static struct platform_driver msipf_driver = { 274 static struct platform_driver msipf_driver = {
275 .driver = { 275 .driver = {
276 .name = "msi-laptop-pf", 276 .name = "msi-laptop-pf",
277 .owner = THIS_MODULE, 277 .owner = THIS_MODULE,
278 } 278 }
279 }; 279 };
280 280
281 static struct platform_device *msipf_device; 281 static struct platform_device *msipf_device;
282 282
283 /* Initialization */ 283 /* Initialization */
284 284
285 static int dmi_check_cb(const struct dmi_system_id *id) 285 static int dmi_check_cb(const struct dmi_system_id *id)
286 { 286 {
287 printk("msi-laptop: Identified laptop model '%s'.\n", id->ident); 287 printk("msi-laptop: Identified laptop model '%s'.\n", id->ident);
288 return 0; 288 return 0;
289 } 289 }
290 290
291 static struct dmi_system_id __initdata msi_dmi_table[] = { 291 static struct dmi_system_id __initdata msi_dmi_table[] = {
292 { 292 {
293 .ident = "MSI S270", 293 .ident = "MSI S270",
294 .matches = { 294 .matches = {
295 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"), 295 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
296 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"), 296 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
297 DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), 297 DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
298 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD") 298 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD")
299 }, 299 },
300 .callback = dmi_check_cb 300 .callback = dmi_check_cb
301 }, 301 },
302 { 302 {
303 .ident = "MSI S271", 303 .ident = "MSI S271",
304 .matches = { 304 .matches = {
305 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 305 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
306 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1058"), 306 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1058"),
307 DMI_MATCH(DMI_PRODUCT_VERSION, "0581"), 307 DMI_MATCH(DMI_PRODUCT_VERSION, "0581"),
308 DMI_MATCH(DMI_BOARD_NAME, "MS-1058") 308 DMI_MATCH(DMI_BOARD_NAME, "MS-1058")
309 }, 309 },
310 .callback = dmi_check_cb 310 .callback = dmi_check_cb
311 }, 311 },
312 { 312 {
313 .ident = "MSI S420", 313 .ident = "MSI S420",
314 .matches = { 314 .matches = {
315 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 315 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
316 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1412"), 316 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1412"),
317 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), 317 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
318 DMI_MATCH(DMI_BOARD_NAME, "MS-1412") 318 DMI_MATCH(DMI_BOARD_NAME, "MS-1412")
319 }, 319 },
320 .callback = dmi_check_cb 320 .callback = dmi_check_cb
321 }, 321 },
322 { 322 {
323 .ident = "Medion MD96100", 323 .ident = "Medion MD96100",
324 .matches = { 324 .matches = {
325 DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"), 325 DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
326 DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"), 326 DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
327 DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), 327 DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
328 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD") 328 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD")
329 }, 329 },
330 .callback = dmi_check_cb 330 .callback = dmi_check_cb
331 }, 331 },
332 { } 332 { }
333 }; 333 };
334 334
335 static int __init msi_init(void) 335 static int __init msi_init(void)
336 { 336 {
337 int ret; 337 int ret;
338 338
339 if (acpi_disabled) 339 if (acpi_disabled)
340 return -ENODEV; 340 return -ENODEV;
341 341
342 if (!force && !dmi_check_system(msi_dmi_table)) 342 if (!force && !dmi_check_system(msi_dmi_table))
343 return -ENODEV; 343 return -ENODEV;
344 344
345 if (auto_brightness < 0 || auto_brightness > 2) 345 if (auto_brightness < 0 || auto_brightness > 2)
346 return -EINVAL; 346 return -EINVAL;
347 347
348 /* Register backlight stuff */ 348 /* Register backlight stuff */
349 349
350 msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL, 350 if (acpi_video_backlight_support()) {
351 &msibl_ops); 351 printk(KERN_INFO "MSI: Brightness ignored, must be controlled "
352 if (IS_ERR(msibl_device)) 352 "by ACPI video driver\n");
353 return PTR_ERR(msibl_device); 353 } else {
354 354 msibl_device = backlight_device_register("msi-laptop-bl", NULL,
355 msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1; 355 NULL, &msibl_ops);
356 if (IS_ERR(msibl_device))
357 return PTR_ERR(msibl_device);
358 msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
359 }
356 360
357 ret = platform_driver_register(&msipf_driver); 361 ret = platform_driver_register(&msipf_driver);
358 if (ret) 362 if (ret)
359 goto fail_backlight; 363 goto fail_backlight;
360 364
361 /* Register platform stuff */ 365 /* Register platform stuff */
362 366
363 msipf_device = platform_device_alloc("msi-laptop-pf", -1); 367 msipf_device = platform_device_alloc("msi-laptop-pf", -1);
364 if (!msipf_device) { 368 if (!msipf_device) {
365 ret = -ENOMEM; 369 ret = -ENOMEM;
366 goto fail_platform_driver; 370 goto fail_platform_driver;
367 } 371 }
368 372
369 ret = platform_device_add(msipf_device); 373 ret = platform_device_add(msipf_device);
370 if (ret) 374 if (ret)
371 goto fail_platform_device1; 375 goto fail_platform_device1;
372 376
373 ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group); 377 ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group);
374 if (ret) 378 if (ret)
375 goto fail_platform_device2; 379 goto fail_platform_device2;
376 380
377 /* Disable automatic brightness control by default because 381 /* Disable automatic brightness control by default because
378 * this module was probably loaded to do brightness control in 382 * this module was probably loaded to do brightness control in
379 * software. */ 383 * software. */
380 384
381 if (auto_brightness != 2) 385 if (auto_brightness != 2)
382 set_auto_brightness(auto_brightness); 386 set_auto_brightness(auto_brightness);
383 387
384 printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n"); 388 printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n");
385 389
386 return 0; 390 return 0;
387 391
388 fail_platform_device2: 392 fail_platform_device2:
389 393
390 platform_device_del(msipf_device); 394 platform_device_del(msipf_device);
391 395
392 fail_platform_device1: 396 fail_platform_device1:
393 397
394 platform_device_put(msipf_device); 398 platform_device_put(msipf_device);
395 399
396 fail_platform_driver: 400 fail_platform_driver:
397 401
398 platform_driver_unregister(&msipf_driver); 402 platform_driver_unregister(&msipf_driver);
399 403
400 fail_backlight: 404 fail_backlight:
401 405
402 backlight_device_unregister(msibl_device); 406 backlight_device_unregister(msibl_device);
403 407
404 return ret; 408 return ret;
405 } 409 }
406 410
407 static void __exit msi_cleanup(void) 411 static void __exit msi_cleanup(void)
408 { 412 {
409 413
410 sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); 414 sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
411 platform_device_unregister(msipf_device); 415 platform_device_unregister(msipf_device);
412 platform_driver_unregister(&msipf_driver); 416 platform_driver_unregister(&msipf_driver);
413 backlight_device_unregister(msibl_device); 417 backlight_device_unregister(msibl_device);
414 418
415 /* Enable automatic brightness control again */ 419 /* Enable automatic brightness control again */
416 if (auto_brightness != 2) 420 if (auto_brightness != 2)
417 set_auto_brightness(1); 421 set_auto_brightness(1);
418 422
419 printk(KERN_INFO "msi-laptop: driver unloaded.\n"); 423 printk(KERN_INFO "msi-laptop: driver unloaded.\n");
420 } 424 }
421 425
422 module_init(msi_init); 426 module_init(msi_init);
423 module_exit(msi_cleanup); 427 module_exit(msi_cleanup);
424 428
425 MODULE_AUTHOR("Lennart Poettering"); 429 MODULE_AUTHOR("Lennart Poettering");
426 MODULE_DESCRIPTION("MSI Laptop Support"); 430 MODULE_DESCRIPTION("MSI Laptop Support");
427 MODULE_VERSION(MSI_DRIVER_VERSION); 431 MODULE_VERSION(MSI_DRIVER_VERSION);
428 MODULE_LICENSE("GPL"); 432 MODULE_LICENSE("GPL");
429 433
430 MODULE_ALIAS("dmi:*:svnMICRO-STARINT'LCO.,LTD:pnMS-1013:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); 434 MODULE_ALIAS("dmi:*:svnMICRO-STARINT'LCO.,LTD:pnMS-1013:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
431 MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*"); 435 MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*");
432 MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); 436 MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
433 MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); 437 MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
434 438
drivers/misc/sony-laptop.c
1 /* 1 /*
2 * ACPI Sony Notebook Control Driver (SNC and SPIC) 2 * ACPI Sony Notebook Control Driver (SNC and SPIC)
3 * 3 *
4 * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net> 4 * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
5 * Copyright (C) 2007 Mattia Dongili <malattia@linux.it> 5 * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
6 * 6 *
7 * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c 7 * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
8 * which are copyrighted by their respective authors. 8 * which are copyrighted by their respective authors.
9 * 9 *
10 * The SNY6001 driver part is based on the sonypi driver which includes 10 * The SNY6001 driver part is based on the sonypi driver which includes
11 * material from: 11 * material from:
12 * 12 *
13 * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net> 13 * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net>
14 * 14 *
15 * Copyright (C) 2005 Narayanan R S <nars@kadamba.org> 15 * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
16 * 16 *
17 * Copyright (C) 2001-2002 Alcรดve <www.alcove.com> 17 * Copyright (C) 2001-2002 Alcรดve <www.alcove.com>
18 * 18 *
19 * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au> 19 * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
20 * 20 *
21 * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp> 21 * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp>
22 * 22 *
23 * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp> 23 * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp>
24 * 24 *
25 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> 25 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
26 * 26 *
27 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras. 27 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
28 * 28 *
29 * This program is free software; you can redistribute it and/or modify 29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License as published by 30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation; either version 2 of the License, or 31 * the Free Software Foundation; either version 2 of the License, or
32 * (at your option) any later version. 32 * (at your option) any later version.
33 * 33 *
34 * This program is distributed in the hope that it will be useful, 34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of 35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details. 37 * GNU General Public License for more details.
38 * 38 *
39 * You should have received a copy of the GNU General Public License 39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software 40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 41 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 * 42 *
43 */ 43 */
44 44
45 #include <linux/kernel.h> 45 #include <linux/kernel.h>
46 #include <linux/module.h> 46 #include <linux/module.h>
47 #include <linux/moduleparam.h> 47 #include <linux/moduleparam.h>
48 #include <linux/init.h> 48 #include <linux/init.h>
49 #include <linux/smp_lock.h> 49 #include <linux/smp_lock.h>
50 #include <linux/types.h> 50 #include <linux/types.h>
51 #include <linux/backlight.h> 51 #include <linux/backlight.h>
52 #include <linux/platform_device.h> 52 #include <linux/platform_device.h>
53 #include <linux/err.h> 53 #include <linux/err.h>
54 #include <linux/dmi.h> 54 #include <linux/dmi.h>
55 #include <linux/pci.h> 55 #include <linux/pci.h>
56 #include <linux/interrupt.h> 56 #include <linux/interrupt.h>
57 #include <linux/delay.h> 57 #include <linux/delay.h>
58 #include <linux/input.h> 58 #include <linux/input.h>
59 #include <linux/kfifo.h> 59 #include <linux/kfifo.h>
60 #include <linux/workqueue.h> 60 #include <linux/workqueue.h>
61 #include <linux/acpi.h> 61 #include <linux/acpi.h>
62 #include <acpi/acpi_drivers.h> 62 #include <acpi/acpi_drivers.h>
63 #include <acpi/acpi_bus.h> 63 #include <acpi/acpi_bus.h>
64 #include <asm/uaccess.h> 64 #include <asm/uaccess.h>
65 #include <linux/sonypi.h> 65 #include <linux/sonypi.h>
66 #include <linux/sony-laptop.h> 66 #include <linux/sony-laptop.h>
67 #ifdef CONFIG_SONYPI_COMPAT 67 #ifdef CONFIG_SONYPI_COMPAT
68 #include <linux/poll.h> 68 #include <linux/poll.h>
69 #include <linux/miscdevice.h> 69 #include <linux/miscdevice.h>
70 #endif 70 #endif
71 71
72 #define DRV_PFX "sony-laptop: " 72 #define DRV_PFX "sony-laptop: "
73 #define dprintk(msg...) do { \ 73 #define dprintk(msg...) do { \
74 if (debug) printk(KERN_WARNING DRV_PFX msg); \ 74 if (debug) printk(KERN_WARNING DRV_PFX msg); \
75 } while (0) 75 } while (0)
76 76
77 #define SONY_LAPTOP_DRIVER_VERSION "0.6" 77 #define SONY_LAPTOP_DRIVER_VERSION "0.6"
78 78
79 #define SONY_NC_CLASS "sony-nc" 79 #define SONY_NC_CLASS "sony-nc"
80 #define SONY_NC_HID "SNY5001" 80 #define SONY_NC_HID "SNY5001"
81 #define SONY_NC_DRIVER_NAME "Sony Notebook Control Driver" 81 #define SONY_NC_DRIVER_NAME "Sony Notebook Control Driver"
82 82
83 #define SONY_PIC_CLASS "sony-pic" 83 #define SONY_PIC_CLASS "sony-pic"
84 #define SONY_PIC_HID "SNY6001" 84 #define SONY_PIC_HID "SNY6001"
85 #define SONY_PIC_DRIVER_NAME "Sony Programmable IO Control Driver" 85 #define SONY_PIC_DRIVER_NAME "Sony Programmable IO Control Driver"
86 86
87 MODULE_AUTHOR("Stelian Pop, Mattia Dongili"); 87 MODULE_AUTHOR("Stelian Pop, Mattia Dongili");
88 MODULE_DESCRIPTION("Sony laptop extras driver (SPIC and SNC ACPI device)"); 88 MODULE_DESCRIPTION("Sony laptop extras driver (SPIC and SNC ACPI device)");
89 MODULE_LICENSE("GPL"); 89 MODULE_LICENSE("GPL");
90 MODULE_VERSION(SONY_LAPTOP_DRIVER_VERSION); 90 MODULE_VERSION(SONY_LAPTOP_DRIVER_VERSION);
91 91
92 static int debug; 92 static int debug;
93 module_param(debug, int, 0); 93 module_param(debug, int, 0);
94 MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " 94 MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help "
95 "the development of this driver"); 95 "the development of this driver");
96 96
97 static int no_spic; /* = 0 */ 97 static int no_spic; /* = 0 */
98 module_param(no_spic, int, 0444); 98 module_param(no_spic, int, 0444);
99 MODULE_PARM_DESC(no_spic, 99 MODULE_PARM_DESC(no_spic,
100 "set this if you don't want to enable the SPIC device"); 100 "set this if you don't want to enable the SPIC device");
101 101
102 static int compat; /* = 0 */ 102 static int compat; /* = 0 */
103 module_param(compat, int, 0444); 103 module_param(compat, int, 0444);
104 MODULE_PARM_DESC(compat, 104 MODULE_PARM_DESC(compat,
105 "set this if you want to enable backward compatibility mode"); 105 "set this if you want to enable backward compatibility mode");
106 106
107 static unsigned long mask = 0xffffffff; 107 static unsigned long mask = 0xffffffff;
108 module_param(mask, ulong, 0644); 108 module_param(mask, ulong, 0644);
109 MODULE_PARM_DESC(mask, 109 MODULE_PARM_DESC(mask,
110 "set this to the mask of event you want to enable (see doc)"); 110 "set this to the mask of event you want to enable (see doc)");
111 111
112 static int camera; /* = 0 */ 112 static int camera; /* = 0 */
113 module_param(camera, int, 0444); 113 module_param(camera, int, 0444);
114 MODULE_PARM_DESC(camera, 114 MODULE_PARM_DESC(camera,
115 "set this to 1 to enable Motion Eye camera controls " 115 "set this to 1 to enable Motion Eye camera controls "
116 "(only use it if you have a C1VE or C1VN model)"); 116 "(only use it if you have a C1VE or C1VN model)");
117 117
118 #ifdef CONFIG_SONYPI_COMPAT 118 #ifdef CONFIG_SONYPI_COMPAT
119 static int minor = -1; 119 static int minor = -1;
120 module_param(minor, int, 0); 120 module_param(minor, int, 0);
121 MODULE_PARM_DESC(minor, 121 MODULE_PARM_DESC(minor,
122 "minor number of the misc device for the SPIC compatibility code, " 122 "minor number of the misc device for the SPIC compatibility code, "
123 "default is -1 (automatic)"); 123 "default is -1 (automatic)");
124 #endif 124 #endif
125 125
126 /*********** Input Devices ***********/ 126 /*********** Input Devices ***********/
127 127
128 #define SONY_LAPTOP_BUF_SIZE 128 128 #define SONY_LAPTOP_BUF_SIZE 128
129 struct sony_laptop_input_s { 129 struct sony_laptop_input_s {
130 atomic_t users; 130 atomic_t users;
131 struct input_dev *jog_dev; 131 struct input_dev *jog_dev;
132 struct input_dev *key_dev; 132 struct input_dev *key_dev;
133 struct kfifo *fifo; 133 struct kfifo *fifo;
134 spinlock_t fifo_lock; 134 spinlock_t fifo_lock;
135 struct workqueue_struct *wq; 135 struct workqueue_struct *wq;
136 }; 136 };
137 static struct sony_laptop_input_s sony_laptop_input = { 137 static struct sony_laptop_input_s sony_laptop_input = {
138 .users = ATOMIC_INIT(0), 138 .users = ATOMIC_INIT(0),
139 }; 139 };
140 140
141 struct sony_laptop_keypress { 141 struct sony_laptop_keypress {
142 struct input_dev *dev; 142 struct input_dev *dev;
143 int key; 143 int key;
144 }; 144 };
145 145
146 /* Correspondance table between sonypi events 146 /* Correspondance table between sonypi events
147 * and input layer indexes in the keymap 147 * and input layer indexes in the keymap
148 */ 148 */
149 static int sony_laptop_input_index[] = { 149 static int sony_laptop_input_index[] = {
150 -1, /* 0 no event */ 150 -1, /* 0 no event */
151 -1, /* 1 SONYPI_EVENT_JOGDIAL_DOWN */ 151 -1, /* 1 SONYPI_EVENT_JOGDIAL_DOWN */
152 -1, /* 2 SONYPI_EVENT_JOGDIAL_UP */ 152 -1, /* 2 SONYPI_EVENT_JOGDIAL_UP */
153 -1, /* 3 SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */ 153 -1, /* 3 SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */
154 -1, /* 4 SONYPI_EVENT_JOGDIAL_UP_PRESSED */ 154 -1, /* 4 SONYPI_EVENT_JOGDIAL_UP_PRESSED */
155 -1, /* 5 SONYPI_EVENT_JOGDIAL_PRESSED */ 155 -1, /* 5 SONYPI_EVENT_JOGDIAL_PRESSED */
156 -1, /* 6 SONYPI_EVENT_JOGDIAL_RELEASED */ 156 -1, /* 6 SONYPI_EVENT_JOGDIAL_RELEASED */
157 0, /* 7 SONYPI_EVENT_CAPTURE_PRESSED */ 157 0, /* 7 SONYPI_EVENT_CAPTURE_PRESSED */
158 1, /* 8 SONYPI_EVENT_CAPTURE_RELEASED */ 158 1, /* 8 SONYPI_EVENT_CAPTURE_RELEASED */
159 2, /* 9 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ 159 2, /* 9 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */
160 3, /* 10 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ 160 3, /* 10 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */
161 4, /* 11 SONYPI_EVENT_FNKEY_ESC */ 161 4, /* 11 SONYPI_EVENT_FNKEY_ESC */
162 5, /* 12 SONYPI_EVENT_FNKEY_F1 */ 162 5, /* 12 SONYPI_EVENT_FNKEY_F1 */
163 6, /* 13 SONYPI_EVENT_FNKEY_F2 */ 163 6, /* 13 SONYPI_EVENT_FNKEY_F2 */
164 7, /* 14 SONYPI_EVENT_FNKEY_F3 */ 164 7, /* 14 SONYPI_EVENT_FNKEY_F3 */
165 8, /* 15 SONYPI_EVENT_FNKEY_F4 */ 165 8, /* 15 SONYPI_EVENT_FNKEY_F4 */
166 9, /* 16 SONYPI_EVENT_FNKEY_F5 */ 166 9, /* 16 SONYPI_EVENT_FNKEY_F5 */
167 10, /* 17 SONYPI_EVENT_FNKEY_F6 */ 167 10, /* 17 SONYPI_EVENT_FNKEY_F6 */
168 11, /* 18 SONYPI_EVENT_FNKEY_F7 */ 168 11, /* 18 SONYPI_EVENT_FNKEY_F7 */
169 12, /* 19 SONYPI_EVENT_FNKEY_F8 */ 169 12, /* 19 SONYPI_EVENT_FNKEY_F8 */
170 13, /* 20 SONYPI_EVENT_FNKEY_F9 */ 170 13, /* 20 SONYPI_EVENT_FNKEY_F9 */
171 14, /* 21 SONYPI_EVENT_FNKEY_F10 */ 171 14, /* 21 SONYPI_EVENT_FNKEY_F10 */
172 15, /* 22 SONYPI_EVENT_FNKEY_F11 */ 172 15, /* 22 SONYPI_EVENT_FNKEY_F11 */
173 16, /* 23 SONYPI_EVENT_FNKEY_F12 */ 173 16, /* 23 SONYPI_EVENT_FNKEY_F12 */
174 17, /* 24 SONYPI_EVENT_FNKEY_1 */ 174 17, /* 24 SONYPI_EVENT_FNKEY_1 */
175 18, /* 25 SONYPI_EVENT_FNKEY_2 */ 175 18, /* 25 SONYPI_EVENT_FNKEY_2 */
176 19, /* 26 SONYPI_EVENT_FNKEY_D */ 176 19, /* 26 SONYPI_EVENT_FNKEY_D */
177 20, /* 27 SONYPI_EVENT_FNKEY_E */ 177 20, /* 27 SONYPI_EVENT_FNKEY_E */
178 21, /* 28 SONYPI_EVENT_FNKEY_F */ 178 21, /* 28 SONYPI_EVENT_FNKEY_F */
179 22, /* 29 SONYPI_EVENT_FNKEY_S */ 179 22, /* 29 SONYPI_EVENT_FNKEY_S */
180 23, /* 30 SONYPI_EVENT_FNKEY_B */ 180 23, /* 30 SONYPI_EVENT_FNKEY_B */
181 24, /* 31 SONYPI_EVENT_BLUETOOTH_PRESSED */ 181 24, /* 31 SONYPI_EVENT_BLUETOOTH_PRESSED */
182 25, /* 32 SONYPI_EVENT_PKEY_P1 */ 182 25, /* 32 SONYPI_EVENT_PKEY_P1 */
183 26, /* 33 SONYPI_EVENT_PKEY_P2 */ 183 26, /* 33 SONYPI_EVENT_PKEY_P2 */
184 27, /* 34 SONYPI_EVENT_PKEY_P3 */ 184 27, /* 34 SONYPI_EVENT_PKEY_P3 */
185 28, /* 35 SONYPI_EVENT_BACK_PRESSED */ 185 28, /* 35 SONYPI_EVENT_BACK_PRESSED */
186 -1, /* 36 SONYPI_EVENT_LID_CLOSED */ 186 -1, /* 36 SONYPI_EVENT_LID_CLOSED */
187 -1, /* 37 SONYPI_EVENT_LID_OPENED */ 187 -1, /* 37 SONYPI_EVENT_LID_OPENED */
188 29, /* 38 SONYPI_EVENT_BLUETOOTH_ON */ 188 29, /* 38 SONYPI_EVENT_BLUETOOTH_ON */
189 30, /* 39 SONYPI_EVENT_BLUETOOTH_OFF */ 189 30, /* 39 SONYPI_EVENT_BLUETOOTH_OFF */
190 31, /* 40 SONYPI_EVENT_HELP_PRESSED */ 190 31, /* 40 SONYPI_EVENT_HELP_PRESSED */
191 32, /* 41 SONYPI_EVENT_FNKEY_ONLY */ 191 32, /* 41 SONYPI_EVENT_FNKEY_ONLY */
192 33, /* 42 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ 192 33, /* 42 SONYPI_EVENT_JOGDIAL_FAST_DOWN */
193 34, /* 43 SONYPI_EVENT_JOGDIAL_FAST_UP */ 193 34, /* 43 SONYPI_EVENT_JOGDIAL_FAST_UP */
194 35, /* 44 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ 194 35, /* 44 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */
195 36, /* 45 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ 195 36, /* 45 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */
196 37, /* 46 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ 196 37, /* 46 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */
197 38, /* 47 SONYPI_EVENT_JOGDIAL_VFAST_UP */ 197 38, /* 47 SONYPI_EVENT_JOGDIAL_VFAST_UP */
198 39, /* 48 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ 198 39, /* 48 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */
199 40, /* 49 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ 199 40, /* 49 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */
200 41, /* 50 SONYPI_EVENT_ZOOM_PRESSED */ 200 41, /* 50 SONYPI_EVENT_ZOOM_PRESSED */
201 42, /* 51 SONYPI_EVENT_THUMBPHRASE_PRESSED */ 201 42, /* 51 SONYPI_EVENT_THUMBPHRASE_PRESSED */
202 43, /* 52 SONYPI_EVENT_MEYE_FACE */ 202 43, /* 52 SONYPI_EVENT_MEYE_FACE */
203 44, /* 53 SONYPI_EVENT_MEYE_OPPOSITE */ 203 44, /* 53 SONYPI_EVENT_MEYE_OPPOSITE */
204 45, /* 54 SONYPI_EVENT_MEMORYSTICK_INSERT */ 204 45, /* 54 SONYPI_EVENT_MEMORYSTICK_INSERT */
205 46, /* 55 SONYPI_EVENT_MEMORYSTICK_EJECT */ 205 46, /* 55 SONYPI_EVENT_MEMORYSTICK_EJECT */
206 -1, /* 56 SONYPI_EVENT_ANYBUTTON_RELEASED */ 206 -1, /* 56 SONYPI_EVENT_ANYBUTTON_RELEASED */
207 -1, /* 57 SONYPI_EVENT_BATTERY_INSERT */ 207 -1, /* 57 SONYPI_EVENT_BATTERY_INSERT */
208 -1, /* 58 SONYPI_EVENT_BATTERY_REMOVE */ 208 -1, /* 58 SONYPI_EVENT_BATTERY_REMOVE */
209 -1, /* 59 SONYPI_EVENT_FNKEY_RELEASED */ 209 -1, /* 59 SONYPI_EVENT_FNKEY_RELEASED */
210 47, /* 60 SONYPI_EVENT_WIRELESS_ON */ 210 47, /* 60 SONYPI_EVENT_WIRELESS_ON */
211 48, /* 61 SONYPI_EVENT_WIRELESS_OFF */ 211 48, /* 61 SONYPI_EVENT_WIRELESS_OFF */
212 49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */ 212 49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */
213 50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */ 213 50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */
214 }; 214 };
215 215
216 static int sony_laptop_input_keycode_map[] = { 216 static int sony_laptop_input_keycode_map[] = {
217 KEY_CAMERA, /* 0 SONYPI_EVENT_CAPTURE_PRESSED */ 217 KEY_CAMERA, /* 0 SONYPI_EVENT_CAPTURE_PRESSED */
218 KEY_RESERVED, /* 1 SONYPI_EVENT_CAPTURE_RELEASED */ 218 KEY_RESERVED, /* 1 SONYPI_EVENT_CAPTURE_RELEASED */
219 KEY_RESERVED, /* 2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ 219 KEY_RESERVED, /* 2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */
220 KEY_RESERVED, /* 3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ 220 KEY_RESERVED, /* 3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */
221 KEY_FN_ESC, /* 4 SONYPI_EVENT_FNKEY_ESC */ 221 KEY_FN_ESC, /* 4 SONYPI_EVENT_FNKEY_ESC */
222 KEY_FN_F1, /* 5 SONYPI_EVENT_FNKEY_F1 */ 222 KEY_FN_F1, /* 5 SONYPI_EVENT_FNKEY_F1 */
223 KEY_FN_F2, /* 6 SONYPI_EVENT_FNKEY_F2 */ 223 KEY_FN_F2, /* 6 SONYPI_EVENT_FNKEY_F2 */
224 KEY_FN_F3, /* 7 SONYPI_EVENT_FNKEY_F3 */ 224 KEY_FN_F3, /* 7 SONYPI_EVENT_FNKEY_F3 */
225 KEY_FN_F4, /* 8 SONYPI_EVENT_FNKEY_F4 */ 225 KEY_FN_F4, /* 8 SONYPI_EVENT_FNKEY_F4 */
226 KEY_FN_F5, /* 9 SONYPI_EVENT_FNKEY_F5 */ 226 KEY_FN_F5, /* 9 SONYPI_EVENT_FNKEY_F5 */
227 KEY_FN_F6, /* 10 SONYPI_EVENT_FNKEY_F6 */ 227 KEY_FN_F6, /* 10 SONYPI_EVENT_FNKEY_F6 */
228 KEY_FN_F7, /* 11 SONYPI_EVENT_FNKEY_F7 */ 228 KEY_FN_F7, /* 11 SONYPI_EVENT_FNKEY_F7 */
229 KEY_FN_F8, /* 12 SONYPI_EVENT_FNKEY_F8 */ 229 KEY_FN_F8, /* 12 SONYPI_EVENT_FNKEY_F8 */
230 KEY_FN_F9, /* 13 SONYPI_EVENT_FNKEY_F9 */ 230 KEY_FN_F9, /* 13 SONYPI_EVENT_FNKEY_F9 */
231 KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */ 231 KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */
232 KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */ 232 KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */
233 KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */ 233 KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */
234 KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */ 234 KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */
235 KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */ 235 KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */
236 KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */ 236 KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */
237 KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */ 237 KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */
238 KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */ 238 KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */
239 KEY_FN_S, /* 22 SONYPI_EVENT_FNKEY_S */ 239 KEY_FN_S, /* 22 SONYPI_EVENT_FNKEY_S */
240 KEY_FN_B, /* 23 SONYPI_EVENT_FNKEY_B */ 240 KEY_FN_B, /* 23 SONYPI_EVENT_FNKEY_B */
241 KEY_BLUETOOTH, /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */ 241 KEY_BLUETOOTH, /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */
242 KEY_PROG1, /* 25 SONYPI_EVENT_PKEY_P1 */ 242 KEY_PROG1, /* 25 SONYPI_EVENT_PKEY_P1 */
243 KEY_PROG2, /* 26 SONYPI_EVENT_PKEY_P2 */ 243 KEY_PROG2, /* 26 SONYPI_EVENT_PKEY_P2 */
244 KEY_PROG3, /* 27 SONYPI_EVENT_PKEY_P3 */ 244 KEY_PROG3, /* 27 SONYPI_EVENT_PKEY_P3 */
245 KEY_BACK, /* 28 SONYPI_EVENT_BACK_PRESSED */ 245 KEY_BACK, /* 28 SONYPI_EVENT_BACK_PRESSED */
246 KEY_BLUETOOTH, /* 29 SONYPI_EVENT_BLUETOOTH_ON */ 246 KEY_BLUETOOTH, /* 29 SONYPI_EVENT_BLUETOOTH_ON */
247 KEY_BLUETOOTH, /* 30 SONYPI_EVENT_BLUETOOTH_OFF */ 247 KEY_BLUETOOTH, /* 30 SONYPI_EVENT_BLUETOOTH_OFF */
248 KEY_HELP, /* 31 SONYPI_EVENT_HELP_PRESSED */ 248 KEY_HELP, /* 31 SONYPI_EVENT_HELP_PRESSED */
249 KEY_FN, /* 32 SONYPI_EVENT_FNKEY_ONLY */ 249 KEY_FN, /* 32 SONYPI_EVENT_FNKEY_ONLY */
250 KEY_RESERVED, /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ 250 KEY_RESERVED, /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */
251 KEY_RESERVED, /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */ 251 KEY_RESERVED, /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */
252 KEY_RESERVED, /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ 252 KEY_RESERVED, /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */
253 KEY_RESERVED, /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ 253 KEY_RESERVED, /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */
254 KEY_RESERVED, /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ 254 KEY_RESERVED, /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */
255 KEY_RESERVED, /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */ 255 KEY_RESERVED, /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */
256 KEY_RESERVED, /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ 256 KEY_RESERVED, /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */
257 KEY_RESERVED, /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ 257 KEY_RESERVED, /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */
258 KEY_ZOOM, /* 41 SONYPI_EVENT_ZOOM_PRESSED */ 258 KEY_ZOOM, /* 41 SONYPI_EVENT_ZOOM_PRESSED */
259 BTN_THUMB, /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */ 259 BTN_THUMB, /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */
260 KEY_RESERVED, /* 43 SONYPI_EVENT_MEYE_FACE */ 260 KEY_RESERVED, /* 43 SONYPI_EVENT_MEYE_FACE */
261 KEY_RESERVED, /* 44 SONYPI_EVENT_MEYE_OPPOSITE */ 261 KEY_RESERVED, /* 44 SONYPI_EVENT_MEYE_OPPOSITE */
262 KEY_RESERVED, /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */ 262 KEY_RESERVED, /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */
263 KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */ 263 KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */
264 KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */ 264 KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */
265 KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */ 265 KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */
266 KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */ 266 KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */
267 KEY_ZOOMOUT /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */ 267 KEY_ZOOMOUT /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
268 }; 268 };
269 269
270 /* release buttons after a short delay if pressed */ 270 /* release buttons after a short delay if pressed */
271 static void do_sony_laptop_release_key(struct work_struct *work) 271 static void do_sony_laptop_release_key(struct work_struct *work)
272 { 272 {
273 struct sony_laptop_keypress kp; 273 struct sony_laptop_keypress kp;
274 274
275 while (kfifo_get(sony_laptop_input.fifo, (unsigned char *)&kp, 275 while (kfifo_get(sony_laptop_input.fifo, (unsigned char *)&kp,
276 sizeof(kp)) == sizeof(kp)) { 276 sizeof(kp)) == sizeof(kp)) {
277 msleep(10); 277 msleep(10);
278 input_report_key(kp.dev, kp.key, 0); 278 input_report_key(kp.dev, kp.key, 0);
279 input_sync(kp.dev); 279 input_sync(kp.dev);
280 } 280 }
281 } 281 }
282 static DECLARE_WORK(sony_laptop_release_key_work, 282 static DECLARE_WORK(sony_laptop_release_key_work,
283 do_sony_laptop_release_key); 283 do_sony_laptop_release_key);
284 284
285 /* forward event to the input subsystem */ 285 /* forward event to the input subsystem */
286 static void sony_laptop_report_input_event(u8 event) 286 static void sony_laptop_report_input_event(u8 event)
287 { 287 {
288 struct input_dev *jog_dev = sony_laptop_input.jog_dev; 288 struct input_dev *jog_dev = sony_laptop_input.jog_dev;
289 struct input_dev *key_dev = sony_laptop_input.key_dev; 289 struct input_dev *key_dev = sony_laptop_input.key_dev;
290 struct sony_laptop_keypress kp = { NULL }; 290 struct sony_laptop_keypress kp = { NULL };
291 291
292 if (event == SONYPI_EVENT_FNKEY_RELEASED) { 292 if (event == SONYPI_EVENT_FNKEY_RELEASED) {
293 /* Nothing, not all VAIOs generate this event */ 293 /* Nothing, not all VAIOs generate this event */
294 return; 294 return;
295 } 295 }
296 296
297 /* report events */ 297 /* report events */
298 switch (event) { 298 switch (event) {
299 /* jog_dev events */ 299 /* jog_dev events */
300 case SONYPI_EVENT_JOGDIAL_UP: 300 case SONYPI_EVENT_JOGDIAL_UP:
301 case SONYPI_EVENT_JOGDIAL_UP_PRESSED: 301 case SONYPI_EVENT_JOGDIAL_UP_PRESSED:
302 input_report_rel(jog_dev, REL_WHEEL, 1); 302 input_report_rel(jog_dev, REL_WHEEL, 1);
303 input_sync(jog_dev); 303 input_sync(jog_dev);
304 return; 304 return;
305 305
306 case SONYPI_EVENT_JOGDIAL_DOWN: 306 case SONYPI_EVENT_JOGDIAL_DOWN:
307 case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: 307 case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED:
308 input_report_rel(jog_dev, REL_WHEEL, -1); 308 input_report_rel(jog_dev, REL_WHEEL, -1);
309 input_sync(jog_dev); 309 input_sync(jog_dev);
310 return; 310 return;
311 311
312 /* key_dev events */ 312 /* key_dev events */
313 case SONYPI_EVENT_JOGDIAL_PRESSED: 313 case SONYPI_EVENT_JOGDIAL_PRESSED:
314 kp.key = BTN_MIDDLE; 314 kp.key = BTN_MIDDLE;
315 kp.dev = jog_dev; 315 kp.dev = jog_dev;
316 break; 316 break;
317 317
318 default: 318 default:
319 if (event >= ARRAY_SIZE(sony_laptop_input_index)) { 319 if (event >= ARRAY_SIZE(sony_laptop_input_index)) {
320 dprintk("sony_laptop_report_input_event, event not known: %d\n", event); 320 dprintk("sony_laptop_report_input_event, event not known: %d\n", event);
321 break; 321 break;
322 } 322 }
323 if (sony_laptop_input_index[event] != -1) { 323 if (sony_laptop_input_index[event] != -1) {
324 kp.key = sony_laptop_input_keycode_map[sony_laptop_input_index[event]]; 324 kp.key = sony_laptop_input_keycode_map[sony_laptop_input_index[event]];
325 if (kp.key != KEY_UNKNOWN) 325 if (kp.key != KEY_UNKNOWN)
326 kp.dev = key_dev; 326 kp.dev = key_dev;
327 } 327 }
328 break; 328 break;
329 } 329 }
330 330
331 if (kp.dev) { 331 if (kp.dev) {
332 input_report_key(kp.dev, kp.key, 1); 332 input_report_key(kp.dev, kp.key, 1);
333 /* we emit the scancode so we can always remap the key */ 333 /* we emit the scancode so we can always remap the key */
334 input_event(kp.dev, EV_MSC, MSC_SCAN, event); 334 input_event(kp.dev, EV_MSC, MSC_SCAN, event);
335 input_sync(kp.dev); 335 input_sync(kp.dev);
336 kfifo_put(sony_laptop_input.fifo, 336 kfifo_put(sony_laptop_input.fifo,
337 (unsigned char *)&kp, sizeof(kp)); 337 (unsigned char *)&kp, sizeof(kp));
338 338
339 if (!work_pending(&sony_laptop_release_key_work)) 339 if (!work_pending(&sony_laptop_release_key_work))
340 queue_work(sony_laptop_input.wq, 340 queue_work(sony_laptop_input.wq,
341 &sony_laptop_release_key_work); 341 &sony_laptop_release_key_work);
342 } else 342 } else
343 dprintk("unknown input event %.2x\n", event); 343 dprintk("unknown input event %.2x\n", event);
344 } 344 }
345 345
346 static int sony_laptop_setup_input(struct acpi_device *acpi_device) 346 static int sony_laptop_setup_input(struct acpi_device *acpi_device)
347 { 347 {
348 struct input_dev *jog_dev; 348 struct input_dev *jog_dev;
349 struct input_dev *key_dev; 349 struct input_dev *key_dev;
350 int i; 350 int i;
351 int error; 351 int error;
352 352
353 /* don't run again if already initialized */ 353 /* don't run again if already initialized */
354 if (atomic_add_return(1, &sony_laptop_input.users) > 1) 354 if (atomic_add_return(1, &sony_laptop_input.users) > 1)
355 return 0; 355 return 0;
356 356
357 /* kfifo */ 357 /* kfifo */
358 spin_lock_init(&sony_laptop_input.fifo_lock); 358 spin_lock_init(&sony_laptop_input.fifo_lock);
359 sony_laptop_input.fifo = 359 sony_laptop_input.fifo =
360 kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, 360 kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
361 &sony_laptop_input.fifo_lock); 361 &sony_laptop_input.fifo_lock);
362 if (IS_ERR(sony_laptop_input.fifo)) { 362 if (IS_ERR(sony_laptop_input.fifo)) {
363 printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); 363 printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
364 error = PTR_ERR(sony_laptop_input.fifo); 364 error = PTR_ERR(sony_laptop_input.fifo);
365 goto err_dec_users; 365 goto err_dec_users;
366 } 366 }
367 367
368 /* init workqueue */ 368 /* init workqueue */
369 sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop"); 369 sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop");
370 if (!sony_laptop_input.wq) { 370 if (!sony_laptop_input.wq) {
371 printk(KERN_ERR DRV_PFX 371 printk(KERN_ERR DRV_PFX
372 "Unabe to create workqueue.\n"); 372 "Unabe to create workqueue.\n");
373 error = -ENXIO; 373 error = -ENXIO;
374 goto err_free_kfifo; 374 goto err_free_kfifo;
375 } 375 }
376 376
377 /* input keys */ 377 /* input keys */
378 key_dev = input_allocate_device(); 378 key_dev = input_allocate_device();
379 if (!key_dev) { 379 if (!key_dev) {
380 error = -ENOMEM; 380 error = -ENOMEM;
381 goto err_destroy_wq; 381 goto err_destroy_wq;
382 } 382 }
383 383
384 key_dev->name = "Sony Vaio Keys"; 384 key_dev->name = "Sony Vaio Keys";
385 key_dev->id.bustype = BUS_ISA; 385 key_dev->id.bustype = BUS_ISA;
386 key_dev->id.vendor = PCI_VENDOR_ID_SONY; 386 key_dev->id.vendor = PCI_VENDOR_ID_SONY;
387 key_dev->dev.parent = &acpi_device->dev; 387 key_dev->dev.parent = &acpi_device->dev;
388 388
389 /* Initialize the Input Drivers: special keys */ 389 /* Initialize the Input Drivers: special keys */
390 set_bit(EV_KEY, key_dev->evbit); 390 set_bit(EV_KEY, key_dev->evbit);
391 set_bit(EV_MSC, key_dev->evbit); 391 set_bit(EV_MSC, key_dev->evbit);
392 set_bit(MSC_SCAN, key_dev->mscbit); 392 set_bit(MSC_SCAN, key_dev->mscbit);
393 key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); 393 key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]);
394 key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); 394 key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map);
395 key_dev->keycode = &sony_laptop_input_keycode_map; 395 key_dev->keycode = &sony_laptop_input_keycode_map;
396 for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) { 396 for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) {
397 if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) { 397 if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) {
398 set_bit(sony_laptop_input_keycode_map[i], 398 set_bit(sony_laptop_input_keycode_map[i],
399 key_dev->keybit); 399 key_dev->keybit);
400 } 400 }
401 } 401 }
402 402
403 error = input_register_device(key_dev); 403 error = input_register_device(key_dev);
404 if (error) 404 if (error)
405 goto err_free_keydev; 405 goto err_free_keydev;
406 406
407 sony_laptop_input.key_dev = key_dev; 407 sony_laptop_input.key_dev = key_dev;
408 408
409 /* jogdial */ 409 /* jogdial */
410 jog_dev = input_allocate_device(); 410 jog_dev = input_allocate_device();
411 if (!jog_dev) { 411 if (!jog_dev) {
412 error = -ENOMEM; 412 error = -ENOMEM;
413 goto err_unregister_keydev; 413 goto err_unregister_keydev;
414 } 414 }
415 415
416 jog_dev->name = "Sony Vaio Jogdial"; 416 jog_dev->name = "Sony Vaio Jogdial";
417 jog_dev->id.bustype = BUS_ISA; 417 jog_dev->id.bustype = BUS_ISA;
418 jog_dev->id.vendor = PCI_VENDOR_ID_SONY; 418 jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
419 key_dev->dev.parent = &acpi_device->dev; 419 key_dev->dev.parent = &acpi_device->dev;
420 420
421 jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); 421 jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
422 jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE); 422 jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
423 jog_dev->relbit[0] = BIT_MASK(REL_WHEEL); 423 jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
424 424
425 error = input_register_device(jog_dev); 425 error = input_register_device(jog_dev);
426 if (error) 426 if (error)
427 goto err_free_jogdev; 427 goto err_free_jogdev;
428 428
429 sony_laptop_input.jog_dev = jog_dev; 429 sony_laptop_input.jog_dev = jog_dev;
430 430
431 return 0; 431 return 0;
432 432
433 err_free_jogdev: 433 err_free_jogdev:
434 input_free_device(jog_dev); 434 input_free_device(jog_dev);
435 435
436 err_unregister_keydev: 436 err_unregister_keydev:
437 input_unregister_device(key_dev); 437 input_unregister_device(key_dev);
438 /* to avoid kref underflow below at input_free_device */ 438 /* to avoid kref underflow below at input_free_device */
439 key_dev = NULL; 439 key_dev = NULL;
440 440
441 err_free_keydev: 441 err_free_keydev:
442 input_free_device(key_dev); 442 input_free_device(key_dev);
443 443
444 err_destroy_wq: 444 err_destroy_wq:
445 destroy_workqueue(sony_laptop_input.wq); 445 destroy_workqueue(sony_laptop_input.wq);
446 446
447 err_free_kfifo: 447 err_free_kfifo:
448 kfifo_free(sony_laptop_input.fifo); 448 kfifo_free(sony_laptop_input.fifo);
449 449
450 err_dec_users: 450 err_dec_users:
451 atomic_dec(&sony_laptop_input.users); 451 atomic_dec(&sony_laptop_input.users);
452 return error; 452 return error;
453 } 453 }
454 454
455 static void sony_laptop_remove_input(void) 455 static void sony_laptop_remove_input(void)
456 { 456 {
457 /* cleanup only after the last user has gone */ 457 /* cleanup only after the last user has gone */
458 if (!atomic_dec_and_test(&sony_laptop_input.users)) 458 if (!atomic_dec_and_test(&sony_laptop_input.users))
459 return; 459 return;
460 460
461 /* flush workqueue first */ 461 /* flush workqueue first */
462 flush_workqueue(sony_laptop_input.wq); 462 flush_workqueue(sony_laptop_input.wq);
463 463
464 /* destroy input devs */ 464 /* destroy input devs */
465 input_unregister_device(sony_laptop_input.key_dev); 465 input_unregister_device(sony_laptop_input.key_dev);
466 sony_laptop_input.key_dev = NULL; 466 sony_laptop_input.key_dev = NULL;
467 467
468 if (sony_laptop_input.jog_dev) { 468 if (sony_laptop_input.jog_dev) {
469 input_unregister_device(sony_laptop_input.jog_dev); 469 input_unregister_device(sony_laptop_input.jog_dev);
470 sony_laptop_input.jog_dev = NULL; 470 sony_laptop_input.jog_dev = NULL;
471 } 471 }
472 472
473 destroy_workqueue(sony_laptop_input.wq); 473 destroy_workqueue(sony_laptop_input.wq);
474 kfifo_free(sony_laptop_input.fifo); 474 kfifo_free(sony_laptop_input.fifo);
475 } 475 }
476 476
477 /*********** Platform Device ***********/ 477 /*********** Platform Device ***********/
478 478
479 static atomic_t sony_pf_users = ATOMIC_INIT(0); 479 static atomic_t sony_pf_users = ATOMIC_INIT(0);
480 static struct platform_driver sony_pf_driver = { 480 static struct platform_driver sony_pf_driver = {
481 .driver = { 481 .driver = {
482 .name = "sony-laptop", 482 .name = "sony-laptop",
483 .owner = THIS_MODULE, 483 .owner = THIS_MODULE,
484 } 484 }
485 }; 485 };
486 static struct platform_device *sony_pf_device; 486 static struct platform_device *sony_pf_device;
487 487
488 static int sony_pf_add(void) 488 static int sony_pf_add(void)
489 { 489 {
490 int ret = 0; 490 int ret = 0;
491 491
492 /* don't run again if already initialized */ 492 /* don't run again if already initialized */
493 if (atomic_add_return(1, &sony_pf_users) > 1) 493 if (atomic_add_return(1, &sony_pf_users) > 1)
494 return 0; 494 return 0;
495 495
496 ret = platform_driver_register(&sony_pf_driver); 496 ret = platform_driver_register(&sony_pf_driver);
497 if (ret) 497 if (ret)
498 goto out; 498 goto out;
499 499
500 sony_pf_device = platform_device_alloc("sony-laptop", -1); 500 sony_pf_device = platform_device_alloc("sony-laptop", -1);
501 if (!sony_pf_device) { 501 if (!sony_pf_device) {
502 ret = -ENOMEM; 502 ret = -ENOMEM;
503 goto out_platform_registered; 503 goto out_platform_registered;
504 } 504 }
505 505
506 ret = platform_device_add(sony_pf_device); 506 ret = platform_device_add(sony_pf_device);
507 if (ret) 507 if (ret)
508 goto out_platform_alloced; 508 goto out_platform_alloced;
509 509
510 return 0; 510 return 0;
511 511
512 out_platform_alloced: 512 out_platform_alloced:
513 platform_device_put(sony_pf_device); 513 platform_device_put(sony_pf_device);
514 sony_pf_device = NULL; 514 sony_pf_device = NULL;
515 out_platform_registered: 515 out_platform_registered:
516 platform_driver_unregister(&sony_pf_driver); 516 platform_driver_unregister(&sony_pf_driver);
517 out: 517 out:
518 atomic_dec(&sony_pf_users); 518 atomic_dec(&sony_pf_users);
519 return ret; 519 return ret;
520 } 520 }
521 521
522 static void sony_pf_remove(void) 522 static void sony_pf_remove(void)
523 { 523 {
524 /* deregister only after the last user has gone */ 524 /* deregister only after the last user has gone */
525 if (!atomic_dec_and_test(&sony_pf_users)) 525 if (!atomic_dec_and_test(&sony_pf_users))
526 return; 526 return;
527 527
528 platform_device_del(sony_pf_device); 528 platform_device_del(sony_pf_device);
529 platform_device_put(sony_pf_device); 529 platform_device_put(sony_pf_device);
530 platform_driver_unregister(&sony_pf_driver); 530 platform_driver_unregister(&sony_pf_driver);
531 } 531 }
532 532
533 /*********** SNC (SNY5001) Device ***********/ 533 /*********** SNC (SNY5001) Device ***********/
534 534
535 /* the device uses 1-based values, while the backlight subsystem uses 535 /* the device uses 1-based values, while the backlight subsystem uses
536 0-based values */ 536 0-based values */
537 #define SONY_MAX_BRIGHTNESS 8 537 #define SONY_MAX_BRIGHTNESS 8
538 538
539 #define SNC_VALIDATE_IN 0 539 #define SNC_VALIDATE_IN 0
540 #define SNC_VALIDATE_OUT 1 540 #define SNC_VALIDATE_OUT 1
541 541
542 static ssize_t sony_nc_sysfs_show(struct device *, struct device_attribute *, 542 static ssize_t sony_nc_sysfs_show(struct device *, struct device_attribute *,
543 char *); 543 char *);
544 static ssize_t sony_nc_sysfs_store(struct device *, struct device_attribute *, 544 static ssize_t sony_nc_sysfs_store(struct device *, struct device_attribute *,
545 const char *, size_t); 545 const char *, size_t);
546 static int boolean_validate(const int, const int); 546 static int boolean_validate(const int, const int);
547 static int brightness_default_validate(const int, const int); 547 static int brightness_default_validate(const int, const int);
548 548
549 struct sony_nc_value { 549 struct sony_nc_value {
550 char *name; /* name of the entry */ 550 char *name; /* name of the entry */
551 char **acpiget; /* names of the ACPI get function */ 551 char **acpiget; /* names of the ACPI get function */
552 char **acpiset; /* names of the ACPI set function */ 552 char **acpiset; /* names of the ACPI set function */
553 int (*validate)(const int, const int); /* input/output validation */ 553 int (*validate)(const int, const int); /* input/output validation */
554 int value; /* current setting */ 554 int value; /* current setting */
555 int valid; /* Has ever been set */ 555 int valid; /* Has ever been set */
556 int debug; /* active only in debug mode ? */ 556 int debug; /* active only in debug mode ? */
557 struct device_attribute devattr; /* sysfs atribute */ 557 struct device_attribute devattr; /* sysfs atribute */
558 }; 558 };
559 559
560 #define SNC_HANDLE_NAMES(_name, _values...) \ 560 #define SNC_HANDLE_NAMES(_name, _values...) \
561 static char *snc_##_name[] = { _values, NULL } 561 static char *snc_##_name[] = { _values, NULL }
562 562
563 #define SNC_HANDLE(_name, _getters, _setters, _validate, _debug) \ 563 #define SNC_HANDLE(_name, _getters, _setters, _validate, _debug) \
564 { \ 564 { \
565 .name = __stringify(_name), \ 565 .name = __stringify(_name), \
566 .acpiget = _getters, \ 566 .acpiget = _getters, \
567 .acpiset = _setters, \ 567 .acpiset = _setters, \
568 .validate = _validate, \ 568 .validate = _validate, \
569 .debug = _debug, \ 569 .debug = _debug, \
570 .devattr = __ATTR(_name, 0, sony_nc_sysfs_show, sony_nc_sysfs_store), \ 570 .devattr = __ATTR(_name, 0, sony_nc_sysfs_show, sony_nc_sysfs_store), \
571 } 571 }
572 572
573 #define SNC_HANDLE_NULL { .name = NULL } 573 #define SNC_HANDLE_NULL { .name = NULL }
574 574
575 SNC_HANDLE_NAMES(fnkey_get, "GHKE"); 575 SNC_HANDLE_NAMES(fnkey_get, "GHKE");
576 576
577 SNC_HANDLE_NAMES(brightness_def_get, "GPBR"); 577 SNC_HANDLE_NAMES(brightness_def_get, "GPBR");
578 SNC_HANDLE_NAMES(brightness_def_set, "SPBR"); 578 SNC_HANDLE_NAMES(brightness_def_set, "SPBR");
579 579
580 SNC_HANDLE_NAMES(cdpower_get, "GCDP"); 580 SNC_HANDLE_NAMES(cdpower_get, "GCDP");
581 SNC_HANDLE_NAMES(cdpower_set, "SCDP", "CDPW"); 581 SNC_HANDLE_NAMES(cdpower_set, "SCDP", "CDPW");
582 582
583 SNC_HANDLE_NAMES(audiopower_get, "GAZP"); 583 SNC_HANDLE_NAMES(audiopower_get, "GAZP");
584 SNC_HANDLE_NAMES(audiopower_set, "AZPW"); 584 SNC_HANDLE_NAMES(audiopower_set, "AZPW");
585 585
586 SNC_HANDLE_NAMES(lanpower_get, "GLNP"); 586 SNC_HANDLE_NAMES(lanpower_get, "GLNP");
587 SNC_HANDLE_NAMES(lanpower_set, "LNPW"); 587 SNC_HANDLE_NAMES(lanpower_set, "LNPW");
588 588
589 SNC_HANDLE_NAMES(lidstate_get, "GLID"); 589 SNC_HANDLE_NAMES(lidstate_get, "GLID");
590 590
591 SNC_HANDLE_NAMES(indicatorlamp_get, "GILS"); 591 SNC_HANDLE_NAMES(indicatorlamp_get, "GILS");
592 SNC_HANDLE_NAMES(indicatorlamp_set, "SILS"); 592 SNC_HANDLE_NAMES(indicatorlamp_set, "SILS");
593 593
594 SNC_HANDLE_NAMES(gainbass_get, "GMGB"); 594 SNC_HANDLE_NAMES(gainbass_get, "GMGB");
595 SNC_HANDLE_NAMES(gainbass_set, "CMGB"); 595 SNC_HANDLE_NAMES(gainbass_set, "CMGB");
596 596
597 SNC_HANDLE_NAMES(PID_get, "GPID"); 597 SNC_HANDLE_NAMES(PID_get, "GPID");
598 598
599 SNC_HANDLE_NAMES(CTR_get, "GCTR"); 599 SNC_HANDLE_NAMES(CTR_get, "GCTR");
600 SNC_HANDLE_NAMES(CTR_set, "SCTR"); 600 SNC_HANDLE_NAMES(CTR_set, "SCTR");
601 601
602 SNC_HANDLE_NAMES(PCR_get, "GPCR"); 602 SNC_HANDLE_NAMES(PCR_get, "GPCR");
603 SNC_HANDLE_NAMES(PCR_set, "SPCR"); 603 SNC_HANDLE_NAMES(PCR_set, "SPCR");
604 604
605 SNC_HANDLE_NAMES(CMI_get, "GCMI"); 605 SNC_HANDLE_NAMES(CMI_get, "GCMI");
606 SNC_HANDLE_NAMES(CMI_set, "SCMI"); 606 SNC_HANDLE_NAMES(CMI_set, "SCMI");
607 607
608 static struct sony_nc_value sony_nc_values[] = { 608 static struct sony_nc_value sony_nc_values[] = {
609 SNC_HANDLE(brightness_default, snc_brightness_def_get, 609 SNC_HANDLE(brightness_default, snc_brightness_def_get,
610 snc_brightness_def_set, brightness_default_validate, 0), 610 snc_brightness_def_set, brightness_default_validate, 0),
611 SNC_HANDLE(fnkey, snc_fnkey_get, NULL, NULL, 0), 611 SNC_HANDLE(fnkey, snc_fnkey_get, NULL, NULL, 0),
612 SNC_HANDLE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0), 612 SNC_HANDLE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0),
613 SNC_HANDLE(audiopower, snc_audiopower_get, snc_audiopower_set, 613 SNC_HANDLE(audiopower, snc_audiopower_get, snc_audiopower_set,
614 boolean_validate, 0), 614 boolean_validate, 0),
615 SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set, 615 SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set,
616 boolean_validate, 1), 616 boolean_validate, 1),
617 SNC_HANDLE(lidstate, snc_lidstate_get, NULL, 617 SNC_HANDLE(lidstate, snc_lidstate_get, NULL,
618 boolean_validate, 0), 618 boolean_validate, 0),
619 SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set, 619 SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set,
620 boolean_validate, 0), 620 boolean_validate, 0),
621 SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set, 621 SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set,
622 boolean_validate, 0), 622 boolean_validate, 0),
623 /* unknown methods */ 623 /* unknown methods */
624 SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1), 624 SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1),
625 SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), 625 SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1),
626 SNC_HANDLE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1), 626 SNC_HANDLE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1),
627 SNC_HANDLE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1), 627 SNC_HANDLE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1),
628 SNC_HANDLE_NULL 628 SNC_HANDLE_NULL
629 }; 629 };
630 630
631 static acpi_handle sony_nc_acpi_handle; 631 static acpi_handle sony_nc_acpi_handle;
632 static struct acpi_device *sony_nc_acpi_device = NULL; 632 static struct acpi_device *sony_nc_acpi_device = NULL;
633 633
634 /* 634 /*
635 * acpi_evaluate_object wrappers 635 * acpi_evaluate_object wrappers
636 */ 636 */
637 static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) 637 static int acpi_callgetfunc(acpi_handle handle, char *name, int *result)
638 { 638 {
639 struct acpi_buffer output; 639 struct acpi_buffer output;
640 union acpi_object out_obj; 640 union acpi_object out_obj;
641 acpi_status status; 641 acpi_status status;
642 642
643 output.length = sizeof(out_obj); 643 output.length = sizeof(out_obj);
644 output.pointer = &out_obj; 644 output.pointer = &out_obj;
645 645
646 status = acpi_evaluate_object(handle, name, NULL, &output); 646 status = acpi_evaluate_object(handle, name, NULL, &output);
647 if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) { 647 if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) {
648 *result = out_obj.integer.value; 648 *result = out_obj.integer.value;
649 return 0; 649 return 0;
650 } 650 }
651 651
652 printk(KERN_WARNING DRV_PFX "acpi_callreadfunc failed\n"); 652 printk(KERN_WARNING DRV_PFX "acpi_callreadfunc failed\n");
653 653
654 return -1; 654 return -1;
655 } 655 }
656 656
657 static int acpi_callsetfunc(acpi_handle handle, char *name, int value, 657 static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
658 int *result) 658 int *result)
659 { 659 {
660 struct acpi_object_list params; 660 struct acpi_object_list params;
661 union acpi_object in_obj; 661 union acpi_object in_obj;
662 struct acpi_buffer output; 662 struct acpi_buffer output;
663 union acpi_object out_obj; 663 union acpi_object out_obj;
664 acpi_status status; 664 acpi_status status;
665 665
666 params.count = 1; 666 params.count = 1;
667 params.pointer = &in_obj; 667 params.pointer = &in_obj;
668 in_obj.type = ACPI_TYPE_INTEGER; 668 in_obj.type = ACPI_TYPE_INTEGER;
669 in_obj.integer.value = value; 669 in_obj.integer.value = value;
670 670
671 output.length = sizeof(out_obj); 671 output.length = sizeof(out_obj);
672 output.pointer = &out_obj; 672 output.pointer = &out_obj;
673 673
674 status = acpi_evaluate_object(handle, name, &params, &output); 674 status = acpi_evaluate_object(handle, name, &params, &output);
675 if (status == AE_OK) { 675 if (status == AE_OK) {
676 if (result != NULL) { 676 if (result != NULL) {
677 if (out_obj.type != ACPI_TYPE_INTEGER) { 677 if (out_obj.type != ACPI_TYPE_INTEGER) {
678 printk(KERN_WARNING DRV_PFX "acpi_evaluate_object bad " 678 printk(KERN_WARNING DRV_PFX "acpi_evaluate_object bad "
679 "return type\n"); 679 "return type\n");
680 return -1; 680 return -1;
681 } 681 }
682 *result = out_obj.integer.value; 682 *result = out_obj.integer.value;
683 } 683 }
684 return 0; 684 return 0;
685 } 685 }
686 686
687 printk(KERN_WARNING DRV_PFX "acpi_evaluate_object failed\n"); 687 printk(KERN_WARNING DRV_PFX "acpi_evaluate_object failed\n");
688 688
689 return -1; 689 return -1;
690 } 690 }
691 691
692 /* 692 /*
693 * sony_nc_values input/output validate functions 693 * sony_nc_values input/output validate functions
694 */ 694 */
695 695
696 /* brightness_default_validate: 696 /* brightness_default_validate:
697 * 697 *
698 * manipulate input output values to keep consistency with the 698 * manipulate input output values to keep consistency with the
699 * backlight framework for which brightness values are 0-based. 699 * backlight framework for which brightness values are 0-based.
700 */ 700 */
701 static int brightness_default_validate(const int direction, const int value) 701 static int brightness_default_validate(const int direction, const int value)
702 { 702 {
703 switch (direction) { 703 switch (direction) {
704 case SNC_VALIDATE_OUT: 704 case SNC_VALIDATE_OUT:
705 return value - 1; 705 return value - 1;
706 case SNC_VALIDATE_IN: 706 case SNC_VALIDATE_IN:
707 if (value >= 0 && value < SONY_MAX_BRIGHTNESS) 707 if (value >= 0 && value < SONY_MAX_BRIGHTNESS)
708 return value + 1; 708 return value + 1;
709 } 709 }
710 return -EINVAL; 710 return -EINVAL;
711 } 711 }
712 712
713 /* boolean_validate: 713 /* boolean_validate:
714 * 714 *
715 * on input validate boolean values 0/1, on output just pass the 715 * on input validate boolean values 0/1, on output just pass the
716 * received value. 716 * received value.
717 */ 717 */
718 static int boolean_validate(const int direction, const int value) 718 static int boolean_validate(const int direction, const int value)
719 { 719 {
720 if (direction == SNC_VALIDATE_IN) { 720 if (direction == SNC_VALIDATE_IN) {
721 if (value != 0 && value != 1) 721 if (value != 0 && value != 1)
722 return -EINVAL; 722 return -EINVAL;
723 } 723 }
724 return value; 724 return value;
725 } 725 }
726 726
727 /* 727 /*
728 * Sysfs show/store common to all sony_nc_values 728 * Sysfs show/store common to all sony_nc_values
729 */ 729 */
730 static ssize_t sony_nc_sysfs_show(struct device *dev, struct device_attribute *attr, 730 static ssize_t sony_nc_sysfs_show(struct device *dev, struct device_attribute *attr,
731 char *buffer) 731 char *buffer)
732 { 732 {
733 int value; 733 int value;
734 struct sony_nc_value *item = 734 struct sony_nc_value *item =
735 container_of(attr, struct sony_nc_value, devattr); 735 container_of(attr, struct sony_nc_value, devattr);
736 736
737 if (!*item->acpiget) 737 if (!*item->acpiget)
738 return -EIO; 738 return -EIO;
739 739
740 if (acpi_callgetfunc(sony_nc_acpi_handle, *item->acpiget, &value) < 0) 740 if (acpi_callgetfunc(sony_nc_acpi_handle, *item->acpiget, &value) < 0)
741 return -EIO; 741 return -EIO;
742 742
743 if (item->validate) 743 if (item->validate)
744 value = item->validate(SNC_VALIDATE_OUT, value); 744 value = item->validate(SNC_VALIDATE_OUT, value);
745 745
746 return snprintf(buffer, PAGE_SIZE, "%d\n", value); 746 return snprintf(buffer, PAGE_SIZE, "%d\n", value);
747 } 747 }
748 748
749 static ssize_t sony_nc_sysfs_store(struct device *dev, 749 static ssize_t sony_nc_sysfs_store(struct device *dev,
750 struct device_attribute *attr, 750 struct device_attribute *attr,
751 const char *buffer, size_t count) 751 const char *buffer, size_t count)
752 { 752 {
753 int value; 753 int value;
754 struct sony_nc_value *item = 754 struct sony_nc_value *item =
755 container_of(attr, struct sony_nc_value, devattr); 755 container_of(attr, struct sony_nc_value, devattr);
756 756
757 if (!item->acpiset) 757 if (!item->acpiset)
758 return -EIO; 758 return -EIO;
759 759
760 if (count > 31) 760 if (count > 31)
761 return -EINVAL; 761 return -EINVAL;
762 762
763 value = simple_strtoul(buffer, NULL, 10); 763 value = simple_strtoul(buffer, NULL, 10);
764 764
765 if (item->validate) 765 if (item->validate)
766 value = item->validate(SNC_VALIDATE_IN, value); 766 value = item->validate(SNC_VALIDATE_IN, value);
767 767
768 if (value < 0) 768 if (value < 0)
769 return value; 769 return value;
770 770
771 if (acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, value, NULL) < 0) 771 if (acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, value, NULL) < 0)
772 return -EIO; 772 return -EIO;
773 item->value = value; 773 item->value = value;
774 item->valid = 1; 774 item->valid = 1;
775 return count; 775 return count;
776 } 776 }
777 777
778 778
779 /* 779 /*
780 * Backlight device 780 * Backlight device
781 */ 781 */
782 static int sony_backlight_update_status(struct backlight_device *bd) 782 static int sony_backlight_update_status(struct backlight_device *bd)
783 { 783 {
784 return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT", 784 return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT",
785 bd->props.brightness + 1, NULL); 785 bd->props.brightness + 1, NULL);
786 } 786 }
787 787
788 static int sony_backlight_get_brightness(struct backlight_device *bd) 788 static int sony_backlight_get_brightness(struct backlight_device *bd)
789 { 789 {
790 int value; 790 int value;
791 791
792 if (acpi_callgetfunc(sony_nc_acpi_handle, "GBRT", &value)) 792 if (acpi_callgetfunc(sony_nc_acpi_handle, "GBRT", &value))
793 return 0; 793 return 0;
794 /* brightness levels are 1-based, while backlight ones are 0-based */ 794 /* brightness levels are 1-based, while backlight ones are 0-based */
795 return value - 1; 795 return value - 1;
796 } 796 }
797 797
798 static struct backlight_device *sony_backlight_device; 798 static struct backlight_device *sony_backlight_device;
799 static struct backlight_ops sony_backlight_ops = { 799 static struct backlight_ops sony_backlight_ops = {
800 .update_status = sony_backlight_update_status, 800 .update_status = sony_backlight_update_status,
801 .get_brightness = sony_backlight_get_brightness, 801 .get_brightness = sony_backlight_get_brightness,
802 }; 802 };
803 803
804 /* 804 /*
805 * New SNC-only Vaios event mapping to driver known keys 805 * New SNC-only Vaios event mapping to driver known keys
806 */ 806 */
807 struct sony_nc_event { 807 struct sony_nc_event {
808 u8 data; 808 u8 data;
809 u8 event; 809 u8 event;
810 }; 810 };
811 811
812 static struct sony_nc_event *sony_nc_events; 812 static struct sony_nc_event *sony_nc_events;
813 813
814 /* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence 814 /* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
815 * for Fn keys 815 * for Fn keys
816 */ 816 */
817 static int sony_nc_C_enable(const struct dmi_system_id *id) 817 static int sony_nc_C_enable(const struct dmi_system_id *id)
818 { 818 {
819 int result = 0; 819 int result = 0;
820 820
821 printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident); 821 printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);
822 822
823 sony_nc_events = id->driver_data; 823 sony_nc_events = id->driver_data;
824 824
825 if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0 825 if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0
826 || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0 826 || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0
827 || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0 827 || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0
828 || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0 828 || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0
829 || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0 829 || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0
830 || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) { 830 || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {
831 printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some " 831 printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "
832 "functionalities may be missing\n"); 832 "functionalities may be missing\n");
833 return 1; 833 return 1;
834 } 834 }
835 return 0; 835 return 0;
836 } 836 }
837 837
838 static struct sony_nc_event sony_C_events[] = { 838 static struct sony_nc_event sony_C_events[] = {
839 { 0x81, SONYPI_EVENT_FNKEY_F1 }, 839 { 0x81, SONYPI_EVENT_FNKEY_F1 },
840 { 0x01, SONYPI_EVENT_FNKEY_RELEASED }, 840 { 0x01, SONYPI_EVENT_FNKEY_RELEASED },
841 { 0x85, SONYPI_EVENT_FNKEY_F5 }, 841 { 0x85, SONYPI_EVENT_FNKEY_F5 },
842 { 0x05, SONYPI_EVENT_FNKEY_RELEASED }, 842 { 0x05, SONYPI_EVENT_FNKEY_RELEASED },
843 { 0x86, SONYPI_EVENT_FNKEY_F6 }, 843 { 0x86, SONYPI_EVENT_FNKEY_F6 },
844 { 0x06, SONYPI_EVENT_FNKEY_RELEASED }, 844 { 0x06, SONYPI_EVENT_FNKEY_RELEASED },
845 { 0x87, SONYPI_EVENT_FNKEY_F7 }, 845 { 0x87, SONYPI_EVENT_FNKEY_F7 },
846 { 0x07, SONYPI_EVENT_FNKEY_RELEASED }, 846 { 0x07, SONYPI_EVENT_FNKEY_RELEASED },
847 { 0x8A, SONYPI_EVENT_FNKEY_F10 }, 847 { 0x8A, SONYPI_EVENT_FNKEY_F10 },
848 { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, 848 { 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
849 { 0x8C, SONYPI_EVENT_FNKEY_F12 }, 849 { 0x8C, SONYPI_EVENT_FNKEY_F12 },
850 { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, 850 { 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
851 { 0, 0 }, 851 { 0, 0 },
852 }; 852 };
853 853
854 /* SNC-only model map */ 854 /* SNC-only model map */
855 static const struct dmi_system_id sony_nc_ids[] = { 855 static const struct dmi_system_id sony_nc_ids[] = {
856 { 856 {
857 .ident = "Sony Vaio FE Series", 857 .ident = "Sony Vaio FE Series",
858 .callback = sony_nc_C_enable, 858 .callback = sony_nc_C_enable,
859 .driver_data = sony_C_events, 859 .driver_data = sony_C_events,
860 .matches = { 860 .matches = {
861 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 861 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
862 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"), 862 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),
863 }, 863 },
864 }, 864 },
865 { 865 {
866 .ident = "Sony Vaio FZ Series", 866 .ident = "Sony Vaio FZ Series",
867 .callback = sony_nc_C_enable, 867 .callback = sony_nc_C_enable,
868 .driver_data = sony_C_events, 868 .driver_data = sony_C_events,
869 .matches = { 869 .matches = {
870 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 870 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
871 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"), 871 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),
872 }, 872 },
873 }, 873 },
874 { 874 {
875 .ident = "Sony Vaio C Series", 875 .ident = "Sony Vaio C Series",
876 .callback = sony_nc_C_enable, 876 .callback = sony_nc_C_enable,
877 .driver_data = sony_C_events, 877 .driver_data = sony_C_events,
878 .matches = { 878 .matches = {
879 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 879 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
880 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"), 880 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
881 }, 881 },
882 }, 882 },
883 { 883 {
884 .ident = "Sony Vaio N Series", 884 .ident = "Sony Vaio N Series",
885 .callback = sony_nc_C_enable, 885 .callback = sony_nc_C_enable,
886 .driver_data = sony_C_events, 886 .driver_data = sony_C_events,
887 .matches = { 887 .matches = {
888 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 888 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
889 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"), 889 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"),
890 }, 890 },
891 }, 891 },
892 { } 892 { }
893 }; 893 };
894 894
895 /* 895 /*
896 * ACPI callbacks 896 * ACPI callbacks
897 */ 897 */
898 static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) 898 static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
899 { 899 {
900 struct sony_nc_event *evmap; 900 struct sony_nc_event *evmap;
901 u32 ev = event; 901 u32 ev = event;
902 int result; 902 int result;
903 903
904 if (ev == 0x92) { 904 if (ev == 0x92) {
905 /* read the key pressed from EC.GECR 905 /* read the key pressed from EC.GECR
906 * A call to SN07 with 0x0202 will do it as well respecting 906 * A call to SN07 with 0x0202 will do it as well respecting
907 * the current protocol on different OSes 907 * the current protocol on different OSes
908 * 908 *
909 * Note: the path for GECR may be 909 * Note: the path for GECR may be
910 * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends) 910 * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
911 * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR) 911 * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
912 * 912 *
913 * TODO: we may want to do the same for the older GHKE -need 913 * TODO: we may want to do the same for the older GHKE -need
914 * dmi list- so this snippet may become one more callback. 914 * dmi list- so this snippet may become one more callback.
915 */ 915 */
916 if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0) 916 if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)
917 dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev); 917 dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);
918 else 918 else
919 ev = result & 0xFF; 919 ev = result & 0xFF;
920 } 920 }
921 921
922 if (sony_nc_events) 922 if (sony_nc_events)
923 for (evmap = sony_nc_events; evmap->event; evmap++) { 923 for (evmap = sony_nc_events; evmap->event; evmap++) {
924 if (evmap->data == ev) { 924 if (evmap->data == ev) {
925 ev = evmap->event; 925 ev = evmap->event;
926 break; 926 break;
927 } 927 }
928 } 928 }
929 929
930 dprintk("sony_acpi_notify, event: 0x%.2x\n", ev); 930 dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
931 sony_laptop_report_input_event(ev); 931 sony_laptop_report_input_event(ev);
932 acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev); 932 acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
933 } 933 }
934 934
935 static acpi_status sony_walk_callback(acpi_handle handle, u32 level, 935 static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
936 void *context, void **return_value) 936 void *context, void **return_value)
937 { 937 {
938 struct acpi_namespace_node *node; 938 struct acpi_namespace_node *node;
939 union acpi_operand_object *operand; 939 union acpi_operand_object *operand;
940 940
941 node = (struct acpi_namespace_node *)handle; 941 node = (struct acpi_namespace_node *)handle;
942 operand = (union acpi_operand_object *)node->object; 942 operand = (union acpi_operand_object *)node->object;
943 943
944 printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", node->name.ascii, 944 printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", node->name.ascii,
945 (u32) operand->method.param_count); 945 (u32) operand->method.param_count);
946 946
947 return AE_OK; 947 return AE_OK;
948 } 948 }
949 949
950 /* 950 /*
951 * ACPI device 951 * ACPI device
952 */ 952 */
953 static int sony_nc_resume(struct acpi_device *device) 953 static int sony_nc_resume(struct acpi_device *device)
954 { 954 {
955 struct sony_nc_value *item; 955 struct sony_nc_value *item;
956 956
957 for (item = sony_nc_values; item->name; item++) { 957 for (item = sony_nc_values; item->name; item++) {
958 int ret; 958 int ret;
959 959
960 if (!item->valid) 960 if (!item->valid)
961 continue; 961 continue;
962 ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, 962 ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset,
963 item->value, NULL); 963 item->value, NULL);
964 if (ret < 0) { 964 if (ret < 0) {
965 printk("%s: %d\n", __func__, ret); 965 printk("%s: %d\n", __func__, ret);
966 break; 966 break;
967 } 967 }
968 } 968 }
969 969
970 /* set the last requested brightness level */ 970 /* set the last requested brightness level */
971 if (sony_backlight_device && 971 if (sony_backlight_device &&
972 !sony_backlight_update_status(sony_backlight_device)) 972 !sony_backlight_update_status(sony_backlight_device))
973 printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n"); 973 printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
974 974
975 /* re-initialize models with specific requirements */ 975 /* re-initialize models with specific requirements */
976 dmi_check_system(sony_nc_ids); 976 dmi_check_system(sony_nc_ids);
977 977
978 return 0; 978 return 0;
979 } 979 }
980 980
981 static int sony_nc_add(struct acpi_device *device) 981 static int sony_nc_add(struct acpi_device *device)
982 { 982 {
983 acpi_status status; 983 acpi_status status;
984 int result = 0; 984 int result = 0;
985 acpi_handle handle; 985 acpi_handle handle;
986 struct sony_nc_value *item; 986 struct sony_nc_value *item;
987 987
988 printk(KERN_INFO DRV_PFX "%s v%s.\n", 988 printk(KERN_INFO DRV_PFX "%s v%s.\n",
989 SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); 989 SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
990 990
991 sony_nc_acpi_device = device; 991 sony_nc_acpi_device = device;
992 strcpy(acpi_device_class(device), "sony/hotkey"); 992 strcpy(acpi_device_class(device), "sony/hotkey");
993 993
994 sony_nc_acpi_handle = device->handle; 994 sony_nc_acpi_handle = device->handle;
995 995
996 /* read device status */ 996 /* read device status */
997 result = acpi_bus_get_status(device); 997 result = acpi_bus_get_status(device);
998 /* bail IFF the above call was successful and the device is not present */ 998 /* bail IFF the above call was successful and the device is not present */
999 if (!result && !device->status.present) { 999 if (!result && !device->status.present) {
1000 dprintk("Device not present\n"); 1000 dprintk("Device not present\n");
1001 result = -ENODEV; 1001 result = -ENODEV;
1002 goto outwalk; 1002 goto outwalk;
1003 } 1003 }
1004 1004
1005 if (debug) { 1005 if (debug) {
1006 status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, 1006 status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle,
1007 1, sony_walk_callback, NULL, NULL); 1007 1, sony_walk_callback, NULL, NULL);
1008 if (ACPI_FAILURE(status)) { 1008 if (ACPI_FAILURE(status)) {
1009 printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n"); 1009 printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n");
1010 result = -ENODEV; 1010 result = -ENODEV;
1011 goto outwalk; 1011 goto outwalk;
1012 } 1012 }
1013 } 1013 }
1014 1014
1015 /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1 1015 /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1
1016 * should be respected as we already checked for the device presence above */ 1016 * should be respected as we already checked for the device presence above */
1017 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) { 1017 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) {
1018 dprintk("Invoking _INI\n"); 1018 dprintk("Invoking _INI\n");
1019 if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI, 1019 if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI,
1020 NULL, NULL))) 1020 NULL, NULL)))
1021 dprintk("_INI Method failed\n"); 1021 dprintk("_INI Method failed\n");
1022 } 1022 }
1023 1023
1024 /* setup input devices and helper fifo */ 1024 /* setup input devices and helper fifo */
1025 result = sony_laptop_setup_input(device); 1025 result = sony_laptop_setup_input(device);
1026 if (result) { 1026 if (result) {
1027 printk(KERN_ERR DRV_PFX 1027 printk(KERN_ERR DRV_PFX
1028 "Unabe to create input devices.\n"); 1028 "Unabe to create input devices.\n");
1029 goto outwalk; 1029 goto outwalk;
1030 } 1030 }
1031 1031
1032 status = acpi_install_notify_handler(sony_nc_acpi_handle, 1032 status = acpi_install_notify_handler(sony_nc_acpi_handle,
1033 ACPI_DEVICE_NOTIFY, 1033 ACPI_DEVICE_NOTIFY,
1034 sony_acpi_notify, NULL); 1034 sony_acpi_notify, NULL);
1035 if (ACPI_FAILURE(status)) { 1035 if (ACPI_FAILURE(status)) {
1036 printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status); 1036 printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status);
1037 result = -ENODEV; 1037 result = -ENODEV;
1038 goto outinput; 1038 goto outinput;
1039 } 1039 }
1040 1040
1041 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", &handle))) { 1041 if (!acpi_video_backlight_support()) {
1042 printk(KERN_INFO DRV_PFX "Sony: Brightness ignored, must be "
1043 "controlled by ACPI video driver\n");
1044 } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
1045 &handle))) {
1042 sony_backlight_device = backlight_device_register("sony", NULL, 1046 sony_backlight_device = backlight_device_register("sony", NULL,
1043 NULL, 1047 NULL,
1044 &sony_backlight_ops); 1048 &sony_backlight_ops);
1045 1049
1046 if (IS_ERR(sony_backlight_device)) { 1050 if (IS_ERR(sony_backlight_device)) {
1047 printk(KERN_WARNING DRV_PFX "unable to register backlight device\n"); 1051 printk(KERN_WARNING DRV_PFX "unable to register backlight device\n");
1048 sony_backlight_device = NULL; 1052 sony_backlight_device = NULL;
1049 } else { 1053 } else {
1050 sony_backlight_device->props.brightness = 1054 sony_backlight_device->props.brightness =
1051 sony_backlight_get_brightness 1055 sony_backlight_get_brightness
1052 (sony_backlight_device); 1056 (sony_backlight_device);
1053 sony_backlight_device->props.max_brightness = 1057 sony_backlight_device->props.max_brightness =
1054 SONY_MAX_BRIGHTNESS - 1; 1058 SONY_MAX_BRIGHTNESS - 1;
1055 } 1059 }
1056 1060
1057 } 1061 }
1058 1062
1059 /* initialize models with specific requirements */ 1063 /* initialize models with specific requirements */
1060 dmi_check_system(sony_nc_ids); 1064 dmi_check_system(sony_nc_ids);
1061 1065
1062 result = sony_pf_add(); 1066 result = sony_pf_add();
1063 if (result) 1067 if (result)
1064 goto outbacklight; 1068 goto outbacklight;
1065 1069
1066 /* create sony_pf sysfs attributes related to the SNC device */ 1070 /* create sony_pf sysfs attributes related to the SNC device */
1067 for (item = sony_nc_values; item->name; ++item) { 1071 for (item = sony_nc_values; item->name; ++item) {
1068 1072
1069 if (!debug && item->debug) 1073 if (!debug && item->debug)
1070 continue; 1074 continue;
1071 1075
1072 /* find the available acpiget as described in the DSDT */ 1076 /* find the available acpiget as described in the DSDT */
1073 for (; item->acpiget && *item->acpiget; ++item->acpiget) { 1077 for (; item->acpiget && *item->acpiget; ++item->acpiget) {
1074 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, 1078 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle,
1075 *item->acpiget, 1079 *item->acpiget,
1076 &handle))) { 1080 &handle))) {
1077 dprintk("Found %s getter: %s\n", 1081 dprintk("Found %s getter: %s\n",
1078 item->name, *item->acpiget); 1082 item->name, *item->acpiget);
1079 item->devattr.attr.mode |= S_IRUGO; 1083 item->devattr.attr.mode |= S_IRUGO;
1080 break; 1084 break;
1081 } 1085 }
1082 } 1086 }
1083 1087
1084 /* find the available acpiset as described in the DSDT */ 1088 /* find the available acpiset as described in the DSDT */
1085 for (; item->acpiset && *item->acpiset; ++item->acpiset) { 1089 for (; item->acpiset && *item->acpiset; ++item->acpiset) {
1086 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, 1090 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle,
1087 *item->acpiset, 1091 *item->acpiset,
1088 &handle))) { 1092 &handle))) {
1089 dprintk("Found %s setter: %s\n", 1093 dprintk("Found %s setter: %s\n",
1090 item->name, *item->acpiset); 1094 item->name, *item->acpiset);
1091 item->devattr.attr.mode |= S_IWUSR; 1095 item->devattr.attr.mode |= S_IWUSR;
1092 break; 1096 break;
1093 } 1097 }
1094 } 1098 }
1095 1099
1096 if (item->devattr.attr.mode != 0) { 1100 if (item->devattr.attr.mode != 0) {
1097 result = 1101 result =
1098 device_create_file(&sony_pf_device->dev, 1102 device_create_file(&sony_pf_device->dev,
1099 &item->devattr); 1103 &item->devattr);
1100 if (result) 1104 if (result)
1101 goto out_sysfs; 1105 goto out_sysfs;
1102 } 1106 }
1103 } 1107 }
1104 1108
1105 return 0; 1109 return 0;
1106 1110
1107 out_sysfs: 1111 out_sysfs:
1108 for (item = sony_nc_values; item->name; ++item) { 1112 for (item = sony_nc_values; item->name; ++item) {
1109 device_remove_file(&sony_pf_device->dev, &item->devattr); 1113 device_remove_file(&sony_pf_device->dev, &item->devattr);
1110 } 1114 }
1111 sony_pf_remove(); 1115 sony_pf_remove();
1112 1116
1113 outbacklight: 1117 outbacklight:
1114 if (sony_backlight_device) 1118 if (sony_backlight_device)
1115 backlight_device_unregister(sony_backlight_device); 1119 backlight_device_unregister(sony_backlight_device);
1116 1120
1117 status = acpi_remove_notify_handler(sony_nc_acpi_handle, 1121 status = acpi_remove_notify_handler(sony_nc_acpi_handle,
1118 ACPI_DEVICE_NOTIFY, 1122 ACPI_DEVICE_NOTIFY,
1119 sony_acpi_notify); 1123 sony_acpi_notify);
1120 if (ACPI_FAILURE(status)) 1124 if (ACPI_FAILURE(status))
1121 printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n"); 1125 printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
1122 1126
1123 outinput: 1127 outinput:
1124 sony_laptop_remove_input(); 1128 sony_laptop_remove_input();
1125 1129
1126 outwalk: 1130 outwalk:
1127 return result; 1131 return result;
1128 } 1132 }
1129 1133
1130 static int sony_nc_remove(struct acpi_device *device, int type) 1134 static int sony_nc_remove(struct acpi_device *device, int type)
1131 { 1135 {
1132 acpi_status status; 1136 acpi_status status;
1133 struct sony_nc_value *item; 1137 struct sony_nc_value *item;
1134 1138
1135 if (sony_backlight_device) 1139 if (sony_backlight_device)
1136 backlight_device_unregister(sony_backlight_device); 1140 backlight_device_unregister(sony_backlight_device);
1137 1141
1138 sony_nc_acpi_device = NULL; 1142 sony_nc_acpi_device = NULL;
1139 1143
1140 status = acpi_remove_notify_handler(sony_nc_acpi_handle, 1144 status = acpi_remove_notify_handler(sony_nc_acpi_handle,
1141 ACPI_DEVICE_NOTIFY, 1145 ACPI_DEVICE_NOTIFY,
1142 sony_acpi_notify); 1146 sony_acpi_notify);
1143 if (ACPI_FAILURE(status)) 1147 if (ACPI_FAILURE(status))
1144 printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n"); 1148 printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
1145 1149
1146 for (item = sony_nc_values; item->name; ++item) { 1150 for (item = sony_nc_values; item->name; ++item) {
1147 device_remove_file(&sony_pf_device->dev, &item->devattr); 1151 device_remove_file(&sony_pf_device->dev, &item->devattr);
1148 } 1152 }
1149 1153
1150 sony_pf_remove(); 1154 sony_pf_remove();
1151 sony_laptop_remove_input(); 1155 sony_laptop_remove_input();
1152 dprintk(SONY_NC_DRIVER_NAME " removed.\n"); 1156 dprintk(SONY_NC_DRIVER_NAME " removed.\n");
1153 1157
1154 return 0; 1158 return 0;
1155 } 1159 }
1156 1160
1157 static const struct acpi_device_id sony_device_ids[] = { 1161 static const struct acpi_device_id sony_device_ids[] = {
1158 {SONY_NC_HID, 0}, 1162 {SONY_NC_HID, 0},
1159 {SONY_PIC_HID, 0}, 1163 {SONY_PIC_HID, 0},
1160 {"", 0}, 1164 {"", 0},
1161 }; 1165 };
1162 MODULE_DEVICE_TABLE(acpi, sony_device_ids); 1166 MODULE_DEVICE_TABLE(acpi, sony_device_ids);
1163 1167
1164 static const struct acpi_device_id sony_nc_device_ids[] = { 1168 static const struct acpi_device_id sony_nc_device_ids[] = {
1165 {SONY_NC_HID, 0}, 1169 {SONY_NC_HID, 0},
1166 {"", 0}, 1170 {"", 0},
1167 }; 1171 };
1168 1172
1169 static struct acpi_driver sony_nc_driver = { 1173 static struct acpi_driver sony_nc_driver = {
1170 .name = SONY_NC_DRIVER_NAME, 1174 .name = SONY_NC_DRIVER_NAME,
1171 .class = SONY_NC_CLASS, 1175 .class = SONY_NC_CLASS,
1172 .ids = sony_nc_device_ids, 1176 .ids = sony_nc_device_ids,
1173 .owner = THIS_MODULE, 1177 .owner = THIS_MODULE,
1174 .ops = { 1178 .ops = {
1175 .add = sony_nc_add, 1179 .add = sony_nc_add,
1176 .remove = sony_nc_remove, 1180 .remove = sony_nc_remove,
1177 .resume = sony_nc_resume, 1181 .resume = sony_nc_resume,
1178 }, 1182 },
1179 }; 1183 };
1180 1184
1181 /*********** SPIC (SNY6001) Device ***********/ 1185 /*********** SPIC (SNY6001) Device ***********/
1182 1186
1183 #define SONYPI_DEVICE_TYPE1 0x00000001 1187 #define SONYPI_DEVICE_TYPE1 0x00000001
1184 #define SONYPI_DEVICE_TYPE2 0x00000002 1188 #define SONYPI_DEVICE_TYPE2 0x00000002
1185 #define SONYPI_DEVICE_TYPE3 0x00000004 1189 #define SONYPI_DEVICE_TYPE3 0x00000004
1186 #define SONYPI_DEVICE_TYPE4 0x00000008 1190 #define SONYPI_DEVICE_TYPE4 0x00000008
1187 1191
1188 #define SONYPI_TYPE1_OFFSET 0x04 1192 #define SONYPI_TYPE1_OFFSET 0x04
1189 #define SONYPI_TYPE2_OFFSET 0x12 1193 #define SONYPI_TYPE2_OFFSET 0x12
1190 #define SONYPI_TYPE3_OFFSET 0x12 1194 #define SONYPI_TYPE3_OFFSET 0x12
1191 #define SONYPI_TYPE4_OFFSET 0x12 1195 #define SONYPI_TYPE4_OFFSET 0x12
1192 1196
1193 struct sony_pic_ioport { 1197 struct sony_pic_ioport {
1194 struct acpi_resource_io io1; 1198 struct acpi_resource_io io1;
1195 struct acpi_resource_io io2; 1199 struct acpi_resource_io io2;
1196 struct list_head list; 1200 struct list_head list;
1197 }; 1201 };
1198 1202
1199 struct sony_pic_irq { 1203 struct sony_pic_irq {
1200 struct acpi_resource_irq irq; 1204 struct acpi_resource_irq irq;
1201 struct list_head list; 1205 struct list_head list;
1202 }; 1206 };
1203 1207
1204 struct sonypi_eventtypes { 1208 struct sonypi_eventtypes {
1205 u8 data; 1209 u8 data;
1206 unsigned long mask; 1210 unsigned long mask;
1207 struct sonypi_event *events; 1211 struct sonypi_event *events;
1208 }; 1212 };
1209 1213
1210 struct device_ctrl { 1214 struct device_ctrl {
1211 int model; 1215 int model;
1212 int (*handle_irq)(const u8, const u8); 1216 int (*handle_irq)(const u8, const u8);
1213 u16 evport_offset; 1217 u16 evport_offset;
1214 u8 has_camera; 1218 u8 has_camera;
1215 u8 has_bluetooth; 1219 u8 has_bluetooth;
1216 u8 has_wwan; 1220 u8 has_wwan;
1217 struct sonypi_eventtypes *event_types; 1221 struct sonypi_eventtypes *event_types;
1218 }; 1222 };
1219 1223
1220 struct sony_pic_dev { 1224 struct sony_pic_dev {
1221 struct device_ctrl *control; 1225 struct device_ctrl *control;
1222 struct acpi_device *acpi_dev; 1226 struct acpi_device *acpi_dev;
1223 struct sony_pic_irq *cur_irq; 1227 struct sony_pic_irq *cur_irq;
1224 struct sony_pic_ioport *cur_ioport; 1228 struct sony_pic_ioport *cur_ioport;
1225 struct list_head interrupts; 1229 struct list_head interrupts;
1226 struct list_head ioports; 1230 struct list_head ioports;
1227 struct mutex lock; 1231 struct mutex lock;
1228 u8 camera_power; 1232 u8 camera_power;
1229 u8 bluetooth_power; 1233 u8 bluetooth_power;
1230 u8 wwan_power; 1234 u8 wwan_power;
1231 }; 1235 };
1232 1236
1233 static struct sony_pic_dev spic_dev = { 1237 static struct sony_pic_dev spic_dev = {
1234 .interrupts = LIST_HEAD_INIT(spic_dev.interrupts), 1238 .interrupts = LIST_HEAD_INIT(spic_dev.interrupts),
1235 .ioports = LIST_HEAD_INIT(spic_dev.ioports), 1239 .ioports = LIST_HEAD_INIT(spic_dev.ioports),
1236 }; 1240 };
1237 1241
1238 /* Event masks */ 1242 /* Event masks */
1239 #define SONYPI_JOGGER_MASK 0x00000001 1243 #define SONYPI_JOGGER_MASK 0x00000001
1240 #define SONYPI_CAPTURE_MASK 0x00000002 1244 #define SONYPI_CAPTURE_MASK 0x00000002
1241 #define SONYPI_FNKEY_MASK 0x00000004 1245 #define SONYPI_FNKEY_MASK 0x00000004
1242 #define SONYPI_BLUETOOTH_MASK 0x00000008 1246 #define SONYPI_BLUETOOTH_MASK 0x00000008
1243 #define SONYPI_PKEY_MASK 0x00000010 1247 #define SONYPI_PKEY_MASK 0x00000010
1244 #define SONYPI_BACK_MASK 0x00000020 1248 #define SONYPI_BACK_MASK 0x00000020
1245 #define SONYPI_HELP_MASK 0x00000040 1249 #define SONYPI_HELP_MASK 0x00000040
1246 #define SONYPI_LID_MASK 0x00000080 1250 #define SONYPI_LID_MASK 0x00000080
1247 #define SONYPI_ZOOM_MASK 0x00000100 1251 #define SONYPI_ZOOM_MASK 0x00000100
1248 #define SONYPI_THUMBPHRASE_MASK 0x00000200 1252 #define SONYPI_THUMBPHRASE_MASK 0x00000200
1249 #define SONYPI_MEYE_MASK 0x00000400 1253 #define SONYPI_MEYE_MASK 0x00000400
1250 #define SONYPI_MEMORYSTICK_MASK 0x00000800 1254 #define SONYPI_MEMORYSTICK_MASK 0x00000800
1251 #define SONYPI_BATTERY_MASK 0x00001000 1255 #define SONYPI_BATTERY_MASK 0x00001000
1252 #define SONYPI_WIRELESS_MASK 0x00002000 1256 #define SONYPI_WIRELESS_MASK 0x00002000
1253 1257
1254 struct sonypi_event { 1258 struct sonypi_event {
1255 u8 data; 1259 u8 data;
1256 u8 event; 1260 u8 event;
1257 }; 1261 };
1258 1262
1259 /* The set of possible button release events */ 1263 /* The set of possible button release events */
1260 static struct sonypi_event sonypi_releaseev[] = { 1264 static struct sonypi_event sonypi_releaseev[] = {
1261 { 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED }, 1265 { 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED },
1262 { 0, 0 } 1266 { 0, 0 }
1263 }; 1267 };
1264 1268
1265 /* The set of possible jogger events */ 1269 /* The set of possible jogger events */
1266 static struct sonypi_event sonypi_joggerev[] = { 1270 static struct sonypi_event sonypi_joggerev[] = {
1267 { 0x1f, SONYPI_EVENT_JOGDIAL_UP }, 1271 { 0x1f, SONYPI_EVENT_JOGDIAL_UP },
1268 { 0x01, SONYPI_EVENT_JOGDIAL_DOWN }, 1272 { 0x01, SONYPI_EVENT_JOGDIAL_DOWN },
1269 { 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED }, 1273 { 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED },
1270 { 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED }, 1274 { 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED },
1271 { 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP }, 1275 { 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP },
1272 { 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN }, 1276 { 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN },
1273 { 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED }, 1277 { 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED },
1274 { 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED }, 1278 { 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED },
1275 { 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP }, 1279 { 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP },
1276 { 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN }, 1280 { 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN },
1277 { 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED }, 1281 { 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED },
1278 { 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED }, 1282 { 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED },
1279 { 0x40, SONYPI_EVENT_JOGDIAL_PRESSED }, 1283 { 0x40, SONYPI_EVENT_JOGDIAL_PRESSED },
1280 { 0, 0 } 1284 { 0, 0 }
1281 }; 1285 };
1282 1286
1283 /* The set of possible capture button events */ 1287 /* The set of possible capture button events */
1284 static struct sonypi_event sonypi_captureev[] = { 1288 static struct sonypi_event sonypi_captureev[] = {
1285 { 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED }, 1289 { 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED },
1286 { 0x07, SONYPI_EVENT_CAPTURE_PRESSED }, 1290 { 0x07, SONYPI_EVENT_CAPTURE_PRESSED },
1287 { 0x40, SONYPI_EVENT_CAPTURE_PRESSED }, 1291 { 0x40, SONYPI_EVENT_CAPTURE_PRESSED },
1288 { 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED }, 1292 { 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED },
1289 { 0, 0 } 1293 { 0, 0 }
1290 }; 1294 };
1291 1295
1292 /* The set of possible fnkeys events */ 1296 /* The set of possible fnkeys events */
1293 static struct sonypi_event sonypi_fnkeyev[] = { 1297 static struct sonypi_event sonypi_fnkeyev[] = {
1294 { 0x10, SONYPI_EVENT_FNKEY_ESC }, 1298 { 0x10, SONYPI_EVENT_FNKEY_ESC },
1295 { 0x11, SONYPI_EVENT_FNKEY_F1 }, 1299 { 0x11, SONYPI_EVENT_FNKEY_F1 },
1296 { 0x12, SONYPI_EVENT_FNKEY_F2 }, 1300 { 0x12, SONYPI_EVENT_FNKEY_F2 },
1297 { 0x13, SONYPI_EVENT_FNKEY_F3 }, 1301 { 0x13, SONYPI_EVENT_FNKEY_F3 },
1298 { 0x14, SONYPI_EVENT_FNKEY_F4 }, 1302 { 0x14, SONYPI_EVENT_FNKEY_F4 },
1299 { 0x15, SONYPI_EVENT_FNKEY_F5 }, 1303 { 0x15, SONYPI_EVENT_FNKEY_F5 },
1300 { 0x16, SONYPI_EVENT_FNKEY_F6 }, 1304 { 0x16, SONYPI_EVENT_FNKEY_F6 },
1301 { 0x17, SONYPI_EVENT_FNKEY_F7 }, 1305 { 0x17, SONYPI_EVENT_FNKEY_F7 },
1302 { 0x18, SONYPI_EVENT_FNKEY_F8 }, 1306 { 0x18, SONYPI_EVENT_FNKEY_F8 },
1303 { 0x19, SONYPI_EVENT_FNKEY_F9 }, 1307 { 0x19, SONYPI_EVENT_FNKEY_F9 },
1304 { 0x1a, SONYPI_EVENT_FNKEY_F10 }, 1308 { 0x1a, SONYPI_EVENT_FNKEY_F10 },
1305 { 0x1b, SONYPI_EVENT_FNKEY_F11 }, 1309 { 0x1b, SONYPI_EVENT_FNKEY_F11 },
1306 { 0x1c, SONYPI_EVENT_FNKEY_F12 }, 1310 { 0x1c, SONYPI_EVENT_FNKEY_F12 },
1307 { 0x1f, SONYPI_EVENT_FNKEY_RELEASED }, 1311 { 0x1f, SONYPI_EVENT_FNKEY_RELEASED },
1308 { 0x21, SONYPI_EVENT_FNKEY_1 }, 1312 { 0x21, SONYPI_EVENT_FNKEY_1 },
1309 { 0x22, SONYPI_EVENT_FNKEY_2 }, 1313 { 0x22, SONYPI_EVENT_FNKEY_2 },
1310 { 0x31, SONYPI_EVENT_FNKEY_D }, 1314 { 0x31, SONYPI_EVENT_FNKEY_D },
1311 { 0x32, SONYPI_EVENT_FNKEY_E }, 1315 { 0x32, SONYPI_EVENT_FNKEY_E },
1312 { 0x33, SONYPI_EVENT_FNKEY_F }, 1316 { 0x33, SONYPI_EVENT_FNKEY_F },
1313 { 0x34, SONYPI_EVENT_FNKEY_S }, 1317 { 0x34, SONYPI_EVENT_FNKEY_S },
1314 { 0x35, SONYPI_EVENT_FNKEY_B }, 1318 { 0x35, SONYPI_EVENT_FNKEY_B },
1315 { 0x36, SONYPI_EVENT_FNKEY_ONLY }, 1319 { 0x36, SONYPI_EVENT_FNKEY_ONLY },
1316 { 0, 0 } 1320 { 0, 0 }
1317 }; 1321 };
1318 1322
1319 /* The set of possible program key events */ 1323 /* The set of possible program key events */
1320 static struct sonypi_event sonypi_pkeyev[] = { 1324 static struct sonypi_event sonypi_pkeyev[] = {
1321 { 0x01, SONYPI_EVENT_PKEY_P1 }, 1325 { 0x01, SONYPI_EVENT_PKEY_P1 },
1322 { 0x02, SONYPI_EVENT_PKEY_P2 }, 1326 { 0x02, SONYPI_EVENT_PKEY_P2 },
1323 { 0x04, SONYPI_EVENT_PKEY_P3 }, 1327 { 0x04, SONYPI_EVENT_PKEY_P3 },
1324 { 0, 0 } 1328 { 0, 0 }
1325 }; 1329 };
1326 1330
1327 /* The set of possible bluetooth events */ 1331 /* The set of possible bluetooth events */
1328 static struct sonypi_event sonypi_blueev[] = { 1332 static struct sonypi_event sonypi_blueev[] = {
1329 { 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED }, 1333 { 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED },
1330 { 0x59, SONYPI_EVENT_BLUETOOTH_ON }, 1334 { 0x59, SONYPI_EVENT_BLUETOOTH_ON },
1331 { 0x5a, SONYPI_EVENT_BLUETOOTH_OFF }, 1335 { 0x5a, SONYPI_EVENT_BLUETOOTH_OFF },
1332 { 0, 0 } 1336 { 0, 0 }
1333 }; 1337 };
1334 1338
1335 /* The set of possible wireless events */ 1339 /* The set of possible wireless events */
1336 static struct sonypi_event sonypi_wlessev[] = { 1340 static struct sonypi_event sonypi_wlessev[] = {
1337 { 0x59, SONYPI_EVENT_WIRELESS_ON }, 1341 { 0x59, SONYPI_EVENT_WIRELESS_ON },
1338 { 0x5a, SONYPI_EVENT_WIRELESS_OFF }, 1342 { 0x5a, SONYPI_EVENT_WIRELESS_OFF },
1339 { 0, 0 } 1343 { 0, 0 }
1340 }; 1344 };
1341 1345
1342 /* The set of possible back button events */ 1346 /* The set of possible back button events */
1343 static struct sonypi_event sonypi_backev[] = { 1347 static struct sonypi_event sonypi_backev[] = {
1344 { 0x20, SONYPI_EVENT_BACK_PRESSED }, 1348 { 0x20, SONYPI_EVENT_BACK_PRESSED },
1345 { 0, 0 } 1349 { 0, 0 }
1346 }; 1350 };
1347 1351
1348 /* The set of possible help button events */ 1352 /* The set of possible help button events */
1349 static struct sonypi_event sonypi_helpev[] = { 1353 static struct sonypi_event sonypi_helpev[] = {
1350 { 0x3b, SONYPI_EVENT_HELP_PRESSED }, 1354 { 0x3b, SONYPI_EVENT_HELP_PRESSED },
1351 { 0, 0 } 1355 { 0, 0 }
1352 }; 1356 };
1353 1357
1354 1358
1355 /* The set of possible lid events */ 1359 /* The set of possible lid events */
1356 static struct sonypi_event sonypi_lidev[] = { 1360 static struct sonypi_event sonypi_lidev[] = {
1357 { 0x51, SONYPI_EVENT_LID_CLOSED }, 1361 { 0x51, SONYPI_EVENT_LID_CLOSED },
1358 { 0x50, SONYPI_EVENT_LID_OPENED }, 1362 { 0x50, SONYPI_EVENT_LID_OPENED },
1359 { 0, 0 } 1363 { 0, 0 }
1360 }; 1364 };
1361 1365
1362 /* The set of possible zoom events */ 1366 /* The set of possible zoom events */
1363 static struct sonypi_event sonypi_zoomev[] = { 1367 static struct sonypi_event sonypi_zoomev[] = {
1364 { 0x39, SONYPI_EVENT_ZOOM_PRESSED }, 1368 { 0x39, SONYPI_EVENT_ZOOM_PRESSED },
1365 { 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED }, 1369 { 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED },
1366 { 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED }, 1370 { 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED },
1367 { 0, 0 } 1371 { 0, 0 }
1368 }; 1372 };
1369 1373
1370 /* The set of possible thumbphrase events */ 1374 /* The set of possible thumbphrase events */
1371 static struct sonypi_event sonypi_thumbphraseev[] = { 1375 static struct sonypi_event sonypi_thumbphraseev[] = {
1372 { 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED }, 1376 { 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED },
1373 { 0, 0 } 1377 { 0, 0 }
1374 }; 1378 };
1375 1379
1376 /* The set of possible motioneye camera events */ 1380 /* The set of possible motioneye camera events */
1377 static struct sonypi_event sonypi_meyeev[] = { 1381 static struct sonypi_event sonypi_meyeev[] = {
1378 { 0x00, SONYPI_EVENT_MEYE_FACE }, 1382 { 0x00, SONYPI_EVENT_MEYE_FACE },
1379 { 0x01, SONYPI_EVENT_MEYE_OPPOSITE }, 1383 { 0x01, SONYPI_EVENT_MEYE_OPPOSITE },
1380 { 0, 0 } 1384 { 0, 0 }
1381 }; 1385 };
1382 1386
1383 /* The set of possible memorystick events */ 1387 /* The set of possible memorystick events */
1384 static struct sonypi_event sonypi_memorystickev[] = { 1388 static struct sonypi_event sonypi_memorystickev[] = {
1385 { 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT }, 1389 { 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT },
1386 { 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT }, 1390 { 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT },
1387 { 0, 0 } 1391 { 0, 0 }
1388 }; 1392 };
1389 1393
1390 /* The set of possible battery events */ 1394 /* The set of possible battery events */
1391 static struct sonypi_event sonypi_batteryev[] = { 1395 static struct sonypi_event sonypi_batteryev[] = {
1392 { 0x20, SONYPI_EVENT_BATTERY_INSERT }, 1396 { 0x20, SONYPI_EVENT_BATTERY_INSERT },
1393 { 0x30, SONYPI_EVENT_BATTERY_REMOVE }, 1397 { 0x30, SONYPI_EVENT_BATTERY_REMOVE },
1394 { 0, 0 } 1398 { 0, 0 }
1395 }; 1399 };
1396 1400
1397 static struct sonypi_eventtypes type1_events[] = { 1401 static struct sonypi_eventtypes type1_events[] = {
1398 { 0, 0xffffffff, sonypi_releaseev }, 1402 { 0, 0xffffffff, sonypi_releaseev },
1399 { 0x70, SONYPI_MEYE_MASK, sonypi_meyeev }, 1403 { 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
1400 { 0x30, SONYPI_LID_MASK, sonypi_lidev }, 1404 { 0x30, SONYPI_LID_MASK, sonypi_lidev },
1401 { 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev }, 1405 { 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
1402 { 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev }, 1406 { 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
1403 { 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 1407 { 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
1404 { 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, 1408 { 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
1405 { 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev }, 1409 { 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
1406 { 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 1410 { 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
1407 { 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev }, 1411 { 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
1408 { 0 }, 1412 { 0 },
1409 }; 1413 };
1410 static struct sonypi_eventtypes type2_events[] = { 1414 static struct sonypi_eventtypes type2_events[] = {
1411 { 0, 0xffffffff, sonypi_releaseev }, 1415 { 0, 0xffffffff, sonypi_releaseev },
1412 { 0x38, SONYPI_LID_MASK, sonypi_lidev }, 1416 { 0x38, SONYPI_LID_MASK, sonypi_lidev },
1413 { 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev }, 1417 { 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
1414 { 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev }, 1418 { 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
1415 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 1419 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
1416 { 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev }, 1420 { 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
1417 { 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev }, 1421 { 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
1418 { 0x11, SONYPI_BACK_MASK, sonypi_backev }, 1422 { 0x11, SONYPI_BACK_MASK, sonypi_backev },
1419 { 0x21, SONYPI_HELP_MASK, sonypi_helpev }, 1423 { 0x21, SONYPI_HELP_MASK, sonypi_helpev },
1420 { 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev }, 1424 { 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
1421 { 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev }, 1425 { 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
1422 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 1426 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
1423 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, 1427 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
1424 { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, 1428 { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
1425 { 0 }, 1429 { 0 },
1426 }; 1430 };
1427 static struct sonypi_eventtypes type3_events[] = { 1431 static struct sonypi_eventtypes type3_events[] = {
1428 { 0, 0xffffffff, sonypi_releaseev }, 1432 { 0, 0xffffffff, sonypi_releaseev },
1429 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 1433 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
1430 { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev }, 1434 { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
1431 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 1435 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
1432 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, 1436 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
1433 { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, 1437 { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
1434 { 0 }, 1438 { 0 },
1435 }; 1439 };
1436 static struct sonypi_eventtypes type4_events[] = { 1440 static struct sonypi_eventtypes type4_events[] = {
1437 { 0, 0xffffffff, sonypi_releaseev }, 1441 { 0, 0xffffffff, sonypi_releaseev },
1438 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, 1442 { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
1439 { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev }, 1443 { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
1440 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, 1444 { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
1441 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, 1445 { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
1442 { 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev }, 1446 { 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev },
1443 { 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev }, 1447 { 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev },
1444 { 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev }, 1448 { 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev },
1445 { 0 }, 1449 { 0 },
1446 }; 1450 };
1447 1451
1448 /* low level spic calls */ 1452 /* low level spic calls */
1449 #define ITERATIONS_LONG 10000 1453 #define ITERATIONS_LONG 10000
1450 #define ITERATIONS_SHORT 10 1454 #define ITERATIONS_SHORT 10
1451 #define wait_on_command(command, iterations) { \ 1455 #define wait_on_command(command, iterations) { \
1452 unsigned int n = iterations; \ 1456 unsigned int n = iterations; \
1453 while (--n && (command)) \ 1457 while (--n && (command)) \
1454 udelay(1); \ 1458 udelay(1); \
1455 if (!n) \ 1459 if (!n) \
1456 dprintk("command failed at %s : %s (line %d)\n", \ 1460 dprintk("command failed at %s : %s (line %d)\n", \
1457 __FILE__, __func__, __LINE__); \ 1461 __FILE__, __func__, __LINE__); \
1458 } 1462 }
1459 1463
1460 static u8 sony_pic_call1(u8 dev) 1464 static u8 sony_pic_call1(u8 dev)
1461 { 1465 {
1462 u8 v1, v2; 1466 u8 v1, v2;
1463 1467
1464 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, 1468 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
1465 ITERATIONS_LONG); 1469 ITERATIONS_LONG);
1466 outb(dev, spic_dev.cur_ioport->io1.minimum + 4); 1470 outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
1467 v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4); 1471 v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4);
1468 v2 = inb_p(spic_dev.cur_ioport->io1.minimum); 1472 v2 = inb_p(spic_dev.cur_ioport->io1.minimum);
1469 dprintk("sony_pic_call1(0x%.2x): 0x%.4x\n", dev, (v2 << 8) | v1); 1473 dprintk("sony_pic_call1(0x%.2x): 0x%.4x\n", dev, (v2 << 8) | v1);
1470 return v2; 1474 return v2;
1471 } 1475 }
1472 1476
1473 static u8 sony_pic_call2(u8 dev, u8 fn) 1477 static u8 sony_pic_call2(u8 dev, u8 fn)
1474 { 1478 {
1475 u8 v1; 1479 u8 v1;
1476 1480
1477 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, 1481 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
1478 ITERATIONS_LONG); 1482 ITERATIONS_LONG);
1479 outb(dev, spic_dev.cur_ioport->io1.minimum + 4); 1483 outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
1480 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, 1484 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
1481 ITERATIONS_LONG); 1485 ITERATIONS_LONG);
1482 outb(fn, spic_dev.cur_ioport->io1.minimum); 1486 outb(fn, spic_dev.cur_ioport->io1.minimum);
1483 v1 = inb_p(spic_dev.cur_ioport->io1.minimum); 1487 v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
1484 dprintk("sony_pic_call2(0x%.2x - 0x%.2x): 0x%.4x\n", dev, fn, v1); 1488 dprintk("sony_pic_call2(0x%.2x - 0x%.2x): 0x%.4x\n", dev, fn, v1);
1485 return v1; 1489 return v1;
1486 } 1490 }
1487 1491
1488 static u8 sony_pic_call3(u8 dev, u8 fn, u8 v) 1492 static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
1489 { 1493 {
1490 u8 v1; 1494 u8 v1;
1491 1495
1492 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); 1496 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
1493 outb(dev, spic_dev.cur_ioport->io1.minimum + 4); 1497 outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
1494 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); 1498 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
1495 outb(fn, spic_dev.cur_ioport->io1.minimum); 1499 outb(fn, spic_dev.cur_ioport->io1.minimum);
1496 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); 1500 wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
1497 outb(v, spic_dev.cur_ioport->io1.minimum); 1501 outb(v, spic_dev.cur_ioport->io1.minimum);
1498 v1 = inb_p(spic_dev.cur_ioport->io1.minimum); 1502 v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
1499 dprintk("sony_pic_call3(0x%.2x - 0x%.2x - 0x%.2x): 0x%.4x\n", 1503 dprintk("sony_pic_call3(0x%.2x - 0x%.2x - 0x%.2x): 0x%.4x\n",
1500 dev, fn, v, v1); 1504 dev, fn, v, v1);
1501 return v1; 1505 return v1;
1502 } 1506 }
1503 1507
1504 /* 1508 /*
1505 * minidrivers for SPIC models 1509 * minidrivers for SPIC models
1506 */ 1510 */
1507 static int type4_handle_irq(const u8 data_mask, const u8 ev) 1511 static int type4_handle_irq(const u8 data_mask, const u8 ev)
1508 { 1512 {
1509 /* 1513 /*
1510 * 0x31 could mean we have to take some extra action and wait for 1514 * 0x31 could mean we have to take some extra action and wait for
1511 * the next irq for some Type4 models, it will generate a new 1515 * the next irq for some Type4 models, it will generate a new
1512 * irq and we can read new data from the device: 1516 * irq and we can read new data from the device:
1513 * - 0x5c and 0x5f requires 0xA0 1517 * - 0x5c and 0x5f requires 0xA0
1514 * - 0x61 requires 0xB3 1518 * - 0x61 requires 0xB3
1515 */ 1519 */
1516 if (data_mask == 0x31) { 1520 if (data_mask == 0x31) {
1517 if (ev == 0x5c || ev == 0x5f) 1521 if (ev == 0x5c || ev == 0x5f)
1518 sony_pic_call1(0xA0); 1522 sony_pic_call1(0xA0);
1519 else if (ev == 0x61) 1523 else if (ev == 0x61)
1520 sony_pic_call1(0xB3); 1524 sony_pic_call1(0xB3);
1521 return 0; 1525 return 0;
1522 } 1526 }
1523 return 1; 1527 return 1;
1524 } 1528 }
1525 1529
1526 static struct device_ctrl spic_types[] = { 1530 static struct device_ctrl spic_types[] = {
1527 { 1531 {
1528 .model = SONYPI_DEVICE_TYPE1, 1532 .model = SONYPI_DEVICE_TYPE1,
1529 .handle_irq = NULL, 1533 .handle_irq = NULL,
1530 .evport_offset = SONYPI_TYPE1_OFFSET, 1534 .evport_offset = SONYPI_TYPE1_OFFSET,
1531 .event_types = type1_events, 1535 .event_types = type1_events,
1532 }, 1536 },
1533 { 1537 {
1534 .model = SONYPI_DEVICE_TYPE2, 1538 .model = SONYPI_DEVICE_TYPE2,
1535 .handle_irq = NULL, 1539 .handle_irq = NULL,
1536 .evport_offset = SONYPI_TYPE2_OFFSET, 1540 .evport_offset = SONYPI_TYPE2_OFFSET,
1537 .event_types = type2_events, 1541 .event_types = type2_events,
1538 }, 1542 },
1539 { 1543 {
1540 .model = SONYPI_DEVICE_TYPE3, 1544 .model = SONYPI_DEVICE_TYPE3,
1541 .handle_irq = NULL, 1545 .handle_irq = NULL,
1542 .evport_offset = SONYPI_TYPE3_OFFSET, 1546 .evport_offset = SONYPI_TYPE3_OFFSET,
1543 .event_types = type3_events, 1547 .event_types = type3_events,
1544 }, 1548 },
1545 { 1549 {
1546 .model = SONYPI_DEVICE_TYPE4, 1550 .model = SONYPI_DEVICE_TYPE4,
1547 .handle_irq = type4_handle_irq, 1551 .handle_irq = type4_handle_irq,
1548 .evport_offset = SONYPI_TYPE4_OFFSET, 1552 .evport_offset = SONYPI_TYPE4_OFFSET,
1549 .event_types = type4_events, 1553 .event_types = type4_events,
1550 }, 1554 },
1551 }; 1555 };
1552 1556
1553 static void sony_pic_detect_device_type(struct sony_pic_dev *dev) 1557 static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
1554 { 1558 {
1555 struct pci_dev *pcidev; 1559 struct pci_dev *pcidev;
1556 1560
1557 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1561 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1558 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 1562 PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
1559 if (pcidev) { 1563 if (pcidev) {
1560 dev->control = &spic_types[0]; 1564 dev->control = &spic_types[0];
1561 goto out; 1565 goto out;
1562 } 1566 }
1563 1567
1564 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1568 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1565 PCI_DEVICE_ID_INTEL_ICH6_1, NULL); 1569 PCI_DEVICE_ID_INTEL_ICH6_1, NULL);
1566 if (pcidev) { 1570 if (pcidev) {
1567 dev->control = &spic_types[2]; 1571 dev->control = &spic_types[2];
1568 goto out; 1572 goto out;
1569 } 1573 }
1570 1574
1571 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1575 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1572 PCI_DEVICE_ID_INTEL_ICH7_1, NULL); 1576 PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
1573 if (pcidev) { 1577 if (pcidev) {
1574 dev->control = &spic_types[3]; 1578 dev->control = &spic_types[3];
1575 goto out; 1579 goto out;
1576 } 1580 }
1577 1581
1578 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1582 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1579 PCI_DEVICE_ID_INTEL_ICH8_4, NULL); 1583 PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
1580 if (pcidev) { 1584 if (pcidev) {
1581 dev->control = &spic_types[3]; 1585 dev->control = &spic_types[3];
1582 goto out; 1586 goto out;
1583 } 1587 }
1584 1588
1585 /* default */ 1589 /* default */
1586 dev->control = &spic_types[1]; 1590 dev->control = &spic_types[1];
1587 1591
1588 out: 1592 out:
1589 if (pcidev) 1593 if (pcidev)
1590 pci_dev_put(pcidev); 1594 pci_dev_put(pcidev);
1591 1595
1592 printk(KERN_INFO DRV_PFX "detected Type%d model\n", 1596 printk(KERN_INFO DRV_PFX "detected Type%d model\n",
1593 dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 : 1597 dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
1594 dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 1598 dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 :
1595 dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4); 1599 dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4);
1596 } 1600 }
1597 1601
1598 /* camera tests and poweron/poweroff */ 1602 /* camera tests and poweron/poweroff */
1599 #define SONYPI_CAMERA_PICTURE 5 1603 #define SONYPI_CAMERA_PICTURE 5
1600 #define SONYPI_CAMERA_CONTROL 0x10 1604 #define SONYPI_CAMERA_CONTROL 0x10
1601 1605
1602 #define SONYPI_CAMERA_BRIGHTNESS 0 1606 #define SONYPI_CAMERA_BRIGHTNESS 0
1603 #define SONYPI_CAMERA_CONTRAST 1 1607 #define SONYPI_CAMERA_CONTRAST 1
1604 #define SONYPI_CAMERA_HUE 2 1608 #define SONYPI_CAMERA_HUE 2
1605 #define SONYPI_CAMERA_COLOR 3 1609 #define SONYPI_CAMERA_COLOR 3
1606 #define SONYPI_CAMERA_SHARPNESS 4 1610 #define SONYPI_CAMERA_SHARPNESS 4
1607 1611
1608 #define SONYPI_CAMERA_EXPOSURE_MASK 0xC 1612 #define SONYPI_CAMERA_EXPOSURE_MASK 0xC
1609 #define SONYPI_CAMERA_WHITE_BALANCE_MASK 0x3 1613 #define SONYPI_CAMERA_WHITE_BALANCE_MASK 0x3
1610 #define SONYPI_CAMERA_PICTURE_MODE_MASK 0x30 1614 #define SONYPI_CAMERA_PICTURE_MODE_MASK 0x30
1611 #define SONYPI_CAMERA_MUTE_MASK 0x40 1615 #define SONYPI_CAMERA_MUTE_MASK 0x40
1612 1616
1613 /* the rest don't need a loop until not 0xff */ 1617 /* the rest don't need a loop until not 0xff */
1614 #define SONYPI_CAMERA_AGC 6 1618 #define SONYPI_CAMERA_AGC 6
1615 #define SONYPI_CAMERA_AGC_MASK 0x30 1619 #define SONYPI_CAMERA_AGC_MASK 0x30
1616 #define SONYPI_CAMERA_SHUTTER_MASK 0x7 1620 #define SONYPI_CAMERA_SHUTTER_MASK 0x7
1617 1621
1618 #define SONYPI_CAMERA_SHUTDOWN_REQUEST 7 1622 #define SONYPI_CAMERA_SHUTDOWN_REQUEST 7
1619 #define SONYPI_CAMERA_CONTROL 0x10 1623 #define SONYPI_CAMERA_CONTROL 0x10
1620 1624
1621 #define SONYPI_CAMERA_STATUS 7 1625 #define SONYPI_CAMERA_STATUS 7
1622 #define SONYPI_CAMERA_STATUS_READY 0x2 1626 #define SONYPI_CAMERA_STATUS_READY 0x2
1623 #define SONYPI_CAMERA_STATUS_POSITION 0x4 1627 #define SONYPI_CAMERA_STATUS_POSITION 0x4
1624 1628
1625 #define SONYPI_DIRECTION_BACKWARDS 0x4 1629 #define SONYPI_DIRECTION_BACKWARDS 0x4
1626 1630
1627 #define SONYPI_CAMERA_REVISION 8 1631 #define SONYPI_CAMERA_REVISION 8
1628 #define SONYPI_CAMERA_ROMVERSION 9 1632 #define SONYPI_CAMERA_ROMVERSION 9
1629 1633
1630 static int __sony_pic_camera_ready(void) 1634 static int __sony_pic_camera_ready(void)
1631 { 1635 {
1632 u8 v; 1636 u8 v;
1633 1637
1634 v = sony_pic_call2(0x8f, SONYPI_CAMERA_STATUS); 1638 v = sony_pic_call2(0x8f, SONYPI_CAMERA_STATUS);
1635 return (v != 0xff && (v & SONYPI_CAMERA_STATUS_READY)); 1639 return (v != 0xff && (v & SONYPI_CAMERA_STATUS_READY));
1636 } 1640 }
1637 1641
1638 static int __sony_pic_camera_off(void) 1642 static int __sony_pic_camera_off(void)
1639 { 1643 {
1640 if (!camera) { 1644 if (!camera) {
1641 printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); 1645 printk(KERN_WARNING DRV_PFX "camera control not enabled\n");
1642 return -ENODEV; 1646 return -ENODEV;
1643 } 1647 }
1644 1648
1645 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, 1649 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE,
1646 SONYPI_CAMERA_MUTE_MASK), 1650 SONYPI_CAMERA_MUTE_MASK),
1647 ITERATIONS_SHORT); 1651 ITERATIONS_SHORT);
1648 1652
1649 if (spic_dev.camera_power) { 1653 if (spic_dev.camera_power) {
1650 sony_pic_call2(0x91, 0); 1654 sony_pic_call2(0x91, 0);
1651 spic_dev.camera_power = 0; 1655 spic_dev.camera_power = 0;
1652 } 1656 }
1653 return 0; 1657 return 0;
1654 } 1658 }
1655 1659
1656 static int __sony_pic_camera_on(void) 1660 static int __sony_pic_camera_on(void)
1657 { 1661 {
1658 int i, j, x; 1662 int i, j, x;
1659 1663
1660 if (!camera) { 1664 if (!camera) {
1661 printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); 1665 printk(KERN_WARNING DRV_PFX "camera control not enabled\n");
1662 return -ENODEV; 1666 return -ENODEV;
1663 } 1667 }
1664 1668
1665 if (spic_dev.camera_power) 1669 if (spic_dev.camera_power)
1666 return 0; 1670 return 0;
1667 1671
1668 for (j = 5; j > 0; j--) { 1672 for (j = 5; j > 0; j--) {
1669 1673
1670 for (x = 0; x < 100 && sony_pic_call2(0x91, 0x1); x++) 1674 for (x = 0; x < 100 && sony_pic_call2(0x91, 0x1); x++)
1671 msleep(10); 1675 msleep(10);
1672 sony_pic_call1(0x93); 1676 sony_pic_call1(0x93);
1673 1677
1674 for (i = 400; i > 0; i--) { 1678 for (i = 400; i > 0; i--) {
1675 if (__sony_pic_camera_ready()) 1679 if (__sony_pic_camera_ready())
1676 break; 1680 break;
1677 msleep(10); 1681 msleep(10);
1678 } 1682 }
1679 if (i) 1683 if (i)
1680 break; 1684 break;
1681 } 1685 }
1682 1686
1683 if (j == 0) { 1687 if (j == 0) {
1684 printk(KERN_WARNING DRV_PFX "failed to power on camera\n"); 1688 printk(KERN_WARNING DRV_PFX "failed to power on camera\n");
1685 return -ENODEV; 1689 return -ENODEV;
1686 } 1690 }
1687 1691
1688 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTROL, 1692 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTROL,
1689 0x5a), 1693 0x5a),
1690 ITERATIONS_SHORT); 1694 ITERATIONS_SHORT);
1691 1695
1692 spic_dev.camera_power = 1; 1696 spic_dev.camera_power = 1;
1693 return 0; 1697 return 0;
1694 } 1698 }
1695 1699
1696 /* External camera command (exported to the motion eye v4l driver) */ 1700 /* External camera command (exported to the motion eye v4l driver) */
1697 int sony_pic_camera_command(int command, u8 value) 1701 int sony_pic_camera_command(int command, u8 value)
1698 { 1702 {
1699 if (!camera) 1703 if (!camera)
1700 return -EIO; 1704 return -EIO;
1701 1705
1702 mutex_lock(&spic_dev.lock); 1706 mutex_lock(&spic_dev.lock);
1703 1707
1704 switch (command) { 1708 switch (command) {
1705 case SONY_PIC_COMMAND_SETCAMERA: 1709 case SONY_PIC_COMMAND_SETCAMERA:
1706 if (value) 1710 if (value)
1707 __sony_pic_camera_on(); 1711 __sony_pic_camera_on();
1708 else 1712 else
1709 __sony_pic_camera_off(); 1713 __sony_pic_camera_off();
1710 break; 1714 break;
1711 case SONY_PIC_COMMAND_SETCAMERABRIGHTNESS: 1715 case SONY_PIC_COMMAND_SETCAMERABRIGHTNESS:
1712 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_BRIGHTNESS, value), 1716 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_BRIGHTNESS, value),
1713 ITERATIONS_SHORT); 1717 ITERATIONS_SHORT);
1714 break; 1718 break;
1715 case SONY_PIC_COMMAND_SETCAMERACONTRAST: 1719 case SONY_PIC_COMMAND_SETCAMERACONTRAST:
1716 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTRAST, value), 1720 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTRAST, value),
1717 ITERATIONS_SHORT); 1721 ITERATIONS_SHORT);
1718 break; 1722 break;
1719 case SONY_PIC_COMMAND_SETCAMERAHUE: 1723 case SONY_PIC_COMMAND_SETCAMERAHUE:
1720 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_HUE, value), 1724 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_HUE, value),
1721 ITERATIONS_SHORT); 1725 ITERATIONS_SHORT);
1722 break; 1726 break;
1723 case SONY_PIC_COMMAND_SETCAMERACOLOR: 1727 case SONY_PIC_COMMAND_SETCAMERACOLOR:
1724 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_COLOR, value), 1728 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_COLOR, value),
1725 ITERATIONS_SHORT); 1729 ITERATIONS_SHORT);
1726 break; 1730 break;
1727 case SONY_PIC_COMMAND_SETCAMERASHARPNESS: 1731 case SONY_PIC_COMMAND_SETCAMERASHARPNESS:
1728 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_SHARPNESS, value), 1732 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_SHARPNESS, value),
1729 ITERATIONS_SHORT); 1733 ITERATIONS_SHORT);
1730 break; 1734 break;
1731 case SONY_PIC_COMMAND_SETCAMERAPICTURE: 1735 case SONY_PIC_COMMAND_SETCAMERAPICTURE:
1732 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, value), 1736 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, value),
1733 ITERATIONS_SHORT); 1737 ITERATIONS_SHORT);
1734 break; 1738 break;
1735 case SONY_PIC_COMMAND_SETCAMERAAGC: 1739 case SONY_PIC_COMMAND_SETCAMERAAGC:
1736 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_AGC, value), 1740 wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_AGC, value),
1737 ITERATIONS_SHORT); 1741 ITERATIONS_SHORT);
1738 break; 1742 break;
1739 default: 1743 default:
1740 printk(KERN_ERR DRV_PFX "sony_pic_camera_command invalid: %d\n", 1744 printk(KERN_ERR DRV_PFX "sony_pic_camera_command invalid: %d\n",
1741 command); 1745 command);
1742 break; 1746 break;
1743 } 1747 }
1744 mutex_unlock(&spic_dev.lock); 1748 mutex_unlock(&spic_dev.lock);
1745 return 0; 1749 return 0;
1746 } 1750 }
1747 EXPORT_SYMBOL(sony_pic_camera_command); 1751 EXPORT_SYMBOL(sony_pic_camera_command);
1748 1752
1749 /* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */ 1753 /* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */
1750 static void sony_pic_set_wwanpower(u8 state) 1754 static void sony_pic_set_wwanpower(u8 state)
1751 { 1755 {
1752 state = !!state; 1756 state = !!state;
1753 mutex_lock(&spic_dev.lock); 1757 mutex_lock(&spic_dev.lock);
1754 if (spic_dev.wwan_power == state) { 1758 if (spic_dev.wwan_power == state) {
1755 mutex_unlock(&spic_dev.lock); 1759 mutex_unlock(&spic_dev.lock);
1756 return; 1760 return;
1757 } 1761 }
1758 sony_pic_call2(0xB0, state); 1762 sony_pic_call2(0xB0, state);
1759 spic_dev.wwan_power = state; 1763 spic_dev.wwan_power = state;
1760 mutex_unlock(&spic_dev.lock); 1764 mutex_unlock(&spic_dev.lock);
1761 } 1765 }
1762 1766
1763 static ssize_t sony_pic_wwanpower_store(struct device *dev, 1767 static ssize_t sony_pic_wwanpower_store(struct device *dev,
1764 struct device_attribute *attr, 1768 struct device_attribute *attr,
1765 const char *buffer, size_t count) 1769 const char *buffer, size_t count)
1766 { 1770 {
1767 unsigned long value; 1771 unsigned long value;
1768 if (count > 31) 1772 if (count > 31)
1769 return -EINVAL; 1773 return -EINVAL;
1770 1774
1771 value = simple_strtoul(buffer, NULL, 10); 1775 value = simple_strtoul(buffer, NULL, 10);
1772 sony_pic_set_wwanpower(value); 1776 sony_pic_set_wwanpower(value);
1773 1777
1774 return count; 1778 return count;
1775 } 1779 }
1776 1780
1777 static ssize_t sony_pic_wwanpower_show(struct device *dev, 1781 static ssize_t sony_pic_wwanpower_show(struct device *dev,
1778 struct device_attribute *attr, char *buffer) 1782 struct device_attribute *attr, char *buffer)
1779 { 1783 {
1780 ssize_t count; 1784 ssize_t count;
1781 mutex_lock(&spic_dev.lock); 1785 mutex_lock(&spic_dev.lock);
1782 count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.wwan_power); 1786 count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.wwan_power);
1783 mutex_unlock(&spic_dev.lock); 1787 mutex_unlock(&spic_dev.lock);
1784 return count; 1788 return count;
1785 } 1789 }
1786 1790
1787 /* bluetooth subsystem power state */ 1791 /* bluetooth subsystem power state */
1788 static void __sony_pic_set_bluetoothpower(u8 state) 1792 static void __sony_pic_set_bluetoothpower(u8 state)
1789 { 1793 {
1790 state = !!state; 1794 state = !!state;
1791 if (spic_dev.bluetooth_power == state) 1795 if (spic_dev.bluetooth_power == state)
1792 return; 1796 return;
1793 sony_pic_call2(0x96, state); 1797 sony_pic_call2(0x96, state);
1794 sony_pic_call1(0x82); 1798 sony_pic_call1(0x82);
1795 spic_dev.bluetooth_power = state; 1799 spic_dev.bluetooth_power = state;
1796 } 1800 }
1797 1801
1798 static ssize_t sony_pic_bluetoothpower_store(struct device *dev, 1802 static ssize_t sony_pic_bluetoothpower_store(struct device *dev,
1799 struct device_attribute *attr, 1803 struct device_attribute *attr,
1800 const char *buffer, size_t count) 1804 const char *buffer, size_t count)
1801 { 1805 {
1802 unsigned long value; 1806 unsigned long value;
1803 if (count > 31) 1807 if (count > 31)
1804 return -EINVAL; 1808 return -EINVAL;
1805 1809
1806 value = simple_strtoul(buffer, NULL, 10); 1810 value = simple_strtoul(buffer, NULL, 10);
1807 mutex_lock(&spic_dev.lock); 1811 mutex_lock(&spic_dev.lock);
1808 __sony_pic_set_bluetoothpower(value); 1812 __sony_pic_set_bluetoothpower(value);
1809 mutex_unlock(&spic_dev.lock); 1813 mutex_unlock(&spic_dev.lock);
1810 1814
1811 return count; 1815 return count;
1812 } 1816 }
1813 1817
1814 static ssize_t sony_pic_bluetoothpower_show(struct device *dev, 1818 static ssize_t sony_pic_bluetoothpower_show(struct device *dev,
1815 struct device_attribute *attr, char *buffer) 1819 struct device_attribute *attr, char *buffer)
1816 { 1820 {
1817 ssize_t count = 0; 1821 ssize_t count = 0;
1818 mutex_lock(&spic_dev.lock); 1822 mutex_lock(&spic_dev.lock);
1819 count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.bluetooth_power); 1823 count = snprintf(buffer, PAGE_SIZE, "%d\n", spic_dev.bluetooth_power);
1820 mutex_unlock(&spic_dev.lock); 1824 mutex_unlock(&spic_dev.lock);
1821 return count; 1825 return count;
1822 } 1826 }
1823 1827
1824 /* fan speed */ 1828 /* fan speed */
1825 /* FAN0 information (reverse engineered from ACPI tables) */ 1829 /* FAN0 information (reverse engineered from ACPI tables) */
1826 #define SONY_PIC_FAN0_STATUS 0x93 1830 #define SONY_PIC_FAN0_STATUS 0x93
1827 static int sony_pic_set_fanspeed(unsigned long value) 1831 static int sony_pic_set_fanspeed(unsigned long value)
1828 { 1832 {
1829 return ec_write(SONY_PIC_FAN0_STATUS, value); 1833 return ec_write(SONY_PIC_FAN0_STATUS, value);
1830 } 1834 }
1831 1835
1832 static int sony_pic_get_fanspeed(u8 *value) 1836 static int sony_pic_get_fanspeed(u8 *value)
1833 { 1837 {
1834 return ec_read(SONY_PIC_FAN0_STATUS, value); 1838 return ec_read(SONY_PIC_FAN0_STATUS, value);
1835 } 1839 }
1836 1840
1837 static ssize_t sony_pic_fanspeed_store(struct device *dev, 1841 static ssize_t sony_pic_fanspeed_store(struct device *dev,
1838 struct device_attribute *attr, 1842 struct device_attribute *attr,
1839 const char *buffer, size_t count) 1843 const char *buffer, size_t count)
1840 { 1844 {
1841 unsigned long value; 1845 unsigned long value;
1842 if (count > 31) 1846 if (count > 31)
1843 return -EINVAL; 1847 return -EINVAL;
1844 1848
1845 value = simple_strtoul(buffer, NULL, 10); 1849 value = simple_strtoul(buffer, NULL, 10);
1846 if (sony_pic_set_fanspeed(value)) 1850 if (sony_pic_set_fanspeed(value))
1847 return -EIO; 1851 return -EIO;
1848 1852
1849 return count; 1853 return count;
1850 } 1854 }
1851 1855
1852 static ssize_t sony_pic_fanspeed_show(struct device *dev, 1856 static ssize_t sony_pic_fanspeed_show(struct device *dev,
1853 struct device_attribute *attr, char *buffer) 1857 struct device_attribute *attr, char *buffer)
1854 { 1858 {
1855 u8 value = 0; 1859 u8 value = 0;
1856 if (sony_pic_get_fanspeed(&value)) 1860 if (sony_pic_get_fanspeed(&value))
1857 return -EIO; 1861 return -EIO;
1858 1862
1859 return snprintf(buffer, PAGE_SIZE, "%d\n", value); 1863 return snprintf(buffer, PAGE_SIZE, "%d\n", value);
1860 } 1864 }
1861 1865
1862 #define SPIC_ATTR(_name, _mode) \ 1866 #define SPIC_ATTR(_name, _mode) \
1863 struct device_attribute spic_attr_##_name = __ATTR(_name, \ 1867 struct device_attribute spic_attr_##_name = __ATTR(_name, \
1864 _mode, sony_pic_## _name ##_show, \ 1868 _mode, sony_pic_## _name ##_show, \
1865 sony_pic_## _name ##_store) 1869 sony_pic_## _name ##_store)
1866 1870
1867 static SPIC_ATTR(bluetoothpower, 0644); 1871 static SPIC_ATTR(bluetoothpower, 0644);
1868 static SPIC_ATTR(wwanpower, 0644); 1872 static SPIC_ATTR(wwanpower, 0644);
1869 static SPIC_ATTR(fanspeed, 0644); 1873 static SPIC_ATTR(fanspeed, 0644);
1870 1874
1871 static struct attribute *spic_attributes[] = { 1875 static struct attribute *spic_attributes[] = {
1872 &spic_attr_bluetoothpower.attr, 1876 &spic_attr_bluetoothpower.attr,
1873 &spic_attr_wwanpower.attr, 1877 &spic_attr_wwanpower.attr,
1874 &spic_attr_fanspeed.attr, 1878 &spic_attr_fanspeed.attr,
1875 NULL 1879 NULL
1876 }; 1880 };
1877 1881
1878 static struct attribute_group spic_attribute_group = { 1882 static struct attribute_group spic_attribute_group = {
1879 .attrs = spic_attributes 1883 .attrs = spic_attributes
1880 }; 1884 };
1881 1885
1882 /******** SONYPI compatibility **********/ 1886 /******** SONYPI compatibility **********/
1883 #ifdef CONFIG_SONYPI_COMPAT 1887 #ifdef CONFIG_SONYPI_COMPAT
1884 1888
1885 /* battery / brightness / temperature addresses */ 1889 /* battery / brightness / temperature addresses */
1886 #define SONYPI_BAT_FLAGS 0x81 1890 #define SONYPI_BAT_FLAGS 0x81
1887 #define SONYPI_LCD_LIGHT 0x96 1891 #define SONYPI_LCD_LIGHT 0x96
1888 #define SONYPI_BAT1_PCTRM 0xa0 1892 #define SONYPI_BAT1_PCTRM 0xa0
1889 #define SONYPI_BAT1_LEFT 0xa2 1893 #define SONYPI_BAT1_LEFT 0xa2
1890 #define SONYPI_BAT1_MAXRT 0xa4 1894 #define SONYPI_BAT1_MAXRT 0xa4
1891 #define SONYPI_BAT2_PCTRM 0xa8 1895 #define SONYPI_BAT2_PCTRM 0xa8
1892 #define SONYPI_BAT2_LEFT 0xaa 1896 #define SONYPI_BAT2_LEFT 0xaa
1893 #define SONYPI_BAT2_MAXRT 0xac 1897 #define SONYPI_BAT2_MAXRT 0xac
1894 #define SONYPI_BAT1_MAXTK 0xb0 1898 #define SONYPI_BAT1_MAXTK 0xb0
1895 #define SONYPI_BAT1_FULL 0xb2 1899 #define SONYPI_BAT1_FULL 0xb2
1896 #define SONYPI_BAT2_MAXTK 0xb8 1900 #define SONYPI_BAT2_MAXTK 0xb8
1897 #define SONYPI_BAT2_FULL 0xba 1901 #define SONYPI_BAT2_FULL 0xba
1898 #define SONYPI_TEMP_STATUS 0xC1 1902 #define SONYPI_TEMP_STATUS 0xC1
1899 1903
1900 struct sonypi_compat_s { 1904 struct sonypi_compat_s {
1901 struct fasync_struct *fifo_async; 1905 struct fasync_struct *fifo_async;
1902 struct kfifo *fifo; 1906 struct kfifo *fifo;
1903 spinlock_t fifo_lock; 1907 spinlock_t fifo_lock;
1904 wait_queue_head_t fifo_proc_list; 1908 wait_queue_head_t fifo_proc_list;
1905 atomic_t open_count; 1909 atomic_t open_count;
1906 }; 1910 };
1907 static struct sonypi_compat_s sonypi_compat = { 1911 static struct sonypi_compat_s sonypi_compat = {
1908 .open_count = ATOMIC_INIT(0), 1912 .open_count = ATOMIC_INIT(0),
1909 }; 1913 };
1910 1914
1911 static int sonypi_misc_fasync(int fd, struct file *filp, int on) 1915 static int sonypi_misc_fasync(int fd, struct file *filp, int on)
1912 { 1916 {
1913 int retval; 1917 int retval;
1914 1918
1915 retval = fasync_helper(fd, filp, on, &sonypi_compat.fifo_async); 1919 retval = fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
1916 if (retval < 0) 1920 if (retval < 0)
1917 return retval; 1921 return retval;
1918 return 0; 1922 return 0;
1919 } 1923 }
1920 1924
1921 static int sonypi_misc_release(struct inode *inode, struct file *file) 1925 static int sonypi_misc_release(struct inode *inode, struct file *file)
1922 { 1926 {
1923 atomic_dec(&sonypi_compat.open_count); 1927 atomic_dec(&sonypi_compat.open_count);
1924 return 0; 1928 return 0;
1925 } 1929 }
1926 1930
1927 static int sonypi_misc_open(struct inode *inode, struct file *file) 1931 static int sonypi_misc_open(struct inode *inode, struct file *file)
1928 { 1932 {
1929 /* Flush input queue on first open */ 1933 /* Flush input queue on first open */
1930 lock_kernel(); 1934 lock_kernel();
1931 if (atomic_inc_return(&sonypi_compat.open_count) == 1) 1935 if (atomic_inc_return(&sonypi_compat.open_count) == 1)
1932 kfifo_reset(sonypi_compat.fifo); 1936 kfifo_reset(sonypi_compat.fifo);
1933 unlock_kernel(); 1937 unlock_kernel();
1934 return 0; 1938 return 0;
1935 } 1939 }
1936 1940
1937 static ssize_t sonypi_misc_read(struct file *file, char __user *buf, 1941 static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
1938 size_t count, loff_t *pos) 1942 size_t count, loff_t *pos)
1939 { 1943 {
1940 ssize_t ret; 1944 ssize_t ret;
1941 unsigned char c; 1945 unsigned char c;
1942 1946
1943 if ((kfifo_len(sonypi_compat.fifo) == 0) && 1947 if ((kfifo_len(sonypi_compat.fifo) == 0) &&
1944 (file->f_flags & O_NONBLOCK)) 1948 (file->f_flags & O_NONBLOCK))
1945 return -EAGAIN; 1949 return -EAGAIN;
1946 1950
1947 ret = wait_event_interruptible(sonypi_compat.fifo_proc_list, 1951 ret = wait_event_interruptible(sonypi_compat.fifo_proc_list,
1948 kfifo_len(sonypi_compat.fifo) != 0); 1952 kfifo_len(sonypi_compat.fifo) != 0);
1949 if (ret) 1953 if (ret)
1950 return ret; 1954 return ret;
1951 1955
1952 while (ret < count && 1956 while (ret < count &&
1953 (kfifo_get(sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) { 1957 (kfifo_get(sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) {
1954 if (put_user(c, buf++)) 1958 if (put_user(c, buf++))
1955 return -EFAULT; 1959 return -EFAULT;
1956 ret++; 1960 ret++;
1957 } 1961 }
1958 1962
1959 if (ret > 0) { 1963 if (ret > 0) {
1960 struct inode *inode = file->f_path.dentry->d_inode; 1964 struct inode *inode = file->f_path.dentry->d_inode;
1961 inode->i_atime = current_fs_time(inode->i_sb); 1965 inode->i_atime = current_fs_time(inode->i_sb);
1962 } 1966 }
1963 1967
1964 return ret; 1968 return ret;
1965 } 1969 }
1966 1970
1967 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) 1971 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait)
1968 { 1972 {
1969 poll_wait(file, &sonypi_compat.fifo_proc_list, wait); 1973 poll_wait(file, &sonypi_compat.fifo_proc_list, wait);
1970 if (kfifo_len(sonypi_compat.fifo)) 1974 if (kfifo_len(sonypi_compat.fifo))
1971 return POLLIN | POLLRDNORM; 1975 return POLLIN | POLLRDNORM;
1972 return 0; 1976 return 0;
1973 } 1977 }
1974 1978
1975 static int ec_read16(u8 addr, u16 *value) 1979 static int ec_read16(u8 addr, u16 *value)
1976 { 1980 {
1977 u8 val_lb, val_hb; 1981 u8 val_lb, val_hb;
1978 if (ec_read(addr, &val_lb)) 1982 if (ec_read(addr, &val_lb))
1979 return -1; 1983 return -1;
1980 if (ec_read(addr + 1, &val_hb)) 1984 if (ec_read(addr + 1, &val_hb))
1981 return -1; 1985 return -1;
1982 *value = val_lb | (val_hb << 8); 1986 *value = val_lb | (val_hb << 8);
1983 return 0; 1987 return 0;
1984 } 1988 }
1985 1989
1986 static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, 1990 static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
1987 unsigned int cmd, unsigned long arg) 1991 unsigned int cmd, unsigned long arg)
1988 { 1992 {
1989 int ret = 0; 1993 int ret = 0;
1990 void __user *argp = (void __user *)arg; 1994 void __user *argp = (void __user *)arg;
1991 u8 val8; 1995 u8 val8;
1992 u16 val16; 1996 u16 val16;
1993 int value; 1997 int value;
1994 1998
1995 mutex_lock(&spic_dev.lock); 1999 mutex_lock(&spic_dev.lock);
1996 switch (cmd) { 2000 switch (cmd) {
1997 case SONYPI_IOCGBRT: 2001 case SONYPI_IOCGBRT:
1998 if (sony_backlight_device == NULL) { 2002 if (sony_backlight_device == NULL) {
1999 ret = -EIO; 2003 ret = -EIO;
2000 break; 2004 break;
2001 } 2005 }
2002 if (acpi_callgetfunc(sony_nc_acpi_handle, "GBRT", &value)) { 2006 if (acpi_callgetfunc(sony_nc_acpi_handle, "GBRT", &value)) {
2003 ret = -EIO; 2007 ret = -EIO;
2004 break; 2008 break;
2005 } 2009 }
2006 val8 = ((value & 0xff) - 1) << 5; 2010 val8 = ((value & 0xff) - 1) << 5;
2007 if (copy_to_user(argp, &val8, sizeof(val8))) 2011 if (copy_to_user(argp, &val8, sizeof(val8)))
2008 ret = -EFAULT; 2012 ret = -EFAULT;
2009 break; 2013 break;
2010 case SONYPI_IOCSBRT: 2014 case SONYPI_IOCSBRT:
2011 if (sony_backlight_device == NULL) { 2015 if (sony_backlight_device == NULL) {
2012 ret = -EIO; 2016 ret = -EIO;
2013 break; 2017 break;
2014 } 2018 }
2015 if (copy_from_user(&val8, argp, sizeof(val8))) { 2019 if (copy_from_user(&val8, argp, sizeof(val8))) {
2016 ret = -EFAULT; 2020 ret = -EFAULT;
2017 break; 2021 break;
2018 } 2022 }
2019 if (acpi_callsetfunc(sony_nc_acpi_handle, "SBRT", 2023 if (acpi_callsetfunc(sony_nc_acpi_handle, "SBRT",
2020 (val8 >> 5) + 1, NULL)) { 2024 (val8 >> 5) + 1, NULL)) {
2021 ret = -EIO; 2025 ret = -EIO;
2022 break; 2026 break;
2023 } 2027 }
2024 /* sync the backlight device status */ 2028 /* sync the backlight device status */
2025 sony_backlight_device->props.brightness = 2029 sony_backlight_device->props.brightness =
2026 sony_backlight_get_brightness(sony_backlight_device); 2030 sony_backlight_get_brightness(sony_backlight_device);
2027 break; 2031 break;
2028 case SONYPI_IOCGBAT1CAP: 2032 case SONYPI_IOCGBAT1CAP:
2029 if (ec_read16(SONYPI_BAT1_FULL, &val16)) { 2033 if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
2030 ret = -EIO; 2034 ret = -EIO;
2031 break; 2035 break;
2032 } 2036 }
2033 if (copy_to_user(argp, &val16, sizeof(val16))) 2037 if (copy_to_user(argp, &val16, sizeof(val16)))
2034 ret = -EFAULT; 2038 ret = -EFAULT;
2035 break; 2039 break;
2036 case SONYPI_IOCGBAT1REM: 2040 case SONYPI_IOCGBAT1REM:
2037 if (ec_read16(SONYPI_BAT1_LEFT, &val16)) { 2041 if (ec_read16(SONYPI_BAT1_LEFT, &val16)) {
2038 ret = -EIO; 2042 ret = -EIO;
2039 break; 2043 break;
2040 } 2044 }
2041 if (copy_to_user(argp, &val16, sizeof(val16))) 2045 if (copy_to_user(argp, &val16, sizeof(val16)))
2042 ret = -EFAULT; 2046 ret = -EFAULT;
2043 break; 2047 break;
2044 case SONYPI_IOCGBAT2CAP: 2048 case SONYPI_IOCGBAT2CAP:
2045 if (ec_read16(SONYPI_BAT2_FULL, &val16)) { 2049 if (ec_read16(SONYPI_BAT2_FULL, &val16)) {
2046 ret = -EIO; 2050 ret = -EIO;
2047 break; 2051 break;
2048 } 2052 }
2049 if (copy_to_user(argp, &val16, sizeof(val16))) 2053 if (copy_to_user(argp, &val16, sizeof(val16)))
2050 ret = -EFAULT; 2054 ret = -EFAULT;
2051 break; 2055 break;
2052 case SONYPI_IOCGBAT2REM: 2056 case SONYPI_IOCGBAT2REM:
2053 if (ec_read16(SONYPI_BAT2_LEFT, &val16)) { 2057 if (ec_read16(SONYPI_BAT2_LEFT, &val16)) {
2054 ret = -EIO; 2058 ret = -EIO;
2055 break; 2059 break;
2056 } 2060 }
2057 if (copy_to_user(argp, &val16, sizeof(val16))) 2061 if (copy_to_user(argp, &val16, sizeof(val16)))
2058 ret = -EFAULT; 2062 ret = -EFAULT;
2059 break; 2063 break;
2060 case SONYPI_IOCGBATFLAGS: 2064 case SONYPI_IOCGBATFLAGS:
2061 if (ec_read(SONYPI_BAT_FLAGS, &val8)) { 2065 if (ec_read(SONYPI_BAT_FLAGS, &val8)) {
2062 ret = -EIO; 2066 ret = -EIO;
2063 break; 2067 break;
2064 } 2068 }
2065 val8 &= 0x07; 2069 val8 &= 0x07;
2066 if (copy_to_user(argp, &val8, sizeof(val8))) 2070 if (copy_to_user(argp, &val8, sizeof(val8)))
2067 ret = -EFAULT; 2071 ret = -EFAULT;
2068 break; 2072 break;
2069 case SONYPI_IOCGBLUE: 2073 case SONYPI_IOCGBLUE:
2070 val8 = spic_dev.bluetooth_power; 2074 val8 = spic_dev.bluetooth_power;
2071 if (copy_to_user(argp, &val8, sizeof(val8))) 2075 if (copy_to_user(argp, &val8, sizeof(val8)))
2072 ret = -EFAULT; 2076 ret = -EFAULT;
2073 break; 2077 break;
2074 case SONYPI_IOCSBLUE: 2078 case SONYPI_IOCSBLUE:
2075 if (copy_from_user(&val8, argp, sizeof(val8))) { 2079 if (copy_from_user(&val8, argp, sizeof(val8))) {
2076 ret = -EFAULT; 2080 ret = -EFAULT;
2077 break; 2081 break;
2078 } 2082 }
2079 __sony_pic_set_bluetoothpower(val8); 2083 __sony_pic_set_bluetoothpower(val8);
2080 break; 2084 break;
2081 /* FAN Controls */ 2085 /* FAN Controls */
2082 case SONYPI_IOCGFAN: 2086 case SONYPI_IOCGFAN:
2083 if (sony_pic_get_fanspeed(&val8)) { 2087 if (sony_pic_get_fanspeed(&val8)) {
2084 ret = -EIO; 2088 ret = -EIO;
2085 break; 2089 break;
2086 } 2090 }
2087 if (copy_to_user(argp, &val8, sizeof(val8))) 2091 if (copy_to_user(argp, &val8, sizeof(val8)))
2088 ret = -EFAULT; 2092 ret = -EFAULT;
2089 break; 2093 break;
2090 case SONYPI_IOCSFAN: 2094 case SONYPI_IOCSFAN:
2091 if (copy_from_user(&val8, argp, sizeof(val8))) { 2095 if (copy_from_user(&val8, argp, sizeof(val8))) {
2092 ret = -EFAULT; 2096 ret = -EFAULT;
2093 break; 2097 break;
2094 } 2098 }
2095 if (sony_pic_set_fanspeed(val8)) 2099 if (sony_pic_set_fanspeed(val8))
2096 ret = -EIO; 2100 ret = -EIO;
2097 break; 2101 break;
2098 /* GET Temperature (useful under APM) */ 2102 /* GET Temperature (useful under APM) */
2099 case SONYPI_IOCGTEMP: 2103 case SONYPI_IOCGTEMP:
2100 if (ec_read(SONYPI_TEMP_STATUS, &val8)) { 2104 if (ec_read(SONYPI_TEMP_STATUS, &val8)) {
2101 ret = -EIO; 2105 ret = -EIO;
2102 break; 2106 break;
2103 } 2107 }
2104 if (copy_to_user(argp, &val8, sizeof(val8))) 2108 if (copy_to_user(argp, &val8, sizeof(val8)))
2105 ret = -EFAULT; 2109 ret = -EFAULT;
2106 break; 2110 break;
2107 default: 2111 default:
2108 ret = -EINVAL; 2112 ret = -EINVAL;
2109 } 2113 }
2110 mutex_unlock(&spic_dev.lock); 2114 mutex_unlock(&spic_dev.lock);
2111 return ret; 2115 return ret;
2112 } 2116 }
2113 2117
2114 static const struct file_operations sonypi_misc_fops = { 2118 static const struct file_operations sonypi_misc_fops = {
2115 .owner = THIS_MODULE, 2119 .owner = THIS_MODULE,
2116 .read = sonypi_misc_read, 2120 .read = sonypi_misc_read,
2117 .poll = sonypi_misc_poll, 2121 .poll = sonypi_misc_poll,
2118 .open = sonypi_misc_open, 2122 .open = sonypi_misc_open,
2119 .release = sonypi_misc_release, 2123 .release = sonypi_misc_release,
2120 .fasync = sonypi_misc_fasync, 2124 .fasync = sonypi_misc_fasync,
2121 .ioctl = sonypi_misc_ioctl, 2125 .ioctl = sonypi_misc_ioctl,
2122 }; 2126 };
2123 2127
2124 static struct miscdevice sonypi_misc_device = { 2128 static struct miscdevice sonypi_misc_device = {
2125 .minor = MISC_DYNAMIC_MINOR, 2129 .minor = MISC_DYNAMIC_MINOR,
2126 .name = "sonypi", 2130 .name = "sonypi",
2127 .fops = &sonypi_misc_fops, 2131 .fops = &sonypi_misc_fops,
2128 }; 2132 };
2129 2133
2130 static void sonypi_compat_report_event(u8 event) 2134 static void sonypi_compat_report_event(u8 event)
2131 { 2135 {
2132 kfifo_put(sonypi_compat.fifo, (unsigned char *)&event, sizeof(event)); 2136 kfifo_put(sonypi_compat.fifo, (unsigned char *)&event, sizeof(event));
2133 kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN); 2137 kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN);
2134 wake_up_interruptible(&sonypi_compat.fifo_proc_list); 2138 wake_up_interruptible(&sonypi_compat.fifo_proc_list);
2135 } 2139 }
2136 2140
2137 static int sonypi_compat_init(void) 2141 static int sonypi_compat_init(void)
2138 { 2142 {
2139 int error; 2143 int error;
2140 2144
2141 spin_lock_init(&sonypi_compat.fifo_lock); 2145 spin_lock_init(&sonypi_compat.fifo_lock);
2142 sonypi_compat.fifo = kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL, 2146 sonypi_compat.fifo = kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
2143 &sonypi_compat.fifo_lock); 2147 &sonypi_compat.fifo_lock);
2144 if (IS_ERR(sonypi_compat.fifo)) { 2148 if (IS_ERR(sonypi_compat.fifo)) {
2145 printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); 2149 printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
2146 return PTR_ERR(sonypi_compat.fifo); 2150 return PTR_ERR(sonypi_compat.fifo);
2147 } 2151 }
2148 2152
2149 init_waitqueue_head(&sonypi_compat.fifo_proc_list); 2153 init_waitqueue_head(&sonypi_compat.fifo_proc_list);
2150 2154
2151 if (minor != -1) 2155 if (minor != -1)
2152 sonypi_misc_device.minor = minor; 2156 sonypi_misc_device.minor = minor;
2153 error = misc_register(&sonypi_misc_device); 2157 error = misc_register(&sonypi_misc_device);
2154 if (error) { 2158 if (error) {
2155 printk(KERN_ERR DRV_PFX "misc_register failed\n"); 2159 printk(KERN_ERR DRV_PFX "misc_register failed\n");
2156 goto err_free_kfifo; 2160 goto err_free_kfifo;
2157 } 2161 }
2158 if (minor == -1) 2162 if (minor == -1)
2159 printk(KERN_INFO DRV_PFX "device allocated minor is %d\n", 2163 printk(KERN_INFO DRV_PFX "device allocated minor is %d\n",
2160 sonypi_misc_device.minor); 2164 sonypi_misc_device.minor);
2161 2165
2162 return 0; 2166 return 0;
2163 2167
2164 err_free_kfifo: 2168 err_free_kfifo:
2165 kfifo_free(sonypi_compat.fifo); 2169 kfifo_free(sonypi_compat.fifo);
2166 return error; 2170 return error;
2167 } 2171 }
2168 2172
2169 static void sonypi_compat_exit(void) 2173 static void sonypi_compat_exit(void)
2170 { 2174 {
2171 misc_deregister(&sonypi_misc_device); 2175 misc_deregister(&sonypi_misc_device);
2172 kfifo_free(sonypi_compat.fifo); 2176 kfifo_free(sonypi_compat.fifo);
2173 } 2177 }
2174 #else 2178 #else
2175 static int sonypi_compat_init(void) { return 0; } 2179 static int sonypi_compat_init(void) { return 0; }
2176 static void sonypi_compat_exit(void) { } 2180 static void sonypi_compat_exit(void) { }
2177 static void sonypi_compat_report_event(u8 event) { } 2181 static void sonypi_compat_report_event(u8 event) { }
2178 #endif /* CONFIG_SONYPI_COMPAT */ 2182 #endif /* CONFIG_SONYPI_COMPAT */
2179 2183
2180 /* 2184 /*
2181 * ACPI callbacks 2185 * ACPI callbacks
2182 */ 2186 */
2183 static acpi_status 2187 static acpi_status
2184 sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) 2188 sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
2185 { 2189 {
2186 u32 i; 2190 u32 i;
2187 struct sony_pic_dev *dev = (struct sony_pic_dev *)context; 2191 struct sony_pic_dev *dev = (struct sony_pic_dev *)context;
2188 2192
2189 switch (resource->type) { 2193 switch (resource->type) {
2190 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 2194 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
2191 { 2195 {
2192 /* start IO enumeration */ 2196 /* start IO enumeration */
2193 struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); 2197 struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL);
2194 if (!ioport) 2198 if (!ioport)
2195 return AE_ERROR; 2199 return AE_ERROR;
2196 2200
2197 list_add(&ioport->list, &dev->ioports); 2201 list_add(&ioport->list, &dev->ioports);
2198 return AE_OK; 2202 return AE_OK;
2199 } 2203 }
2200 2204
2201 case ACPI_RESOURCE_TYPE_END_DEPENDENT: 2205 case ACPI_RESOURCE_TYPE_END_DEPENDENT:
2202 /* end IO enumeration */ 2206 /* end IO enumeration */
2203 return AE_OK; 2207 return AE_OK;
2204 2208
2205 case ACPI_RESOURCE_TYPE_IRQ: 2209 case ACPI_RESOURCE_TYPE_IRQ:
2206 { 2210 {
2207 struct acpi_resource_irq *p = &resource->data.irq; 2211 struct acpi_resource_irq *p = &resource->data.irq;
2208 struct sony_pic_irq *interrupt = NULL; 2212 struct sony_pic_irq *interrupt = NULL;
2209 if (!p || !p->interrupt_count) { 2213 if (!p || !p->interrupt_count) {
2210 /* 2214 /*
2211 * IRQ descriptors may have no IRQ# bits set, 2215 * IRQ descriptors may have no IRQ# bits set,
2212 * particularly those those w/ _STA disabled 2216 * particularly those those w/ _STA disabled
2213 */ 2217 */
2214 dprintk("Blank IRQ resource\n"); 2218 dprintk("Blank IRQ resource\n");
2215 return AE_OK; 2219 return AE_OK;
2216 } 2220 }
2217 for (i = 0; i < p->interrupt_count; i++) { 2221 for (i = 0; i < p->interrupt_count; i++) {
2218 if (!p->interrupts[i]) { 2222 if (!p->interrupts[i]) {
2219 printk(KERN_WARNING DRV_PFX 2223 printk(KERN_WARNING DRV_PFX
2220 "Invalid IRQ %d\n", 2224 "Invalid IRQ %d\n",
2221 p->interrupts[i]); 2225 p->interrupts[i]);
2222 continue; 2226 continue;
2223 } 2227 }
2224 interrupt = kzalloc(sizeof(*interrupt), 2228 interrupt = kzalloc(sizeof(*interrupt),
2225 GFP_KERNEL); 2229 GFP_KERNEL);
2226 if (!interrupt) 2230 if (!interrupt)
2227 return AE_ERROR; 2231 return AE_ERROR;
2228 2232
2229 list_add(&interrupt->list, &dev->interrupts); 2233 list_add(&interrupt->list, &dev->interrupts);
2230 interrupt->irq.triggering = p->triggering; 2234 interrupt->irq.triggering = p->triggering;
2231 interrupt->irq.polarity = p->polarity; 2235 interrupt->irq.polarity = p->polarity;
2232 interrupt->irq.sharable = p->sharable; 2236 interrupt->irq.sharable = p->sharable;
2233 interrupt->irq.interrupt_count = 1; 2237 interrupt->irq.interrupt_count = 1;
2234 interrupt->irq.interrupts[0] = p->interrupts[i]; 2238 interrupt->irq.interrupts[0] = p->interrupts[i];
2235 } 2239 }
2236 return AE_OK; 2240 return AE_OK;
2237 } 2241 }
2238 case ACPI_RESOURCE_TYPE_IO: 2242 case ACPI_RESOURCE_TYPE_IO:
2239 { 2243 {
2240 struct acpi_resource_io *io = &resource->data.io; 2244 struct acpi_resource_io *io = &resource->data.io;
2241 struct sony_pic_ioport *ioport = 2245 struct sony_pic_ioport *ioport =
2242 list_first_entry(&dev->ioports, struct sony_pic_ioport, list); 2246 list_first_entry(&dev->ioports, struct sony_pic_ioport, list);
2243 if (!io) { 2247 if (!io) {
2244 dprintk("Blank IO resource\n"); 2248 dprintk("Blank IO resource\n");
2245 return AE_OK; 2249 return AE_OK;
2246 } 2250 }
2247 2251
2248 if (!ioport->io1.minimum) { 2252 if (!ioport->io1.minimum) {
2249 memcpy(&ioport->io1, io, sizeof(*io)); 2253 memcpy(&ioport->io1, io, sizeof(*io));
2250 dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum, 2254 dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum,
2251 ioport->io1.address_length); 2255 ioport->io1.address_length);
2252 } 2256 }
2253 else if (!ioport->io2.minimum) { 2257 else if (!ioport->io2.minimum) {
2254 memcpy(&ioport->io2, io, sizeof(*io)); 2258 memcpy(&ioport->io2, io, sizeof(*io));
2255 dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum, 2259 dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum,
2256 ioport->io2.address_length); 2260 ioport->io2.address_length);
2257 } 2261 }
2258 else { 2262 else {
2259 printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n"); 2263 printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
2260 return AE_ERROR; 2264 return AE_ERROR;
2261 } 2265 }
2262 return AE_OK; 2266 return AE_OK;
2263 } 2267 }
2264 default: 2268 default:
2265 dprintk("Resource %d isn't an IRQ nor an IO port\n", 2269 dprintk("Resource %d isn't an IRQ nor an IO port\n",
2266 resource->type); 2270 resource->type);
2267 2271
2268 case ACPI_RESOURCE_TYPE_END_TAG: 2272 case ACPI_RESOURCE_TYPE_END_TAG:
2269 return AE_OK; 2273 return AE_OK;
2270 } 2274 }
2271 return AE_CTRL_TERMINATE; 2275 return AE_CTRL_TERMINATE;
2272 } 2276 }
2273 2277
2274 static int sony_pic_possible_resources(struct acpi_device *device) 2278 static int sony_pic_possible_resources(struct acpi_device *device)
2275 { 2279 {
2276 int result = 0; 2280 int result = 0;
2277 acpi_status status = AE_OK; 2281 acpi_status status = AE_OK;
2278 2282
2279 if (!device) 2283 if (!device)
2280 return -EINVAL; 2284 return -EINVAL;
2281 2285
2282 /* get device status */ 2286 /* get device status */
2283 /* see acpi_pci_link_get_current acpi_pci_link_get_possible */ 2287 /* see acpi_pci_link_get_current acpi_pci_link_get_possible */
2284 dprintk("Evaluating _STA\n"); 2288 dprintk("Evaluating _STA\n");
2285 result = acpi_bus_get_status(device); 2289 result = acpi_bus_get_status(device);
2286 if (result) { 2290 if (result) {
2287 printk(KERN_WARNING DRV_PFX "Unable to read status\n"); 2291 printk(KERN_WARNING DRV_PFX "Unable to read status\n");
2288 goto end; 2292 goto end;
2289 } 2293 }
2290 2294
2291 if (!device->status.enabled) 2295 if (!device->status.enabled)
2292 dprintk("Device disabled\n"); 2296 dprintk("Device disabled\n");
2293 else 2297 else
2294 dprintk("Device enabled\n"); 2298 dprintk("Device enabled\n");
2295 2299
2296 /* 2300 /*
2297 * Query and parse 'method' 2301 * Query and parse 'method'
2298 */ 2302 */
2299 dprintk("Evaluating %s\n", METHOD_NAME__PRS); 2303 dprintk("Evaluating %s\n", METHOD_NAME__PRS);
2300 status = acpi_walk_resources(device->handle, METHOD_NAME__PRS, 2304 status = acpi_walk_resources(device->handle, METHOD_NAME__PRS,
2301 sony_pic_read_possible_resource, &spic_dev); 2305 sony_pic_read_possible_resource, &spic_dev);
2302 if (ACPI_FAILURE(status)) { 2306 if (ACPI_FAILURE(status)) {
2303 printk(KERN_WARNING DRV_PFX 2307 printk(KERN_WARNING DRV_PFX
2304 "Failure evaluating %s\n", 2308 "Failure evaluating %s\n",
2305 METHOD_NAME__PRS); 2309 METHOD_NAME__PRS);
2306 result = -ENODEV; 2310 result = -ENODEV;
2307 } 2311 }
2308 end: 2312 end:
2309 return result; 2313 return result;
2310 } 2314 }
2311 2315
2312 /* 2316 /*
2313 * Disable the spic device by calling its _DIS method 2317 * Disable the spic device by calling its _DIS method
2314 */ 2318 */
2315 static int sony_pic_disable(struct acpi_device *device) 2319 static int sony_pic_disable(struct acpi_device *device)
2316 { 2320 {
2317 acpi_status ret = acpi_evaluate_object(device->handle, "_DIS", NULL, 2321 acpi_status ret = acpi_evaluate_object(device->handle, "_DIS", NULL,
2318 NULL); 2322 NULL);
2319 2323
2320 if (ACPI_FAILURE(ret) && ret != AE_NOT_FOUND) 2324 if (ACPI_FAILURE(ret) && ret != AE_NOT_FOUND)
2321 return -ENXIO; 2325 return -ENXIO;
2322 2326
2323 dprintk("Device disabled\n"); 2327 dprintk("Device disabled\n");
2324 return 0; 2328 return 0;
2325 } 2329 }
2326 2330
2327 2331
2328 /* 2332 /*
2329 * Based on drivers/acpi/pci_link.c:acpi_pci_link_set 2333 * Based on drivers/acpi/pci_link.c:acpi_pci_link_set
2330 * 2334 *
2331 * Call _SRS to set current resources 2335 * Call _SRS to set current resources
2332 */ 2336 */
2333 static int sony_pic_enable(struct acpi_device *device, 2337 static int sony_pic_enable(struct acpi_device *device,
2334 struct sony_pic_ioport *ioport, struct sony_pic_irq *irq) 2338 struct sony_pic_ioport *ioport, struct sony_pic_irq *irq)
2335 { 2339 {
2336 acpi_status status; 2340 acpi_status status;
2337 int result = 0; 2341 int result = 0;
2338 /* Type 1 resource layout is: 2342 /* Type 1 resource layout is:
2339 * IO 2343 * IO
2340 * IO 2344 * IO
2341 * IRQNoFlags 2345 * IRQNoFlags
2342 * End 2346 * End
2343 * 2347 *
2344 * Type 2 and 3 resource layout is: 2348 * Type 2 and 3 resource layout is:
2345 * IO 2349 * IO
2346 * IRQNoFlags 2350 * IRQNoFlags
2347 * End 2351 * End
2348 */ 2352 */
2349 struct { 2353 struct {
2350 struct acpi_resource res1; 2354 struct acpi_resource res1;
2351 struct acpi_resource res2; 2355 struct acpi_resource res2;
2352 struct acpi_resource res3; 2356 struct acpi_resource res3;
2353 struct acpi_resource res4; 2357 struct acpi_resource res4;
2354 } *resource; 2358 } *resource;
2355 struct acpi_buffer buffer = { 0, NULL }; 2359 struct acpi_buffer buffer = { 0, NULL };
2356 2360
2357 if (!ioport || !irq) 2361 if (!ioport || !irq)
2358 return -EINVAL; 2362 return -EINVAL;
2359 2363
2360 /* init acpi_buffer */ 2364 /* init acpi_buffer */
2361 resource = kzalloc(sizeof(*resource) + 1, GFP_KERNEL); 2365 resource = kzalloc(sizeof(*resource) + 1, GFP_KERNEL);
2362 if (!resource) 2366 if (!resource)
2363 return -ENOMEM; 2367 return -ENOMEM;
2364 2368
2365 buffer.length = sizeof(*resource) + 1; 2369 buffer.length = sizeof(*resource) + 1;
2366 buffer.pointer = resource; 2370 buffer.pointer = resource;
2367 2371
2368 /* setup Type 1 resources */ 2372 /* setup Type 1 resources */
2369 if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) { 2373 if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) {
2370 2374
2371 /* setup io resources */ 2375 /* setup io resources */
2372 resource->res1.type = ACPI_RESOURCE_TYPE_IO; 2376 resource->res1.type = ACPI_RESOURCE_TYPE_IO;
2373 resource->res1.length = sizeof(struct acpi_resource); 2377 resource->res1.length = sizeof(struct acpi_resource);
2374 memcpy(&resource->res1.data.io, &ioport->io1, 2378 memcpy(&resource->res1.data.io, &ioport->io1,
2375 sizeof(struct acpi_resource_io)); 2379 sizeof(struct acpi_resource_io));
2376 2380
2377 resource->res2.type = ACPI_RESOURCE_TYPE_IO; 2381 resource->res2.type = ACPI_RESOURCE_TYPE_IO;
2378 resource->res2.length = sizeof(struct acpi_resource); 2382 resource->res2.length = sizeof(struct acpi_resource);
2379 memcpy(&resource->res2.data.io, &ioport->io2, 2383 memcpy(&resource->res2.data.io, &ioport->io2,
2380 sizeof(struct acpi_resource_io)); 2384 sizeof(struct acpi_resource_io));
2381 2385
2382 /* setup irq resource */ 2386 /* setup irq resource */
2383 resource->res3.type = ACPI_RESOURCE_TYPE_IRQ; 2387 resource->res3.type = ACPI_RESOURCE_TYPE_IRQ;
2384 resource->res3.length = sizeof(struct acpi_resource); 2388 resource->res3.length = sizeof(struct acpi_resource);
2385 memcpy(&resource->res3.data.irq, &irq->irq, 2389 memcpy(&resource->res3.data.irq, &irq->irq,
2386 sizeof(struct acpi_resource_irq)); 2390 sizeof(struct acpi_resource_irq));
2387 /* we requested a shared irq */ 2391 /* we requested a shared irq */
2388 resource->res3.data.irq.sharable = ACPI_SHARED; 2392 resource->res3.data.irq.sharable = ACPI_SHARED;
2389 2393
2390 resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG; 2394 resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG;
2391 2395
2392 } 2396 }
2393 /* setup Type 2/3 resources */ 2397 /* setup Type 2/3 resources */
2394 else { 2398 else {
2395 /* setup io resource */ 2399 /* setup io resource */
2396 resource->res1.type = ACPI_RESOURCE_TYPE_IO; 2400 resource->res1.type = ACPI_RESOURCE_TYPE_IO;
2397 resource->res1.length = sizeof(struct acpi_resource); 2401 resource->res1.length = sizeof(struct acpi_resource);
2398 memcpy(&resource->res1.data.io, &ioport->io1, 2402 memcpy(&resource->res1.data.io, &ioport->io1,
2399 sizeof(struct acpi_resource_io)); 2403 sizeof(struct acpi_resource_io));
2400 2404
2401 /* setup irq resource */ 2405 /* setup irq resource */
2402 resource->res2.type = ACPI_RESOURCE_TYPE_IRQ; 2406 resource->res2.type = ACPI_RESOURCE_TYPE_IRQ;
2403 resource->res2.length = sizeof(struct acpi_resource); 2407 resource->res2.length = sizeof(struct acpi_resource);
2404 memcpy(&resource->res2.data.irq, &irq->irq, 2408 memcpy(&resource->res2.data.irq, &irq->irq,
2405 sizeof(struct acpi_resource_irq)); 2409 sizeof(struct acpi_resource_irq));
2406 /* we requested a shared irq */ 2410 /* we requested a shared irq */
2407 resource->res2.data.irq.sharable = ACPI_SHARED; 2411 resource->res2.data.irq.sharable = ACPI_SHARED;
2408 2412
2409 resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG; 2413 resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG;
2410 } 2414 }
2411 2415
2412 /* Attempt to set the resource */ 2416 /* Attempt to set the resource */
2413 dprintk("Evaluating _SRS\n"); 2417 dprintk("Evaluating _SRS\n");
2414 status = acpi_set_current_resources(device->handle, &buffer); 2418 status = acpi_set_current_resources(device->handle, &buffer);
2415 2419
2416 /* check for total failure */ 2420 /* check for total failure */
2417 if (ACPI_FAILURE(status)) { 2421 if (ACPI_FAILURE(status)) {
2418 printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n"); 2422 printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n");
2419 result = -ENODEV; 2423 result = -ENODEV;
2420 goto end; 2424 goto end;
2421 } 2425 }
2422 2426
2423 /* Necessary device initializations calls (from sonypi) */ 2427 /* Necessary device initializations calls (from sonypi) */
2424 sony_pic_call1(0x82); 2428 sony_pic_call1(0x82);
2425 sony_pic_call2(0x81, 0xff); 2429 sony_pic_call2(0x81, 0xff);
2426 sony_pic_call1(compat ? 0x92 : 0x82); 2430 sony_pic_call1(compat ? 0x92 : 0x82);
2427 2431
2428 end: 2432 end:
2429 kfree(resource); 2433 kfree(resource);
2430 return result; 2434 return result;
2431 } 2435 }
2432 2436
2433 /***************** 2437 /*****************
2434 * 2438 *
2435 * ISR: some event is available 2439 * ISR: some event is available
2436 * 2440 *
2437 *****************/ 2441 *****************/
2438 static irqreturn_t sony_pic_irq(int irq, void *dev_id) 2442 static irqreturn_t sony_pic_irq(int irq, void *dev_id)
2439 { 2443 {
2440 int i, j; 2444 int i, j;
2441 u8 ev = 0; 2445 u8 ev = 0;
2442 u8 data_mask = 0; 2446 u8 data_mask = 0;
2443 u8 device_event = 0; 2447 u8 device_event = 0;
2444 2448
2445 struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; 2449 struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
2446 2450
2447 ev = inb_p(dev->cur_ioport->io1.minimum); 2451 ev = inb_p(dev->cur_ioport->io1.minimum);
2448 if (dev->cur_ioport->io2.minimum) 2452 if (dev->cur_ioport->io2.minimum)
2449 data_mask = inb_p(dev->cur_ioport->io2.minimum); 2453 data_mask = inb_p(dev->cur_ioport->io2.minimum);
2450 else 2454 else
2451 data_mask = inb_p(dev->cur_ioport->io1.minimum + 2455 data_mask = inb_p(dev->cur_ioport->io1.minimum +
2452 dev->control->evport_offset); 2456 dev->control->evport_offset);
2453 2457
2454 dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 2458 dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
2455 ev, data_mask, dev->cur_ioport->io1.minimum, 2459 ev, data_mask, dev->cur_ioport->io1.minimum,
2456 dev->control->evport_offset); 2460 dev->control->evport_offset);
2457 2461
2458 if (ev == 0x00 || ev == 0xff) 2462 if (ev == 0x00 || ev == 0xff)
2459 return IRQ_HANDLED; 2463 return IRQ_HANDLED;
2460 2464
2461 for (i = 0; dev->control->event_types[i].mask; i++) { 2465 for (i = 0; dev->control->event_types[i].mask; i++) {
2462 2466
2463 if ((data_mask & dev->control->event_types[i].data) != 2467 if ((data_mask & dev->control->event_types[i].data) !=
2464 dev->control->event_types[i].data) 2468 dev->control->event_types[i].data)
2465 continue; 2469 continue;
2466 2470
2467 if (!(mask & dev->control->event_types[i].mask)) 2471 if (!(mask & dev->control->event_types[i].mask))
2468 continue; 2472 continue;
2469 2473
2470 for (j = 0; dev->control->event_types[i].events[j].event; j++) { 2474 for (j = 0; dev->control->event_types[i].events[j].event; j++) {
2471 if (ev == dev->control->event_types[i].events[j].data) { 2475 if (ev == dev->control->event_types[i].events[j].data) {
2472 device_event = 2476 device_event =
2473 dev->control-> 2477 dev->control->
2474 event_types[i].events[j].event; 2478 event_types[i].events[j].event;
2475 goto found; 2479 goto found;
2476 } 2480 }
2477 } 2481 }
2478 } 2482 }
2479 /* Still not able to decode the event try to pass 2483 /* Still not able to decode the event try to pass
2480 * it over to the minidriver 2484 * it over to the minidriver
2481 */ 2485 */
2482 if (dev->control->handle_irq && 2486 if (dev->control->handle_irq &&
2483 dev->control->handle_irq(data_mask, ev) == 0) 2487 dev->control->handle_irq(data_mask, ev) == 0)
2484 return IRQ_HANDLED; 2488 return IRQ_HANDLED;
2485 2489
2486 dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 2490 dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
2487 ev, data_mask, dev->cur_ioport->io1.minimum, 2491 ev, data_mask, dev->cur_ioport->io1.minimum,
2488 dev->control->evport_offset); 2492 dev->control->evport_offset);
2489 return IRQ_HANDLED; 2493 return IRQ_HANDLED;
2490 2494
2491 found: 2495 found:
2492 sony_laptop_report_input_event(device_event); 2496 sony_laptop_report_input_event(device_event);
2493 acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event); 2497 acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event);
2494 sonypi_compat_report_event(device_event); 2498 sonypi_compat_report_event(device_event);
2495 2499
2496 return IRQ_HANDLED; 2500 return IRQ_HANDLED;
2497 } 2501 }
2498 2502
2499 /***************** 2503 /*****************
2500 * 2504 *
2501 * ACPI driver 2505 * ACPI driver
2502 * 2506 *
2503 *****************/ 2507 *****************/
2504 static int sony_pic_remove(struct acpi_device *device, int type) 2508 static int sony_pic_remove(struct acpi_device *device, int type)
2505 { 2509 {
2506 struct sony_pic_ioport *io, *tmp_io; 2510 struct sony_pic_ioport *io, *tmp_io;
2507 struct sony_pic_irq *irq, *tmp_irq; 2511 struct sony_pic_irq *irq, *tmp_irq;
2508 2512
2509 if (sony_pic_disable(device)) { 2513 if (sony_pic_disable(device)) {
2510 printk(KERN_ERR DRV_PFX "Couldn't disable device.\n"); 2514 printk(KERN_ERR DRV_PFX "Couldn't disable device.\n");
2511 return -ENXIO; 2515 return -ENXIO;
2512 } 2516 }
2513 2517
2514 free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); 2518 free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
2515 release_region(spic_dev.cur_ioport->io1.minimum, 2519 release_region(spic_dev.cur_ioport->io1.minimum,
2516 spic_dev.cur_ioport->io1.address_length); 2520 spic_dev.cur_ioport->io1.address_length);
2517 if (spic_dev.cur_ioport->io2.minimum) 2521 if (spic_dev.cur_ioport->io2.minimum)
2518 release_region(spic_dev.cur_ioport->io2.minimum, 2522 release_region(spic_dev.cur_ioport->io2.minimum,
2519 spic_dev.cur_ioport->io2.address_length); 2523 spic_dev.cur_ioport->io2.address_length);
2520 2524
2521 sonypi_compat_exit(); 2525 sonypi_compat_exit();
2522 2526
2523 sony_laptop_remove_input(); 2527 sony_laptop_remove_input();
2524 2528
2525 /* pf attrs */ 2529 /* pf attrs */
2526 sysfs_remove_group(&sony_pf_device->dev.kobj, &spic_attribute_group); 2530 sysfs_remove_group(&sony_pf_device->dev.kobj, &spic_attribute_group);
2527 sony_pf_remove(); 2531 sony_pf_remove();
2528 2532
2529 list_for_each_entry_safe(io, tmp_io, &spic_dev.ioports, list) { 2533 list_for_each_entry_safe(io, tmp_io, &spic_dev.ioports, list) {
2530 list_del(&io->list); 2534 list_del(&io->list);
2531 kfree(io); 2535 kfree(io);
2532 } 2536 }
2533 list_for_each_entry_safe(irq, tmp_irq, &spic_dev.interrupts, list) { 2537 list_for_each_entry_safe(irq, tmp_irq, &spic_dev.interrupts, list) {
2534 list_del(&irq->list); 2538 list_del(&irq->list);
2535 kfree(irq); 2539 kfree(irq);
2536 } 2540 }
2537 spic_dev.cur_ioport = NULL; 2541 spic_dev.cur_ioport = NULL;
2538 spic_dev.cur_irq = NULL; 2542 spic_dev.cur_irq = NULL;
2539 2543
2540 dprintk(SONY_PIC_DRIVER_NAME " removed.\n"); 2544 dprintk(SONY_PIC_DRIVER_NAME " removed.\n");
2541 return 0; 2545 return 0;
2542 } 2546 }
2543 2547
2544 static int sony_pic_add(struct acpi_device *device) 2548 static int sony_pic_add(struct acpi_device *device)
2545 { 2549 {
2546 int result; 2550 int result;
2547 struct sony_pic_ioport *io, *tmp_io; 2551 struct sony_pic_ioport *io, *tmp_io;
2548 struct sony_pic_irq *irq, *tmp_irq; 2552 struct sony_pic_irq *irq, *tmp_irq;
2549 2553
2550 printk(KERN_INFO DRV_PFX "%s v%s.\n", 2554 printk(KERN_INFO DRV_PFX "%s v%s.\n",
2551 SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); 2555 SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
2552 2556
2553 spic_dev.acpi_dev = device; 2557 spic_dev.acpi_dev = device;
2554 strcpy(acpi_device_class(device), "sony/hotkey"); 2558 strcpy(acpi_device_class(device), "sony/hotkey");
2555 sony_pic_detect_device_type(&spic_dev); 2559 sony_pic_detect_device_type(&spic_dev);
2556 mutex_init(&spic_dev.lock); 2560 mutex_init(&spic_dev.lock);
2557 2561
2558 /* read _PRS resources */ 2562 /* read _PRS resources */
2559 result = sony_pic_possible_resources(device); 2563 result = sony_pic_possible_resources(device);
2560 if (result) { 2564 if (result) {
2561 printk(KERN_ERR DRV_PFX 2565 printk(KERN_ERR DRV_PFX
2562 "Unabe to read possible resources.\n"); 2566 "Unabe to read possible resources.\n");
2563 goto err_free_resources; 2567 goto err_free_resources;
2564 } 2568 }
2565 2569
2566 /* setup input devices and helper fifo */ 2570 /* setup input devices and helper fifo */
2567 result = sony_laptop_setup_input(device); 2571 result = sony_laptop_setup_input(device);
2568 if (result) { 2572 if (result) {
2569 printk(KERN_ERR DRV_PFX 2573 printk(KERN_ERR DRV_PFX
2570 "Unabe to create input devices.\n"); 2574 "Unabe to create input devices.\n");
2571 goto err_free_resources; 2575 goto err_free_resources;
2572 } 2576 }
2573 2577
2574 if (sonypi_compat_init()) 2578 if (sonypi_compat_init())
2575 goto err_remove_input; 2579 goto err_remove_input;
2576 2580
2577 /* request io port */ 2581 /* request io port */
2578 list_for_each_entry_reverse(io, &spic_dev.ioports, list) { 2582 list_for_each_entry_reverse(io, &spic_dev.ioports, list) {
2579 if (request_region(io->io1.minimum, io->io1.address_length, 2583 if (request_region(io->io1.minimum, io->io1.address_length,
2580 "Sony Programable I/O Device")) { 2584 "Sony Programable I/O Device")) {
2581 dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n", 2585 dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n",
2582 io->io1.minimum, io->io1.maximum, 2586 io->io1.minimum, io->io1.maximum,
2583 io->io1.address_length); 2587 io->io1.address_length);
2584 /* Type 1 have 2 ioports */ 2588 /* Type 1 have 2 ioports */
2585 if (io->io2.minimum) { 2589 if (io->io2.minimum) {
2586 if (request_region(io->io2.minimum, 2590 if (request_region(io->io2.minimum,
2587 io->io2.address_length, 2591 io->io2.address_length,
2588 "Sony Programable I/O Device")) { 2592 "Sony Programable I/O Device")) {
2589 dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n", 2593 dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n",
2590 io->io2.minimum, io->io2.maximum, 2594 io->io2.minimum, io->io2.maximum,
2591 io->io2.address_length); 2595 io->io2.address_length);
2592 spic_dev.cur_ioport = io; 2596 spic_dev.cur_ioport = io;
2593 break; 2597 break;
2594 } 2598 }
2595 else { 2599 else {
2596 dprintk("Unable to get I/O port2: " 2600 dprintk("Unable to get I/O port2: "
2597 "0x%.4x (0x%.4x) + 0x%.2x\n", 2601 "0x%.4x (0x%.4x) + 0x%.2x\n",
2598 io->io2.minimum, io->io2.maximum, 2602 io->io2.minimum, io->io2.maximum,
2599 io->io2.address_length); 2603 io->io2.address_length);
2600 release_region(io->io1.minimum, 2604 release_region(io->io1.minimum,
2601 io->io1.address_length); 2605 io->io1.address_length);
2602 } 2606 }
2603 } 2607 }
2604 else { 2608 else {
2605 spic_dev.cur_ioport = io; 2609 spic_dev.cur_ioport = io;
2606 break; 2610 break;
2607 } 2611 }
2608 } 2612 }
2609 } 2613 }
2610 if (!spic_dev.cur_ioport) { 2614 if (!spic_dev.cur_ioport) {
2611 printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); 2615 printk(KERN_ERR DRV_PFX "Failed to request_region.\n");
2612 result = -ENODEV; 2616 result = -ENODEV;
2613 goto err_remove_compat; 2617 goto err_remove_compat;
2614 } 2618 }
2615 2619
2616 /* request IRQ */ 2620 /* request IRQ */
2617 list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { 2621 list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) {
2618 if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, 2622 if (!request_irq(irq->irq.interrupts[0], sony_pic_irq,
2619 IRQF_SHARED, "sony-laptop", &spic_dev)) { 2623 IRQF_SHARED, "sony-laptop", &spic_dev)) {
2620 dprintk("IRQ: %d - triggering: %d - " 2624 dprintk("IRQ: %d - triggering: %d - "
2621 "polarity: %d - shr: %d\n", 2625 "polarity: %d - shr: %d\n",
2622 irq->irq.interrupts[0], 2626 irq->irq.interrupts[0],
2623 irq->irq.triggering, 2627 irq->irq.triggering,
2624 irq->irq.polarity, 2628 irq->irq.polarity,
2625 irq->irq.sharable); 2629 irq->irq.sharable);
2626 spic_dev.cur_irq = irq; 2630 spic_dev.cur_irq = irq;
2627 break; 2631 break;
2628 } 2632 }
2629 } 2633 }
2630 if (!spic_dev.cur_irq) { 2634 if (!spic_dev.cur_irq) {
2631 printk(KERN_ERR DRV_PFX "Failed to request_irq.\n"); 2635 printk(KERN_ERR DRV_PFX "Failed to request_irq.\n");
2632 result = -ENODEV; 2636 result = -ENODEV;
2633 goto err_release_region; 2637 goto err_release_region;
2634 } 2638 }
2635 2639
2636 /* set resource status _SRS */ 2640 /* set resource status _SRS */
2637 result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); 2641 result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq);
2638 if (result) { 2642 if (result) {
2639 printk(KERN_ERR DRV_PFX "Couldn't enable device.\n"); 2643 printk(KERN_ERR DRV_PFX "Couldn't enable device.\n");
2640 goto err_free_irq; 2644 goto err_free_irq;
2641 } 2645 }
2642 2646
2643 spic_dev.bluetooth_power = -1; 2647 spic_dev.bluetooth_power = -1;
2644 /* create device attributes */ 2648 /* create device attributes */
2645 result = sony_pf_add(); 2649 result = sony_pf_add();
2646 if (result) 2650 if (result)
2647 goto err_disable_device; 2651 goto err_disable_device;
2648 2652
2649 result = sysfs_create_group(&sony_pf_device->dev.kobj, &spic_attribute_group); 2653 result = sysfs_create_group(&sony_pf_device->dev.kobj, &spic_attribute_group);
2650 if (result) 2654 if (result)
2651 goto err_remove_pf; 2655 goto err_remove_pf;
2652 2656
2653 return 0; 2657 return 0;
2654 2658
2655 err_remove_pf: 2659 err_remove_pf:
2656 sony_pf_remove(); 2660 sony_pf_remove();
2657 2661
2658 err_disable_device: 2662 err_disable_device:
2659 sony_pic_disable(device); 2663 sony_pic_disable(device);
2660 2664
2661 err_free_irq: 2665 err_free_irq:
2662 free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); 2666 free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
2663 2667
2664 err_release_region: 2668 err_release_region:
2665 release_region(spic_dev.cur_ioport->io1.minimum, 2669 release_region(spic_dev.cur_ioport->io1.minimum,
2666 spic_dev.cur_ioport->io1.address_length); 2670 spic_dev.cur_ioport->io1.address_length);
2667 if (spic_dev.cur_ioport->io2.minimum) 2671 if (spic_dev.cur_ioport->io2.minimum)
2668 release_region(spic_dev.cur_ioport->io2.minimum, 2672 release_region(spic_dev.cur_ioport->io2.minimum,
2669 spic_dev.cur_ioport->io2.address_length); 2673 spic_dev.cur_ioport->io2.address_length);
2670 2674
2671 err_remove_compat: 2675 err_remove_compat:
2672 sonypi_compat_exit(); 2676 sonypi_compat_exit();
2673 2677
2674 err_remove_input: 2678 err_remove_input:
2675 sony_laptop_remove_input(); 2679 sony_laptop_remove_input();
2676 2680
2677 err_free_resources: 2681 err_free_resources:
2678 list_for_each_entry_safe(io, tmp_io, &spic_dev.ioports, list) { 2682 list_for_each_entry_safe(io, tmp_io, &spic_dev.ioports, list) {
2679 list_del(&io->list); 2683 list_del(&io->list);
2680 kfree(io); 2684 kfree(io);
2681 } 2685 }
2682 list_for_each_entry_safe(irq, tmp_irq, &spic_dev.interrupts, list) { 2686 list_for_each_entry_safe(irq, tmp_irq, &spic_dev.interrupts, list) {
2683 list_del(&irq->list); 2687 list_del(&irq->list);
2684 kfree(irq); 2688 kfree(irq);
2685 } 2689 }
2686 spic_dev.cur_ioport = NULL; 2690 spic_dev.cur_ioport = NULL;
2687 spic_dev.cur_irq = NULL; 2691 spic_dev.cur_irq = NULL;
2688 2692
2689 return result; 2693 return result;
2690 } 2694 }
2691 2695
2692 static int sony_pic_suspend(struct acpi_device *device, pm_message_t state) 2696 static int sony_pic_suspend(struct acpi_device *device, pm_message_t state)
2693 { 2697 {
2694 if (sony_pic_disable(device)) 2698 if (sony_pic_disable(device))
2695 return -ENXIO; 2699 return -ENXIO;
2696 return 0; 2700 return 0;
2697 } 2701 }
2698 2702
2699 static int sony_pic_resume(struct acpi_device *device) 2703 static int sony_pic_resume(struct acpi_device *device)
2700 { 2704 {
2701 sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); 2705 sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq);
2702 return 0; 2706 return 0;
2703 } 2707 }
2704 2708
2705 static const struct acpi_device_id sony_pic_device_ids[] = { 2709 static const struct acpi_device_id sony_pic_device_ids[] = {
2706 {SONY_PIC_HID, 0}, 2710 {SONY_PIC_HID, 0},
2707 {"", 0}, 2711 {"", 0},
2708 }; 2712 };
2709 2713
2710 static struct acpi_driver sony_pic_driver = { 2714 static struct acpi_driver sony_pic_driver = {
2711 .name = SONY_PIC_DRIVER_NAME, 2715 .name = SONY_PIC_DRIVER_NAME,
2712 .class = SONY_PIC_CLASS, 2716 .class = SONY_PIC_CLASS,
2713 .ids = sony_pic_device_ids, 2717 .ids = sony_pic_device_ids,
2714 .owner = THIS_MODULE, 2718 .owner = THIS_MODULE,
2715 .ops = { 2719 .ops = {
2716 .add = sony_pic_add, 2720 .add = sony_pic_add,
2717 .remove = sony_pic_remove, 2721 .remove = sony_pic_remove,
2718 .suspend = sony_pic_suspend, 2722 .suspend = sony_pic_suspend,
2719 .resume = sony_pic_resume, 2723 .resume = sony_pic_resume,
2720 }, 2724 },
2721 }; 2725 };
2722 2726
2723 static struct dmi_system_id __initdata sonypi_dmi_table[] = { 2727 static struct dmi_system_id __initdata sonypi_dmi_table[] = {
2724 { 2728 {
2725 .ident = "Sony Vaio", 2729 .ident = "Sony Vaio",
2726 .matches = { 2730 .matches = {
2727 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 2731 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
2728 DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"), 2732 DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"),
2729 }, 2733 },
2730 }, 2734 },
2731 { 2735 {
2732 .ident = "Sony Vaio", 2736 .ident = "Sony Vaio",
2733 .matches = { 2737 .matches = {
2734 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 2738 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
2735 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"), 2739 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"),
2736 }, 2740 },
2737 }, 2741 },
2738 { } 2742 { }
2739 }; 2743 };
2740 2744
2741 static int __init sony_laptop_init(void) 2745 static int __init sony_laptop_init(void)
2742 { 2746 {
2743 int result; 2747 int result;
2744 2748
2745 if (!no_spic && dmi_check_system(sonypi_dmi_table)) { 2749 if (!no_spic && dmi_check_system(sonypi_dmi_table)) {
2746 result = acpi_bus_register_driver(&sony_pic_driver); 2750 result = acpi_bus_register_driver(&sony_pic_driver);
2747 if (result) { 2751 if (result) {
2748 printk(KERN_ERR DRV_PFX 2752 printk(KERN_ERR DRV_PFX
2749 "Unable to register SPIC driver."); 2753 "Unable to register SPIC driver.");
2750 goto out; 2754 goto out;
2751 } 2755 }
2752 } 2756 }
2753 2757
2754 result = acpi_bus_register_driver(&sony_nc_driver); 2758 result = acpi_bus_register_driver(&sony_nc_driver);
2755 if (result) { 2759 if (result) {
2756 printk(KERN_ERR DRV_PFX "Unable to register SNC driver."); 2760 printk(KERN_ERR DRV_PFX "Unable to register SNC driver.");
2757 goto out_unregister_pic; 2761 goto out_unregister_pic;
2758 } 2762 }
2759 2763
2760 return 0; 2764 return 0;
2761 2765
2762 out_unregister_pic: 2766 out_unregister_pic:
2763 if (!no_spic) 2767 if (!no_spic)
2764 acpi_bus_unregister_driver(&sony_pic_driver); 2768 acpi_bus_unregister_driver(&sony_pic_driver);
2765 out: 2769 out:
2766 return result; 2770 return result;
2767 } 2771 }
2768 2772
2769 static void __exit sony_laptop_exit(void) 2773 static void __exit sony_laptop_exit(void)
2770 { 2774 {
2771 acpi_bus_unregister_driver(&sony_nc_driver); 2775 acpi_bus_unregister_driver(&sony_nc_driver);
2772 if (!no_spic) 2776 if (!no_spic)
2773 acpi_bus_unregister_driver(&sony_pic_driver); 2777 acpi_bus_unregister_driver(&sony_pic_driver);
2774 } 2778 }
2775 2779
2776 module_init(sony_laptop_init); 2780 module_init(sony_laptop_init);
2777 module_exit(sony_laptop_exit); 2781 module_exit(sony_laptop_exit);
2778 2782
drivers/misc/thinkpad_acpi.c
1 /* 1 /*
2 * thinkpad_acpi.c - ThinkPad ACPI Extras 2 * thinkpad_acpi.c - ThinkPad ACPI Extras
3 * 3 *
4 * 4 *
5 * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net> 5 * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
6 * Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br> 6 * Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA. 21 * 02110-1301, USA.
22 */ 22 */
23 23
24 #define TPACPI_VERSION "0.21" 24 #define TPACPI_VERSION "0.21"
25 #define TPACPI_SYSFS_VERSION 0x020200 25 #define TPACPI_SYSFS_VERSION 0x020200
26 26
27 /* 27 /*
28 * Changelog: 28 * Changelog:
29 * 2007-10-20 changelog trimmed down 29 * 2007-10-20 changelog trimmed down
30 * 30 *
31 * 2007-03-27 0.14 renamed to thinkpad_acpi and moved to 31 * 2007-03-27 0.14 renamed to thinkpad_acpi and moved to
32 * drivers/misc. 32 * drivers/misc.
33 * 33 *
34 * 2006-11-22 0.13 new maintainer 34 * 2006-11-22 0.13 new maintainer
35 * changelog now lives in git commit history, and will 35 * changelog now lives in git commit history, and will
36 * not be updated further in-file. 36 * not be updated further in-file.
37 * 37 *
38 * 2005-03-17 0.11 support for 600e, 770x 38 * 2005-03-17 0.11 support for 600e, 770x
39 * thanks to Jamie Lentin <lentinj@dial.pipex.com> 39 * thanks to Jamie Lentin <lentinj@dial.pipex.com>
40 * 40 *
41 * 2005-01-16 0.9 use MODULE_VERSION 41 * 2005-01-16 0.9 use MODULE_VERSION
42 * thanks to Henrik Brix Andersen <brix@gentoo.org> 42 * thanks to Henrik Brix Andersen <brix@gentoo.org>
43 * fix parameter passing on module loading 43 * fix parameter passing on module loading
44 * thanks to Rusty Russell <rusty@rustcorp.com.au> 44 * thanks to Rusty Russell <rusty@rustcorp.com.au>
45 * thanks to Jim Radford <radford@blackbean.org> 45 * thanks to Jim Radford <radford@blackbean.org>
46 * 2004-11-08 0.8 fix init error case, don't return from a macro 46 * 2004-11-08 0.8 fix init error case, don't return from a macro
47 * thanks to Chris Wright <chrisw@osdl.org> 47 * thanks to Chris Wright <chrisw@osdl.org>
48 */ 48 */
49 49
50 #include <linux/kernel.h> 50 #include <linux/kernel.h>
51 #include <linux/module.h> 51 #include <linux/module.h>
52 #include <linux/init.h> 52 #include <linux/init.h>
53 #include <linux/types.h> 53 #include <linux/types.h>
54 #include <linux/string.h> 54 #include <linux/string.h>
55 #include <linux/list.h> 55 #include <linux/list.h>
56 #include <linux/mutex.h> 56 #include <linux/mutex.h>
57 #include <linux/kthread.h> 57 #include <linux/kthread.h>
58 #include <linux/freezer.h> 58 #include <linux/freezer.h>
59 #include <linux/delay.h> 59 #include <linux/delay.h>
60 60
61 #include <linux/nvram.h> 61 #include <linux/nvram.h>
62 #include <linux/proc_fs.h> 62 #include <linux/proc_fs.h>
63 #include <linux/sysfs.h> 63 #include <linux/sysfs.h>
64 #include <linux/backlight.h> 64 #include <linux/backlight.h>
65 #include <linux/fb.h> 65 #include <linux/fb.h>
66 #include <linux/platform_device.h> 66 #include <linux/platform_device.h>
67 #include <linux/hwmon.h> 67 #include <linux/hwmon.h>
68 #include <linux/hwmon-sysfs.h> 68 #include <linux/hwmon-sysfs.h>
69 #include <linux/input.h> 69 #include <linux/input.h>
70 #include <linux/leds.h> 70 #include <linux/leds.h>
71 #include <linux/rfkill.h> 71 #include <linux/rfkill.h>
72 #include <asm/uaccess.h> 72 #include <asm/uaccess.h>
73 73
74 #include <linux/dmi.h> 74 #include <linux/dmi.h>
75 #include <linux/jiffies.h> 75 #include <linux/jiffies.h>
76 #include <linux/workqueue.h> 76 #include <linux/workqueue.h>
77 77
78 #include <acpi/acpi_drivers.h> 78 #include <acpi/acpi_drivers.h>
79 #include <acpi/acnamesp.h> 79 #include <acpi/acnamesp.h>
80 80
81 #include <linux/pci_ids.h> 81 #include <linux/pci_ids.h>
82 82
83 83
84 /* ThinkPad CMOS commands */ 84 /* ThinkPad CMOS commands */
85 #define TP_CMOS_VOLUME_DOWN 0 85 #define TP_CMOS_VOLUME_DOWN 0
86 #define TP_CMOS_VOLUME_UP 1 86 #define TP_CMOS_VOLUME_UP 1
87 #define TP_CMOS_VOLUME_MUTE 2 87 #define TP_CMOS_VOLUME_MUTE 2
88 #define TP_CMOS_BRIGHTNESS_UP 4 88 #define TP_CMOS_BRIGHTNESS_UP 4
89 #define TP_CMOS_BRIGHTNESS_DOWN 5 89 #define TP_CMOS_BRIGHTNESS_DOWN 5
90 #define TP_CMOS_THINKLIGHT_ON 12 90 #define TP_CMOS_THINKLIGHT_ON 12
91 #define TP_CMOS_THINKLIGHT_OFF 13 91 #define TP_CMOS_THINKLIGHT_OFF 13
92 92
93 /* NVRAM Addresses */ 93 /* NVRAM Addresses */
94 enum tp_nvram_addr { 94 enum tp_nvram_addr {
95 TP_NVRAM_ADDR_HK2 = 0x57, 95 TP_NVRAM_ADDR_HK2 = 0x57,
96 TP_NVRAM_ADDR_THINKLIGHT = 0x58, 96 TP_NVRAM_ADDR_THINKLIGHT = 0x58,
97 TP_NVRAM_ADDR_VIDEO = 0x59, 97 TP_NVRAM_ADDR_VIDEO = 0x59,
98 TP_NVRAM_ADDR_BRIGHTNESS = 0x5e, 98 TP_NVRAM_ADDR_BRIGHTNESS = 0x5e,
99 TP_NVRAM_ADDR_MIXER = 0x60, 99 TP_NVRAM_ADDR_MIXER = 0x60,
100 }; 100 };
101 101
102 /* NVRAM bit masks */ 102 /* NVRAM bit masks */
103 enum { 103 enum {
104 TP_NVRAM_MASK_HKT_THINKPAD = 0x08, 104 TP_NVRAM_MASK_HKT_THINKPAD = 0x08,
105 TP_NVRAM_MASK_HKT_ZOOM = 0x20, 105 TP_NVRAM_MASK_HKT_ZOOM = 0x20,
106 TP_NVRAM_MASK_HKT_DISPLAY = 0x40, 106 TP_NVRAM_MASK_HKT_DISPLAY = 0x40,
107 TP_NVRAM_MASK_HKT_HIBERNATE = 0x80, 107 TP_NVRAM_MASK_HKT_HIBERNATE = 0x80,
108 TP_NVRAM_MASK_THINKLIGHT = 0x10, 108 TP_NVRAM_MASK_THINKLIGHT = 0x10,
109 TP_NVRAM_MASK_HKT_DISPEXPND = 0x30, 109 TP_NVRAM_MASK_HKT_DISPEXPND = 0x30,
110 TP_NVRAM_MASK_HKT_BRIGHTNESS = 0x20, 110 TP_NVRAM_MASK_HKT_BRIGHTNESS = 0x20,
111 TP_NVRAM_MASK_LEVEL_BRIGHTNESS = 0x0f, 111 TP_NVRAM_MASK_LEVEL_BRIGHTNESS = 0x0f,
112 TP_NVRAM_POS_LEVEL_BRIGHTNESS = 0, 112 TP_NVRAM_POS_LEVEL_BRIGHTNESS = 0,
113 TP_NVRAM_MASK_MUTE = 0x40, 113 TP_NVRAM_MASK_MUTE = 0x40,
114 TP_NVRAM_MASK_HKT_VOLUME = 0x80, 114 TP_NVRAM_MASK_HKT_VOLUME = 0x80,
115 TP_NVRAM_MASK_LEVEL_VOLUME = 0x0f, 115 TP_NVRAM_MASK_LEVEL_VOLUME = 0x0f,
116 TP_NVRAM_POS_LEVEL_VOLUME = 0, 116 TP_NVRAM_POS_LEVEL_VOLUME = 0,
117 }; 117 };
118 118
119 /* ACPI HIDs */ 119 /* ACPI HIDs */
120 #define TPACPI_ACPI_HKEY_HID "IBM0068" 120 #define TPACPI_ACPI_HKEY_HID "IBM0068"
121 121
122 /* Input IDs */ 122 /* Input IDs */
123 #define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */ 123 #define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */
124 #define TPACPI_HKEY_INPUT_VERSION 0x4101 124 #define TPACPI_HKEY_INPUT_VERSION 0x4101
125 125
126 126
127 /**************************************************************************** 127 /****************************************************************************
128 * Main driver 128 * Main driver
129 */ 129 */
130 130
131 #define TPACPI_NAME "thinkpad" 131 #define TPACPI_NAME "thinkpad"
132 #define TPACPI_DESC "ThinkPad ACPI Extras" 132 #define TPACPI_DESC "ThinkPad ACPI Extras"
133 #define TPACPI_FILE TPACPI_NAME "_acpi" 133 #define TPACPI_FILE TPACPI_NAME "_acpi"
134 #define TPACPI_URL "http://ibm-acpi.sf.net/" 134 #define TPACPI_URL "http://ibm-acpi.sf.net/"
135 #define TPACPI_MAIL "ibm-acpi-devel@lists.sourceforge.net" 135 #define TPACPI_MAIL "ibm-acpi-devel@lists.sourceforge.net"
136 136
137 #define TPACPI_PROC_DIR "ibm" 137 #define TPACPI_PROC_DIR "ibm"
138 #define TPACPI_ACPI_EVENT_PREFIX "ibm" 138 #define TPACPI_ACPI_EVENT_PREFIX "ibm"
139 #define TPACPI_DRVR_NAME TPACPI_FILE 139 #define TPACPI_DRVR_NAME TPACPI_FILE
140 #define TPACPI_DRVR_SHORTNAME "tpacpi" 140 #define TPACPI_DRVR_SHORTNAME "tpacpi"
141 #define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon" 141 #define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon"
142 142
143 #define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd" 143 #define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd"
144 #define TPACPI_WORKQUEUE_NAME "ktpacpid" 144 #define TPACPI_WORKQUEUE_NAME "ktpacpid"
145 145
146 #define TPACPI_MAX_ACPI_ARGS 3 146 #define TPACPI_MAX_ACPI_ARGS 3
147 147
148 /* rfkill switches */ 148 /* rfkill switches */
149 enum { 149 enum {
150 TPACPI_RFK_BLUETOOTH_SW_ID = 0, 150 TPACPI_RFK_BLUETOOTH_SW_ID = 0,
151 TPACPI_RFK_WWAN_SW_ID, 151 TPACPI_RFK_WWAN_SW_ID,
152 }; 152 };
153 153
154 /* Debugging */ 154 /* Debugging */
155 #define TPACPI_LOG TPACPI_FILE ": " 155 #define TPACPI_LOG TPACPI_FILE ": "
156 #define TPACPI_ERR KERN_ERR TPACPI_LOG 156 #define TPACPI_ERR KERN_ERR TPACPI_LOG
157 #define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG 157 #define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
158 #define TPACPI_INFO KERN_INFO TPACPI_LOG 158 #define TPACPI_INFO KERN_INFO TPACPI_LOG
159 #define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG 159 #define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
160 160
161 #define TPACPI_DBG_ALL 0xffff 161 #define TPACPI_DBG_ALL 0xffff
162 #define TPACPI_DBG_INIT 0x0001 162 #define TPACPI_DBG_INIT 0x0001
163 #define TPACPI_DBG_EXIT 0x0002 163 #define TPACPI_DBG_EXIT 0x0002
164 #define dbg_printk(a_dbg_level, format, arg...) \ 164 #define dbg_printk(a_dbg_level, format, arg...) \
165 do { if (dbg_level & a_dbg_level) \ 165 do { if (dbg_level & a_dbg_level) \
166 printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ 166 printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
167 } while (0) 167 } while (0)
168 #ifdef CONFIG_THINKPAD_ACPI_DEBUG 168 #ifdef CONFIG_THINKPAD_ACPI_DEBUG
169 #define vdbg_printk(a_dbg_level, format, arg...) \ 169 #define vdbg_printk(a_dbg_level, format, arg...) \
170 dbg_printk(a_dbg_level, format, ## arg) 170 dbg_printk(a_dbg_level, format, ## arg)
171 static const char *str_supported(int is_supported); 171 static const char *str_supported(int is_supported);
172 #else 172 #else
173 #define vdbg_printk(a_dbg_level, format, arg...) 173 #define vdbg_printk(a_dbg_level, format, arg...)
174 #endif 174 #endif
175 175
176 #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") 176 #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
177 #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") 177 #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
178 #define strlencmp(a, b) (strncmp((a), (b), strlen(b))) 178 #define strlencmp(a, b) (strncmp((a), (b), strlen(b)))
179 179
180 180
181 /**************************************************************************** 181 /****************************************************************************
182 * Driver-wide structs and misc. variables 182 * Driver-wide structs and misc. variables
183 */ 183 */
184 184
185 struct ibm_struct; 185 struct ibm_struct;
186 186
187 struct tp_acpi_drv_struct { 187 struct tp_acpi_drv_struct {
188 const struct acpi_device_id *hid; 188 const struct acpi_device_id *hid;
189 struct acpi_driver *driver; 189 struct acpi_driver *driver;
190 190
191 void (*notify) (struct ibm_struct *, u32); 191 void (*notify) (struct ibm_struct *, u32);
192 acpi_handle *handle; 192 acpi_handle *handle;
193 u32 type; 193 u32 type;
194 struct acpi_device *device; 194 struct acpi_device *device;
195 }; 195 };
196 196
197 struct ibm_struct { 197 struct ibm_struct {
198 char *name; 198 char *name;
199 199
200 int (*read) (char *); 200 int (*read) (char *);
201 int (*write) (char *); 201 int (*write) (char *);
202 void (*exit) (void); 202 void (*exit) (void);
203 void (*resume) (void); 203 void (*resume) (void);
204 void (*suspend) (pm_message_t state); 204 void (*suspend) (pm_message_t state);
205 205
206 struct list_head all_drivers; 206 struct list_head all_drivers;
207 207
208 struct tp_acpi_drv_struct *acpi; 208 struct tp_acpi_drv_struct *acpi;
209 209
210 struct { 210 struct {
211 u8 acpi_driver_registered:1; 211 u8 acpi_driver_registered:1;
212 u8 acpi_notify_installed:1; 212 u8 acpi_notify_installed:1;
213 u8 proc_created:1; 213 u8 proc_created:1;
214 u8 init_called:1; 214 u8 init_called:1;
215 u8 experimental:1; 215 u8 experimental:1;
216 } flags; 216 } flags;
217 }; 217 };
218 218
219 struct ibm_init_struct { 219 struct ibm_init_struct {
220 char param[32]; 220 char param[32];
221 221
222 int (*init) (struct ibm_init_struct *); 222 int (*init) (struct ibm_init_struct *);
223 struct ibm_struct *data; 223 struct ibm_struct *data;
224 }; 224 };
225 225
226 static struct { 226 static struct {
227 #ifdef CONFIG_THINKPAD_ACPI_BAY 227 #ifdef CONFIG_THINKPAD_ACPI_BAY
228 u32 bay_status:1; 228 u32 bay_status:1;
229 u32 bay_eject:1; 229 u32 bay_eject:1;
230 u32 bay_status2:1; 230 u32 bay_status2:1;
231 u32 bay_eject2:1; 231 u32 bay_eject2:1;
232 #endif 232 #endif
233 u32 bluetooth:1; 233 u32 bluetooth:1;
234 u32 hotkey:1; 234 u32 hotkey:1;
235 u32 hotkey_mask:1; 235 u32 hotkey_mask:1;
236 u32 hotkey_wlsw:1; 236 u32 hotkey_wlsw:1;
237 u32 hotkey_tablet:1; 237 u32 hotkey_tablet:1;
238 u32 light:1; 238 u32 light:1;
239 u32 light_status:1; 239 u32 light_status:1;
240 u32 bright_16levels:1; 240 u32 bright_16levels:1;
241 u32 bright_acpimode:1; 241 u32 bright_acpimode:1;
242 u32 wan:1; 242 u32 wan:1;
243 u32 fan_ctrl_status_undef:1; 243 u32 fan_ctrl_status_undef:1;
244 u32 input_device_registered:1; 244 u32 input_device_registered:1;
245 u32 platform_drv_registered:1; 245 u32 platform_drv_registered:1;
246 u32 platform_drv_attrs_registered:1; 246 u32 platform_drv_attrs_registered:1;
247 u32 sensors_pdrv_registered:1; 247 u32 sensors_pdrv_registered:1;
248 u32 sensors_pdrv_attrs_registered:1; 248 u32 sensors_pdrv_attrs_registered:1;
249 u32 sensors_pdev_attrs_registered:1; 249 u32 sensors_pdev_attrs_registered:1;
250 u32 hotkey_poll_active:1; 250 u32 hotkey_poll_active:1;
251 } tp_features; 251 } tp_features;
252 252
253 static struct { 253 static struct {
254 u16 hotkey_mask_ff:1; 254 u16 hotkey_mask_ff:1;
255 u16 bright_cmos_ec_unsync:1; 255 u16 bright_cmos_ec_unsync:1;
256 } tp_warned; 256 } tp_warned;
257 257
258 struct thinkpad_id_data { 258 struct thinkpad_id_data {
259 unsigned int vendor; /* ThinkPad vendor: 259 unsigned int vendor; /* ThinkPad vendor:
260 * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */ 260 * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
261 261
262 char *bios_version_str; /* Something like 1ZET51WW (1.03z) */ 262 char *bios_version_str; /* Something like 1ZET51WW (1.03z) */
263 char *ec_version_str; /* Something like 1ZHT51WW-1.04a */ 263 char *ec_version_str; /* Something like 1ZHT51WW-1.04a */
264 264
265 u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ 265 u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */
266 u16 ec_model; 266 u16 ec_model;
267 267
268 char *model_str; /* ThinkPad T43 */ 268 char *model_str; /* ThinkPad T43 */
269 char *nummodel_str; /* 9384A9C for a 9384-A9C model */ 269 char *nummodel_str; /* 9384A9C for a 9384-A9C model */
270 }; 270 };
271 static struct thinkpad_id_data thinkpad_id; 271 static struct thinkpad_id_data thinkpad_id;
272 272
273 static enum { 273 static enum {
274 TPACPI_LIFE_INIT = 0, 274 TPACPI_LIFE_INIT = 0,
275 TPACPI_LIFE_RUNNING, 275 TPACPI_LIFE_RUNNING,
276 TPACPI_LIFE_EXITING, 276 TPACPI_LIFE_EXITING,
277 } tpacpi_lifecycle; 277 } tpacpi_lifecycle;
278 278
279 static int experimental; 279 static int experimental;
280 static u32 dbg_level; 280 static u32 dbg_level;
281 281
282 static struct workqueue_struct *tpacpi_wq; 282 static struct workqueue_struct *tpacpi_wq;
283 283
284 /* Special LED class that can defer work */ 284 /* Special LED class that can defer work */
285 struct tpacpi_led_classdev { 285 struct tpacpi_led_classdev {
286 struct led_classdev led_classdev; 286 struct led_classdev led_classdev;
287 struct work_struct work; 287 struct work_struct work;
288 enum led_brightness new_brightness; 288 enum led_brightness new_brightness;
289 unsigned int led; 289 unsigned int led;
290 }; 290 };
291 291
292 /**************************************************************************** 292 /****************************************************************************
293 **************************************************************************** 293 ****************************************************************************
294 * 294 *
295 * ACPI Helpers and device model 295 * ACPI Helpers and device model
296 * 296 *
297 **************************************************************************** 297 ****************************************************************************
298 ****************************************************************************/ 298 ****************************************************************************/
299 299
300 /************************************************************************* 300 /*************************************************************************
301 * ACPI basic handles 301 * ACPI basic handles
302 */ 302 */
303 303
304 static acpi_handle root_handle; 304 static acpi_handle root_handle;
305 305
306 #define TPACPI_HANDLE(object, parent, paths...) \ 306 #define TPACPI_HANDLE(object, parent, paths...) \
307 static acpi_handle object##_handle; \ 307 static acpi_handle object##_handle; \
308 static acpi_handle *object##_parent = &parent##_handle; \ 308 static acpi_handle *object##_parent = &parent##_handle; \
309 static char *object##_path; \ 309 static char *object##_path; \
310 static char *object##_paths[] = { paths } 310 static char *object##_paths[] = { paths }
311 311
312 TPACPI_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */ 312 TPACPI_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */
313 "\\_SB.PCI.ISA.EC", /* 570 */ 313 "\\_SB.PCI.ISA.EC", /* 570 */
314 "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */ 314 "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */
315 "\\_SB.PCI0.ISA.EC", /* A21e, A2xm/p, T20-22, X20-21 */ 315 "\\_SB.PCI0.ISA.EC", /* A21e, A2xm/p, T20-22, X20-21 */
316 "\\_SB.PCI0.AD4S.EC0", /* i1400, R30 */ 316 "\\_SB.PCI0.AD4S.EC0", /* i1400, R30 */
317 "\\_SB.PCI0.ICH3.EC0", /* R31 */ 317 "\\_SB.PCI0.ICH3.EC0", /* R31 */
318 "\\_SB.PCI0.LPC.EC", /* all others */ 318 "\\_SB.PCI0.LPC.EC", /* all others */
319 ); 319 );
320 320
321 TPACPI_HANDLE(ecrd, ec, "ECRD"); /* 570 */ 321 TPACPI_HANDLE(ecrd, ec, "ECRD"); /* 570 */
322 TPACPI_HANDLE(ecwr, ec, "ECWR"); /* 570 */ 322 TPACPI_HANDLE(ecwr, ec, "ECWR"); /* 570 */
323 323
324 TPACPI_HANDLE(cmos, root, "\\UCMS", /* R50, R50e, R50p, R51, */ 324 TPACPI_HANDLE(cmos, root, "\\UCMS", /* R50, R50e, R50p, R51, */
325 /* T4x, X31, X40 */ 325 /* T4x, X31, X40 */
326 "\\CMOS", /* A3x, G4x, R32, T23, T30, X22-24, X30 */ 326 "\\CMOS", /* A3x, G4x, R32, T23, T30, X22-24, X30 */
327 "\\CMS", /* R40, R40e */ 327 "\\CMS", /* R40, R40e */
328 ); /* all others */ 328 ); /* all others */
329 329
330 TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */ 330 TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */
331 "^HKEY", /* R30, R31 */ 331 "^HKEY", /* R30, R31 */
332 "HKEY", /* all others */ 332 "HKEY", /* all others */
333 ); /* 570 */ 333 ); /* 570 */
334 334
335 TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */ 335 TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */
336 "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ 336 "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */
337 "\\_SB.PCI0.VID0", /* 770e */ 337 "\\_SB.PCI0.VID0", /* 770e */
338 "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ 338 "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */
339 "\\_SB.PCI0.AGP.VID", /* all others */ 339 "\\_SB.PCI0.AGP.VID", /* all others */
340 ); /* R30, R31 */ 340 ); /* R30, R31 */
341 341
342 342
343 /************************************************************************* 343 /*************************************************************************
344 * ACPI helpers 344 * ACPI helpers
345 */ 345 */
346 346
347 static int acpi_evalf(acpi_handle handle, 347 static int acpi_evalf(acpi_handle handle,
348 void *res, char *method, char *fmt, ...) 348 void *res, char *method, char *fmt, ...)
349 { 349 {
350 char *fmt0 = fmt; 350 char *fmt0 = fmt;
351 struct acpi_object_list params; 351 struct acpi_object_list params;
352 union acpi_object in_objs[TPACPI_MAX_ACPI_ARGS]; 352 union acpi_object in_objs[TPACPI_MAX_ACPI_ARGS];
353 struct acpi_buffer result, *resultp; 353 struct acpi_buffer result, *resultp;
354 union acpi_object out_obj; 354 union acpi_object out_obj;
355 acpi_status status; 355 acpi_status status;
356 va_list ap; 356 va_list ap;
357 char res_type; 357 char res_type;
358 int success; 358 int success;
359 int quiet; 359 int quiet;
360 360
361 if (!*fmt) { 361 if (!*fmt) {
362 printk(TPACPI_ERR "acpi_evalf() called with empty format\n"); 362 printk(TPACPI_ERR "acpi_evalf() called with empty format\n");
363 return 0; 363 return 0;
364 } 364 }
365 365
366 if (*fmt == 'q') { 366 if (*fmt == 'q') {
367 quiet = 1; 367 quiet = 1;
368 fmt++; 368 fmt++;
369 } else 369 } else
370 quiet = 0; 370 quiet = 0;
371 371
372 res_type = *(fmt++); 372 res_type = *(fmt++);
373 373
374 params.count = 0; 374 params.count = 0;
375 params.pointer = &in_objs[0]; 375 params.pointer = &in_objs[0];
376 376
377 va_start(ap, fmt); 377 va_start(ap, fmt);
378 while (*fmt) { 378 while (*fmt) {
379 char c = *(fmt++); 379 char c = *(fmt++);
380 switch (c) { 380 switch (c) {
381 case 'd': /* int */ 381 case 'd': /* int */
382 in_objs[params.count].integer.value = va_arg(ap, int); 382 in_objs[params.count].integer.value = va_arg(ap, int);
383 in_objs[params.count++].type = ACPI_TYPE_INTEGER; 383 in_objs[params.count++].type = ACPI_TYPE_INTEGER;
384 break; 384 break;
385 /* add more types as needed */ 385 /* add more types as needed */
386 default: 386 default:
387 printk(TPACPI_ERR "acpi_evalf() called " 387 printk(TPACPI_ERR "acpi_evalf() called "
388 "with invalid format character '%c'\n", c); 388 "with invalid format character '%c'\n", c);
389 return 0; 389 return 0;
390 } 390 }
391 } 391 }
392 va_end(ap); 392 va_end(ap);
393 393
394 if (res_type != 'v') { 394 if (res_type != 'v') {
395 result.length = sizeof(out_obj); 395 result.length = sizeof(out_obj);
396 result.pointer = &out_obj; 396 result.pointer = &out_obj;
397 resultp = &result; 397 resultp = &result;
398 } else 398 } else
399 resultp = NULL; 399 resultp = NULL;
400 400
401 status = acpi_evaluate_object(handle, method, &params, resultp); 401 status = acpi_evaluate_object(handle, method, &params, resultp);
402 402
403 switch (res_type) { 403 switch (res_type) {
404 case 'd': /* int */ 404 case 'd': /* int */
405 if (res) 405 if (res)
406 *(int *)res = out_obj.integer.value; 406 *(int *)res = out_obj.integer.value;
407 success = status == AE_OK && out_obj.type == ACPI_TYPE_INTEGER; 407 success = status == AE_OK && out_obj.type == ACPI_TYPE_INTEGER;
408 break; 408 break;
409 case 'v': /* void */ 409 case 'v': /* void */
410 success = status == AE_OK; 410 success = status == AE_OK;
411 break; 411 break;
412 /* add more types as needed */ 412 /* add more types as needed */
413 default: 413 default:
414 printk(TPACPI_ERR "acpi_evalf() called " 414 printk(TPACPI_ERR "acpi_evalf() called "
415 "with invalid format character '%c'\n", res_type); 415 "with invalid format character '%c'\n", res_type);
416 return 0; 416 return 0;
417 } 417 }
418 418
419 if (!success && !quiet) 419 if (!success && !quiet)
420 printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %d\n", 420 printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %d\n",
421 method, fmt0, status); 421 method, fmt0, status);
422 422
423 return success; 423 return success;
424 } 424 }
425 425
426 static int acpi_ec_read(int i, u8 *p) 426 static int acpi_ec_read(int i, u8 *p)
427 { 427 {
428 int v; 428 int v;
429 429
430 if (ecrd_handle) { 430 if (ecrd_handle) {
431 if (!acpi_evalf(ecrd_handle, &v, NULL, "dd", i)) 431 if (!acpi_evalf(ecrd_handle, &v, NULL, "dd", i))
432 return 0; 432 return 0;
433 *p = v; 433 *p = v;
434 } else { 434 } else {
435 if (ec_read(i, p) < 0) 435 if (ec_read(i, p) < 0)
436 return 0; 436 return 0;
437 } 437 }
438 438
439 return 1; 439 return 1;
440 } 440 }
441 441
442 static int acpi_ec_write(int i, u8 v) 442 static int acpi_ec_write(int i, u8 v)
443 { 443 {
444 if (ecwr_handle) { 444 if (ecwr_handle) {
445 if (!acpi_evalf(ecwr_handle, NULL, NULL, "vdd", i, v)) 445 if (!acpi_evalf(ecwr_handle, NULL, NULL, "vdd", i, v))
446 return 0; 446 return 0;
447 } else { 447 } else {
448 if (ec_write(i, v) < 0) 448 if (ec_write(i, v) < 0)
449 return 0; 449 return 0;
450 } 450 }
451 451
452 return 1; 452 return 1;
453 } 453 }
454 454
455 #if defined(CONFIG_THINKPAD_ACPI_DOCK) || defined(CONFIG_THINKPAD_ACPI_BAY) 455 #if defined(CONFIG_THINKPAD_ACPI_DOCK) || defined(CONFIG_THINKPAD_ACPI_BAY)
456 static int _sta(acpi_handle handle) 456 static int _sta(acpi_handle handle)
457 { 457 {
458 int status; 458 int status;
459 459
460 if (!handle || !acpi_evalf(handle, &status, "_STA", "d")) 460 if (!handle || !acpi_evalf(handle, &status, "_STA", "d"))
461 status = 0; 461 status = 0;
462 462
463 return status; 463 return status;
464 } 464 }
465 #endif 465 #endif
466 466
467 static int issue_thinkpad_cmos_command(int cmos_cmd) 467 static int issue_thinkpad_cmos_command(int cmos_cmd)
468 { 468 {
469 if (!cmos_handle) 469 if (!cmos_handle)
470 return -ENXIO; 470 return -ENXIO;
471 471
472 if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd)) 472 if (!acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd))
473 return -EIO; 473 return -EIO;
474 474
475 return 0; 475 return 0;
476 } 476 }
477 477
478 /************************************************************************* 478 /*************************************************************************
479 * ACPI device model 479 * ACPI device model
480 */ 480 */
481 481
482 #define TPACPI_ACPIHANDLE_INIT(object) \ 482 #define TPACPI_ACPIHANDLE_INIT(object) \
483 drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \ 483 drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \
484 object##_paths, ARRAY_SIZE(object##_paths), &object##_path) 484 object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
485 485
486 static void drv_acpi_handle_init(char *name, 486 static void drv_acpi_handle_init(char *name,
487 acpi_handle *handle, acpi_handle parent, 487 acpi_handle *handle, acpi_handle parent,
488 char **paths, int num_paths, char **path) 488 char **paths, int num_paths, char **path)
489 { 489 {
490 int i; 490 int i;
491 acpi_status status; 491 acpi_status status;
492 492
493 vdbg_printk(TPACPI_DBG_INIT, "trying to locate ACPI handle for %s\n", 493 vdbg_printk(TPACPI_DBG_INIT, "trying to locate ACPI handle for %s\n",
494 name); 494 name);
495 495
496 for (i = 0; i < num_paths; i++) { 496 for (i = 0; i < num_paths; i++) {
497 status = acpi_get_handle(parent, paths[i], handle); 497 status = acpi_get_handle(parent, paths[i], handle);
498 if (ACPI_SUCCESS(status)) { 498 if (ACPI_SUCCESS(status)) {
499 *path = paths[i]; 499 *path = paths[i];
500 dbg_printk(TPACPI_DBG_INIT, 500 dbg_printk(TPACPI_DBG_INIT,
501 "Found ACPI handle %s for %s\n", 501 "Found ACPI handle %s for %s\n",
502 *path, name); 502 *path, name);
503 return; 503 return;
504 } 504 }
505 } 505 }
506 506
507 vdbg_printk(TPACPI_DBG_INIT, "ACPI handle for %s not found\n", 507 vdbg_printk(TPACPI_DBG_INIT, "ACPI handle for %s not found\n",
508 name); 508 name);
509 *handle = NULL; 509 *handle = NULL;
510 } 510 }
511 511
512 static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data) 512 static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
513 { 513 {
514 struct ibm_struct *ibm = data; 514 struct ibm_struct *ibm = data;
515 515
516 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) 516 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
517 return; 517 return;
518 518
519 if (!ibm || !ibm->acpi || !ibm->acpi->notify) 519 if (!ibm || !ibm->acpi || !ibm->acpi->notify)
520 return; 520 return;
521 521
522 ibm->acpi->notify(ibm, event); 522 ibm->acpi->notify(ibm, event);
523 } 523 }
524 524
525 static int __init setup_acpi_notify(struct ibm_struct *ibm) 525 static int __init setup_acpi_notify(struct ibm_struct *ibm)
526 { 526 {
527 acpi_status status; 527 acpi_status status;
528 int rc; 528 int rc;
529 529
530 BUG_ON(!ibm->acpi); 530 BUG_ON(!ibm->acpi);
531 531
532 if (!*ibm->acpi->handle) 532 if (!*ibm->acpi->handle)
533 return 0; 533 return 0;
534 534
535 vdbg_printk(TPACPI_DBG_INIT, 535 vdbg_printk(TPACPI_DBG_INIT,
536 "setting up ACPI notify for %s\n", ibm->name); 536 "setting up ACPI notify for %s\n", ibm->name);
537 537
538 rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device); 538 rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device);
539 if (rc < 0) { 539 if (rc < 0) {
540 printk(TPACPI_ERR "acpi_bus_get_device(%s) failed: %d\n", 540 printk(TPACPI_ERR "acpi_bus_get_device(%s) failed: %d\n",
541 ibm->name, rc); 541 ibm->name, rc);
542 return -ENODEV; 542 return -ENODEV;
543 } 543 }
544 544
545 ibm->acpi->device->driver_data = ibm; 545 ibm->acpi->device->driver_data = ibm;
546 sprintf(acpi_device_class(ibm->acpi->device), "%s/%s", 546 sprintf(acpi_device_class(ibm->acpi->device), "%s/%s",
547 TPACPI_ACPI_EVENT_PREFIX, 547 TPACPI_ACPI_EVENT_PREFIX,
548 ibm->name); 548 ibm->name);
549 549
550 status = acpi_install_notify_handler(*ibm->acpi->handle, 550 status = acpi_install_notify_handler(*ibm->acpi->handle,
551 ibm->acpi->type, dispatch_acpi_notify, ibm); 551 ibm->acpi->type, dispatch_acpi_notify, ibm);
552 if (ACPI_FAILURE(status)) { 552 if (ACPI_FAILURE(status)) {
553 if (status == AE_ALREADY_EXISTS) { 553 if (status == AE_ALREADY_EXISTS) {
554 printk(TPACPI_NOTICE 554 printk(TPACPI_NOTICE
555 "another device driver is already " 555 "another device driver is already "
556 "handling %s events\n", ibm->name); 556 "handling %s events\n", ibm->name);
557 } else { 557 } else {
558 printk(TPACPI_ERR 558 printk(TPACPI_ERR
559 "acpi_install_notify_handler(%s) failed: %d\n", 559 "acpi_install_notify_handler(%s) failed: %d\n",
560 ibm->name, status); 560 ibm->name, status);
561 } 561 }
562 return -ENODEV; 562 return -ENODEV;
563 } 563 }
564 ibm->flags.acpi_notify_installed = 1; 564 ibm->flags.acpi_notify_installed = 1;
565 return 0; 565 return 0;
566 } 566 }
567 567
568 static int __init tpacpi_device_add(struct acpi_device *device) 568 static int __init tpacpi_device_add(struct acpi_device *device)
569 { 569 {
570 return 0; 570 return 0;
571 } 571 }
572 572
573 static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) 573 static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
574 { 574 {
575 int rc; 575 int rc;
576 576
577 dbg_printk(TPACPI_DBG_INIT, 577 dbg_printk(TPACPI_DBG_INIT,
578 "registering %s as an ACPI driver\n", ibm->name); 578 "registering %s as an ACPI driver\n", ibm->name);
579 579
580 BUG_ON(!ibm->acpi); 580 BUG_ON(!ibm->acpi);
581 581
582 ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); 582 ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
583 if (!ibm->acpi->driver) { 583 if (!ibm->acpi->driver) {
584 printk(TPACPI_ERR 584 printk(TPACPI_ERR
585 "failed to allocate memory for ibm->acpi->driver\n"); 585 "failed to allocate memory for ibm->acpi->driver\n");
586 return -ENOMEM; 586 return -ENOMEM;
587 } 587 }
588 588
589 sprintf(ibm->acpi->driver->name, "%s_%s", TPACPI_NAME, ibm->name); 589 sprintf(ibm->acpi->driver->name, "%s_%s", TPACPI_NAME, ibm->name);
590 ibm->acpi->driver->ids = ibm->acpi->hid; 590 ibm->acpi->driver->ids = ibm->acpi->hid;
591 591
592 ibm->acpi->driver->ops.add = &tpacpi_device_add; 592 ibm->acpi->driver->ops.add = &tpacpi_device_add;
593 593
594 rc = acpi_bus_register_driver(ibm->acpi->driver); 594 rc = acpi_bus_register_driver(ibm->acpi->driver);
595 if (rc < 0) { 595 if (rc < 0) {
596 printk(TPACPI_ERR "acpi_bus_register_driver(%s) failed: %d\n", 596 printk(TPACPI_ERR "acpi_bus_register_driver(%s) failed: %d\n",
597 ibm->name, rc); 597 ibm->name, rc);
598 kfree(ibm->acpi->driver); 598 kfree(ibm->acpi->driver);
599 ibm->acpi->driver = NULL; 599 ibm->acpi->driver = NULL;
600 } else if (!rc) 600 } else if (!rc)
601 ibm->flags.acpi_driver_registered = 1; 601 ibm->flags.acpi_driver_registered = 1;
602 602
603 return rc; 603 return rc;
604 } 604 }
605 605
606 606
607 /**************************************************************************** 607 /****************************************************************************
608 **************************************************************************** 608 ****************************************************************************
609 * 609 *
610 * Procfs Helpers 610 * Procfs Helpers
611 * 611 *
612 **************************************************************************** 612 ****************************************************************************
613 ****************************************************************************/ 613 ****************************************************************************/
614 614
615 static int dispatch_procfs_read(char *page, char **start, off_t off, 615 static int dispatch_procfs_read(char *page, char **start, off_t off,
616 int count, int *eof, void *data) 616 int count, int *eof, void *data)
617 { 617 {
618 struct ibm_struct *ibm = data; 618 struct ibm_struct *ibm = data;
619 int len; 619 int len;
620 620
621 if (!ibm || !ibm->read) 621 if (!ibm || !ibm->read)
622 return -EINVAL; 622 return -EINVAL;
623 623
624 len = ibm->read(page); 624 len = ibm->read(page);
625 if (len < 0) 625 if (len < 0)
626 return len; 626 return len;
627 627
628 if (len <= off + count) 628 if (len <= off + count)
629 *eof = 1; 629 *eof = 1;
630 *start = page + off; 630 *start = page + off;
631 len -= off; 631 len -= off;
632 if (len > count) 632 if (len > count)
633 len = count; 633 len = count;
634 if (len < 0) 634 if (len < 0)
635 len = 0; 635 len = 0;
636 636
637 return len; 637 return len;
638 } 638 }
639 639
640 static int dispatch_procfs_write(struct file *file, 640 static int dispatch_procfs_write(struct file *file,
641 const char __user *userbuf, 641 const char __user *userbuf,
642 unsigned long count, void *data) 642 unsigned long count, void *data)
643 { 643 {
644 struct ibm_struct *ibm = data; 644 struct ibm_struct *ibm = data;
645 char *kernbuf; 645 char *kernbuf;
646 int ret; 646 int ret;
647 647
648 if (!ibm || !ibm->write) 648 if (!ibm || !ibm->write)
649 return -EINVAL; 649 return -EINVAL;
650 650
651 kernbuf = kmalloc(count + 2, GFP_KERNEL); 651 kernbuf = kmalloc(count + 2, GFP_KERNEL);
652 if (!kernbuf) 652 if (!kernbuf)
653 return -ENOMEM; 653 return -ENOMEM;
654 654
655 if (copy_from_user(kernbuf, userbuf, count)) { 655 if (copy_from_user(kernbuf, userbuf, count)) {
656 kfree(kernbuf); 656 kfree(kernbuf);
657 return -EFAULT; 657 return -EFAULT;
658 } 658 }
659 659
660 kernbuf[count] = 0; 660 kernbuf[count] = 0;
661 strcat(kernbuf, ","); 661 strcat(kernbuf, ",");
662 ret = ibm->write(kernbuf); 662 ret = ibm->write(kernbuf);
663 if (ret == 0) 663 if (ret == 0)
664 ret = count; 664 ret = count;
665 665
666 kfree(kernbuf); 666 kfree(kernbuf);
667 667
668 return ret; 668 return ret;
669 } 669 }
670 670
671 static char *next_cmd(char **cmds) 671 static char *next_cmd(char **cmds)
672 { 672 {
673 char *start = *cmds; 673 char *start = *cmds;
674 char *end; 674 char *end;
675 675
676 while ((end = strchr(start, ',')) && end == start) 676 while ((end = strchr(start, ',')) && end == start)
677 start = end + 1; 677 start = end + 1;
678 678
679 if (!end) 679 if (!end)
680 return NULL; 680 return NULL;
681 681
682 *end = 0; 682 *end = 0;
683 *cmds = end + 1; 683 *cmds = end + 1;
684 return start; 684 return start;
685 } 685 }
686 686
687 687
688 /**************************************************************************** 688 /****************************************************************************
689 **************************************************************************** 689 ****************************************************************************
690 * 690 *
691 * Device model: input, hwmon and platform 691 * Device model: input, hwmon and platform
692 * 692 *
693 **************************************************************************** 693 ****************************************************************************
694 ****************************************************************************/ 694 ****************************************************************************/
695 695
696 static struct platform_device *tpacpi_pdev; 696 static struct platform_device *tpacpi_pdev;
697 static struct platform_device *tpacpi_sensors_pdev; 697 static struct platform_device *tpacpi_sensors_pdev;
698 static struct device *tpacpi_hwmon; 698 static struct device *tpacpi_hwmon;
699 static struct input_dev *tpacpi_inputdev; 699 static struct input_dev *tpacpi_inputdev;
700 static struct mutex tpacpi_inputdev_send_mutex; 700 static struct mutex tpacpi_inputdev_send_mutex;
701 static LIST_HEAD(tpacpi_all_drivers); 701 static LIST_HEAD(tpacpi_all_drivers);
702 702
703 static int tpacpi_suspend_handler(struct platform_device *pdev, 703 static int tpacpi_suspend_handler(struct platform_device *pdev,
704 pm_message_t state) 704 pm_message_t state)
705 { 705 {
706 struct ibm_struct *ibm, *itmp; 706 struct ibm_struct *ibm, *itmp;
707 707
708 list_for_each_entry_safe(ibm, itmp, 708 list_for_each_entry_safe(ibm, itmp,
709 &tpacpi_all_drivers, 709 &tpacpi_all_drivers,
710 all_drivers) { 710 all_drivers) {
711 if (ibm->suspend) 711 if (ibm->suspend)
712 (ibm->suspend)(state); 712 (ibm->suspend)(state);
713 } 713 }
714 714
715 return 0; 715 return 0;
716 } 716 }
717 717
718 static int tpacpi_resume_handler(struct platform_device *pdev) 718 static int tpacpi_resume_handler(struct platform_device *pdev)
719 { 719 {
720 struct ibm_struct *ibm, *itmp; 720 struct ibm_struct *ibm, *itmp;
721 721
722 list_for_each_entry_safe(ibm, itmp, 722 list_for_each_entry_safe(ibm, itmp,
723 &tpacpi_all_drivers, 723 &tpacpi_all_drivers,
724 all_drivers) { 724 all_drivers) {
725 if (ibm->resume) 725 if (ibm->resume)
726 (ibm->resume)(); 726 (ibm->resume)();
727 } 727 }
728 728
729 return 0; 729 return 0;
730 } 730 }
731 731
732 static struct platform_driver tpacpi_pdriver = { 732 static struct platform_driver tpacpi_pdriver = {
733 .driver = { 733 .driver = {
734 .name = TPACPI_DRVR_NAME, 734 .name = TPACPI_DRVR_NAME,
735 .owner = THIS_MODULE, 735 .owner = THIS_MODULE,
736 }, 736 },
737 .suspend = tpacpi_suspend_handler, 737 .suspend = tpacpi_suspend_handler,
738 .resume = tpacpi_resume_handler, 738 .resume = tpacpi_resume_handler,
739 }; 739 };
740 740
741 static struct platform_driver tpacpi_hwmon_pdriver = { 741 static struct platform_driver tpacpi_hwmon_pdriver = {
742 .driver = { 742 .driver = {
743 .name = TPACPI_HWMON_DRVR_NAME, 743 .name = TPACPI_HWMON_DRVR_NAME,
744 .owner = THIS_MODULE, 744 .owner = THIS_MODULE,
745 }, 745 },
746 }; 746 };
747 747
748 /************************************************************************* 748 /*************************************************************************
749 * sysfs support helpers 749 * sysfs support helpers
750 */ 750 */
751 751
752 struct attribute_set { 752 struct attribute_set {
753 unsigned int members, max_members; 753 unsigned int members, max_members;
754 struct attribute_group group; 754 struct attribute_group group;
755 }; 755 };
756 756
757 struct attribute_set_obj { 757 struct attribute_set_obj {
758 struct attribute_set s; 758 struct attribute_set s;
759 struct attribute *a; 759 struct attribute *a;
760 } __attribute__((packed)); 760 } __attribute__((packed));
761 761
762 static struct attribute_set *create_attr_set(unsigned int max_members, 762 static struct attribute_set *create_attr_set(unsigned int max_members,
763 const char *name) 763 const char *name)
764 { 764 {
765 struct attribute_set_obj *sobj; 765 struct attribute_set_obj *sobj;
766 766
767 if (max_members == 0) 767 if (max_members == 0)
768 return NULL; 768 return NULL;
769 769
770 /* Allocates space for implicit NULL at the end too */ 770 /* Allocates space for implicit NULL at the end too */
771 sobj = kzalloc(sizeof(struct attribute_set_obj) + 771 sobj = kzalloc(sizeof(struct attribute_set_obj) +
772 max_members * sizeof(struct attribute *), 772 max_members * sizeof(struct attribute *),
773 GFP_KERNEL); 773 GFP_KERNEL);
774 if (!sobj) 774 if (!sobj)
775 return NULL; 775 return NULL;
776 sobj->s.max_members = max_members; 776 sobj->s.max_members = max_members;
777 sobj->s.group.attrs = &sobj->a; 777 sobj->s.group.attrs = &sobj->a;
778 sobj->s.group.name = name; 778 sobj->s.group.name = name;
779 779
780 return &sobj->s; 780 return &sobj->s;
781 } 781 }
782 782
783 #define destroy_attr_set(_set) \ 783 #define destroy_attr_set(_set) \
784 kfree(_set); 784 kfree(_set);
785 785
786 /* not multi-threaded safe, use it in a single thread per set */ 786 /* not multi-threaded safe, use it in a single thread per set */
787 static int add_to_attr_set(struct attribute_set *s, struct attribute *attr) 787 static int add_to_attr_set(struct attribute_set *s, struct attribute *attr)
788 { 788 {
789 if (!s || !attr) 789 if (!s || !attr)
790 return -EINVAL; 790 return -EINVAL;
791 791
792 if (s->members >= s->max_members) 792 if (s->members >= s->max_members)
793 return -ENOMEM; 793 return -ENOMEM;
794 794
795 s->group.attrs[s->members] = attr; 795 s->group.attrs[s->members] = attr;
796 s->members++; 796 s->members++;
797 797
798 return 0; 798 return 0;
799 } 799 }
800 800
801 static int add_many_to_attr_set(struct attribute_set *s, 801 static int add_many_to_attr_set(struct attribute_set *s,
802 struct attribute **attr, 802 struct attribute **attr,
803 unsigned int count) 803 unsigned int count)
804 { 804 {
805 int i, res; 805 int i, res;
806 806
807 for (i = 0; i < count; i++) { 807 for (i = 0; i < count; i++) {
808 res = add_to_attr_set(s, attr[i]); 808 res = add_to_attr_set(s, attr[i]);
809 if (res) 809 if (res)
810 return res; 810 return res;
811 } 811 }
812 812
813 return 0; 813 return 0;
814 } 814 }
815 815
816 static void delete_attr_set(struct attribute_set *s, struct kobject *kobj) 816 static void delete_attr_set(struct attribute_set *s, struct kobject *kobj)
817 { 817 {
818 sysfs_remove_group(kobj, &s->group); 818 sysfs_remove_group(kobj, &s->group);
819 destroy_attr_set(s); 819 destroy_attr_set(s);
820 } 820 }
821 821
822 #define register_attr_set_with_sysfs(_attr_set, _kobj) \ 822 #define register_attr_set_with_sysfs(_attr_set, _kobj) \
823 sysfs_create_group(_kobj, &_attr_set->group) 823 sysfs_create_group(_kobj, &_attr_set->group)
824 824
825 static int parse_strtoul(const char *buf, 825 static int parse_strtoul(const char *buf,
826 unsigned long max, unsigned long *value) 826 unsigned long max, unsigned long *value)
827 { 827 {
828 char *endp; 828 char *endp;
829 829
830 while (*buf && isspace(*buf)) 830 while (*buf && isspace(*buf))
831 buf++; 831 buf++;
832 *value = simple_strtoul(buf, &endp, 0); 832 *value = simple_strtoul(buf, &endp, 0);
833 while (*endp && isspace(*endp)) 833 while (*endp && isspace(*endp))
834 endp++; 834 endp++;
835 if (*endp || *value > max) 835 if (*endp || *value > max)
836 return -EINVAL; 836 return -EINVAL;
837 837
838 return 0; 838 return 0;
839 } 839 }
840 840
841 static void tpacpi_disable_brightness_delay(void) 841 static void tpacpi_disable_brightness_delay(void)
842 { 842 {
843 if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0)) 843 if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0))
844 printk(TPACPI_NOTICE 844 printk(TPACPI_NOTICE
845 "ACPI backlight control delay disabled\n"); 845 "ACPI backlight control delay disabled\n");
846 } 846 }
847 847
848 static int __init tpacpi_query_bcl_levels(acpi_handle handle) 848 static int __init tpacpi_query_bcl_levels(acpi_handle handle)
849 { 849 {
850 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 850 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
851 union acpi_object *obj; 851 union acpi_object *obj;
852 int rc; 852 int rc;
853 853
854 if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { 854 if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
855 obj = (union acpi_object *)buffer.pointer; 855 obj = (union acpi_object *)buffer.pointer;
856 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { 856 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
857 printk(TPACPI_ERR "Unknown _BCL data, " 857 printk(TPACPI_ERR "Unknown _BCL data, "
858 "please report this to %s\n", TPACPI_MAIL); 858 "please report this to %s\n", TPACPI_MAIL);
859 rc = 0; 859 rc = 0;
860 } else { 860 } else {
861 rc = obj->package.count; 861 rc = obj->package.count;
862 } 862 }
863 } else { 863 } else {
864 return 0; 864 return 0;
865 } 865 }
866 866
867 kfree(buffer.pointer); 867 kfree(buffer.pointer);
868 return rc; 868 return rc;
869 } 869 }
870 870
871 static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle, 871 static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
872 u32 lvl, void *context, void **rv) 872 u32 lvl, void *context, void **rv)
873 { 873 {
874 char name[ACPI_PATH_SEGMENT_LENGTH]; 874 char name[ACPI_PATH_SEGMENT_LENGTH];
875 struct acpi_buffer buffer = { sizeof(name), &name }; 875 struct acpi_buffer buffer = { sizeof(name), &name };
876 876
877 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && 877 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
878 !strncmp("_BCL", name, sizeof(name) - 1)) { 878 !strncmp("_BCL", name, sizeof(name) - 1)) {
879 BUG_ON(!rv || !*rv); 879 BUG_ON(!rv || !*rv);
880 **(int **)rv = tpacpi_query_bcl_levels(handle); 880 **(int **)rv = tpacpi_query_bcl_levels(handle);
881 return AE_CTRL_TERMINATE; 881 return AE_CTRL_TERMINATE;
882 } else { 882 } else {
883 return AE_OK; 883 return AE_OK;
884 } 884 }
885 } 885 }
886 886
887 /* 887 /*
888 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map 888 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
889 */ 889 */
890 static int __init tpacpi_check_std_acpi_brightness_support(void) 890 static int __init tpacpi_check_std_acpi_brightness_support(void)
891 { 891 {
892 int status; 892 int status;
893 int bcl_levels = 0; 893 int bcl_levels = 0;
894 void *bcl_ptr = &bcl_levels; 894 void *bcl_ptr = &bcl_levels;
895 895
896 if (!vid_handle) { 896 if (!vid_handle) {
897 TPACPI_ACPIHANDLE_INIT(vid); 897 TPACPI_ACPIHANDLE_INIT(vid);
898 } 898 }
899 if (!vid_handle) 899 if (!vid_handle)
900 return 0; 900 return 0;
901 901
902 /* 902 /*
903 * Search for a _BCL method, and execute it. This is safe on all 903 * Search for a _BCL method, and execute it. This is safe on all
904 * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista 904 * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
905 * BIOS in ACPI backlight control mode. We do NOT have to care 905 * BIOS in ACPI backlight control mode. We do NOT have to care
906 * about calling the _BCL method in an enabled video device, any 906 * about calling the _BCL method in an enabled video device, any
907 * will do for our purposes. 907 * will do for our purposes.
908 */ 908 */
909 909
910 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, 910 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
911 tpacpi_acpi_walk_find_bcl, NULL, 911 tpacpi_acpi_walk_find_bcl, NULL,
912 &bcl_ptr); 912 &bcl_ptr);
913 913
914 if (ACPI_SUCCESS(status) && bcl_levels > 2) { 914 if (ACPI_SUCCESS(status) && bcl_levels > 2) {
915 tp_features.bright_acpimode = 1; 915 tp_features.bright_acpimode = 1;
916 return (bcl_levels - 2); 916 return (bcl_levels - 2);
917 } 917 }
918 918
919 return 0; 919 return 0;
920 } 920 }
921 921
922 static int __init tpacpi_new_rfkill(const unsigned int id, 922 static int __init tpacpi_new_rfkill(const unsigned int id,
923 struct rfkill **rfk, 923 struct rfkill **rfk,
924 const enum rfkill_type rfktype, 924 const enum rfkill_type rfktype,
925 const char *name, 925 const char *name,
926 int (*toggle_radio)(void *, enum rfkill_state), 926 int (*toggle_radio)(void *, enum rfkill_state),
927 int (*get_state)(void *, enum rfkill_state *)) 927 int (*get_state)(void *, enum rfkill_state *))
928 { 928 {
929 int res; 929 int res;
930 enum rfkill_state initial_state; 930 enum rfkill_state initial_state;
931 931
932 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); 932 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
933 if (!*rfk) { 933 if (!*rfk) {
934 printk(TPACPI_ERR 934 printk(TPACPI_ERR
935 "failed to allocate memory for rfkill class\n"); 935 "failed to allocate memory for rfkill class\n");
936 return -ENOMEM; 936 return -ENOMEM;
937 } 937 }
938 938
939 (*rfk)->name = name; 939 (*rfk)->name = name;
940 (*rfk)->get_state = get_state; 940 (*rfk)->get_state = get_state;
941 (*rfk)->toggle_radio = toggle_radio; 941 (*rfk)->toggle_radio = toggle_radio;
942 942
943 if (!get_state(NULL, &initial_state)) 943 if (!get_state(NULL, &initial_state))
944 (*rfk)->state = initial_state; 944 (*rfk)->state = initial_state;
945 945
946 res = rfkill_register(*rfk); 946 res = rfkill_register(*rfk);
947 if (res < 0) { 947 if (res < 0) {
948 printk(TPACPI_ERR 948 printk(TPACPI_ERR
949 "failed to register %s rfkill switch: %d\n", 949 "failed to register %s rfkill switch: %d\n",
950 name, res); 950 name, res);
951 rfkill_free(*rfk); 951 rfkill_free(*rfk);
952 *rfk = NULL; 952 *rfk = NULL;
953 return res; 953 return res;
954 } 954 }
955 955
956 return 0; 956 return 0;
957 } 957 }
958 958
959 /************************************************************************* 959 /*************************************************************************
960 * thinkpad-acpi driver attributes 960 * thinkpad-acpi driver attributes
961 */ 961 */
962 962
963 /* interface_version --------------------------------------------------- */ 963 /* interface_version --------------------------------------------------- */
964 static ssize_t tpacpi_driver_interface_version_show( 964 static ssize_t tpacpi_driver_interface_version_show(
965 struct device_driver *drv, 965 struct device_driver *drv,
966 char *buf) 966 char *buf)
967 { 967 {
968 return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION); 968 return snprintf(buf, PAGE_SIZE, "0x%08x\n", TPACPI_SYSFS_VERSION);
969 } 969 }
970 970
971 static DRIVER_ATTR(interface_version, S_IRUGO, 971 static DRIVER_ATTR(interface_version, S_IRUGO,
972 tpacpi_driver_interface_version_show, NULL); 972 tpacpi_driver_interface_version_show, NULL);
973 973
974 /* debug_level --------------------------------------------------------- */ 974 /* debug_level --------------------------------------------------------- */
975 static ssize_t tpacpi_driver_debug_show(struct device_driver *drv, 975 static ssize_t tpacpi_driver_debug_show(struct device_driver *drv,
976 char *buf) 976 char *buf)
977 { 977 {
978 return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level); 978 return snprintf(buf, PAGE_SIZE, "0x%04x\n", dbg_level);
979 } 979 }
980 980
981 static ssize_t tpacpi_driver_debug_store(struct device_driver *drv, 981 static ssize_t tpacpi_driver_debug_store(struct device_driver *drv,
982 const char *buf, size_t count) 982 const char *buf, size_t count)
983 { 983 {
984 unsigned long t; 984 unsigned long t;
985 985
986 if (parse_strtoul(buf, 0xffff, &t)) 986 if (parse_strtoul(buf, 0xffff, &t))
987 return -EINVAL; 987 return -EINVAL;
988 988
989 dbg_level = t; 989 dbg_level = t;
990 990
991 return count; 991 return count;
992 } 992 }
993 993
994 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, 994 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
995 tpacpi_driver_debug_show, tpacpi_driver_debug_store); 995 tpacpi_driver_debug_show, tpacpi_driver_debug_store);
996 996
997 /* version ------------------------------------------------------------- */ 997 /* version ------------------------------------------------------------- */
998 static ssize_t tpacpi_driver_version_show(struct device_driver *drv, 998 static ssize_t tpacpi_driver_version_show(struct device_driver *drv,
999 char *buf) 999 char *buf)
1000 { 1000 {
1001 return snprintf(buf, PAGE_SIZE, "%s v%s\n", 1001 return snprintf(buf, PAGE_SIZE, "%s v%s\n",
1002 TPACPI_DESC, TPACPI_VERSION); 1002 TPACPI_DESC, TPACPI_VERSION);
1003 } 1003 }
1004 1004
1005 static DRIVER_ATTR(version, S_IRUGO, 1005 static DRIVER_ATTR(version, S_IRUGO,
1006 tpacpi_driver_version_show, NULL); 1006 tpacpi_driver_version_show, NULL);
1007 1007
1008 /* --------------------------------------------------------------------- */ 1008 /* --------------------------------------------------------------------- */
1009 1009
1010 static struct driver_attribute *tpacpi_driver_attributes[] = { 1010 static struct driver_attribute *tpacpi_driver_attributes[] = {
1011 &driver_attr_debug_level, &driver_attr_version, 1011 &driver_attr_debug_level, &driver_attr_version,
1012 &driver_attr_interface_version, 1012 &driver_attr_interface_version,
1013 }; 1013 };
1014 1014
1015 static int __init tpacpi_create_driver_attributes(struct device_driver *drv) 1015 static int __init tpacpi_create_driver_attributes(struct device_driver *drv)
1016 { 1016 {
1017 int i, res; 1017 int i, res;
1018 1018
1019 i = 0; 1019 i = 0;
1020 res = 0; 1020 res = 0;
1021 while (!res && i < ARRAY_SIZE(tpacpi_driver_attributes)) { 1021 while (!res && i < ARRAY_SIZE(tpacpi_driver_attributes)) {
1022 res = driver_create_file(drv, tpacpi_driver_attributes[i]); 1022 res = driver_create_file(drv, tpacpi_driver_attributes[i]);
1023 i++; 1023 i++;
1024 } 1024 }
1025 1025
1026 return res; 1026 return res;
1027 } 1027 }
1028 1028
1029 static void tpacpi_remove_driver_attributes(struct device_driver *drv) 1029 static void tpacpi_remove_driver_attributes(struct device_driver *drv)
1030 { 1030 {
1031 int i; 1031 int i;
1032 1032
1033 for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++) 1033 for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++)
1034 driver_remove_file(drv, tpacpi_driver_attributes[i]); 1034 driver_remove_file(drv, tpacpi_driver_attributes[i]);
1035 } 1035 }
1036 1036
1037 /**************************************************************************** 1037 /****************************************************************************
1038 **************************************************************************** 1038 ****************************************************************************
1039 * 1039 *
1040 * Subdrivers 1040 * Subdrivers
1041 * 1041 *
1042 **************************************************************************** 1042 ****************************************************************************
1043 ****************************************************************************/ 1043 ****************************************************************************/
1044 1044
1045 /************************************************************************* 1045 /*************************************************************************
1046 * thinkpad-acpi init subdriver 1046 * thinkpad-acpi init subdriver
1047 */ 1047 */
1048 1048
1049 static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) 1049 static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
1050 { 1050 {
1051 printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION); 1051 printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION);
1052 printk(TPACPI_INFO "%s\n", TPACPI_URL); 1052 printk(TPACPI_INFO "%s\n", TPACPI_URL);
1053 1053
1054 printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n", 1054 printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n",
1055 (thinkpad_id.bios_version_str) ? 1055 (thinkpad_id.bios_version_str) ?
1056 thinkpad_id.bios_version_str : "unknown", 1056 thinkpad_id.bios_version_str : "unknown",
1057 (thinkpad_id.ec_version_str) ? 1057 (thinkpad_id.ec_version_str) ?
1058 thinkpad_id.ec_version_str : "unknown"); 1058 thinkpad_id.ec_version_str : "unknown");
1059 1059
1060 if (thinkpad_id.vendor && thinkpad_id.model_str) 1060 if (thinkpad_id.vendor && thinkpad_id.model_str)
1061 printk(TPACPI_INFO "%s %s, model %s\n", 1061 printk(TPACPI_INFO "%s %s, model %s\n",
1062 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? 1062 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
1063 "IBM" : ((thinkpad_id.vendor == 1063 "IBM" : ((thinkpad_id.vendor ==
1064 PCI_VENDOR_ID_LENOVO) ? 1064 PCI_VENDOR_ID_LENOVO) ?
1065 "Lenovo" : "Unknown vendor"), 1065 "Lenovo" : "Unknown vendor"),
1066 thinkpad_id.model_str, 1066 thinkpad_id.model_str,
1067 (thinkpad_id.nummodel_str) ? 1067 (thinkpad_id.nummodel_str) ?
1068 thinkpad_id.nummodel_str : "unknown"); 1068 thinkpad_id.nummodel_str : "unknown");
1069 1069
1070 return 0; 1070 return 0;
1071 } 1071 }
1072 1072
1073 static int thinkpad_acpi_driver_read(char *p) 1073 static int thinkpad_acpi_driver_read(char *p)
1074 { 1074 {
1075 int len = 0; 1075 int len = 0;
1076 1076
1077 len += sprintf(p + len, "driver:\t\t%s\n", TPACPI_DESC); 1077 len += sprintf(p + len, "driver:\t\t%s\n", TPACPI_DESC);
1078 len += sprintf(p + len, "version:\t%s\n", TPACPI_VERSION); 1078 len += sprintf(p + len, "version:\t%s\n", TPACPI_VERSION);
1079 1079
1080 return len; 1080 return len;
1081 } 1081 }
1082 1082
1083 static struct ibm_struct thinkpad_acpi_driver_data = { 1083 static struct ibm_struct thinkpad_acpi_driver_data = {
1084 .name = "driver", 1084 .name = "driver",
1085 .read = thinkpad_acpi_driver_read, 1085 .read = thinkpad_acpi_driver_read,
1086 }; 1086 };
1087 1087
1088 /************************************************************************* 1088 /*************************************************************************
1089 * Hotkey subdriver 1089 * Hotkey subdriver
1090 */ 1090 */
1091 1091
1092 enum { /* hot key scan codes (derived from ACPI DSDT) */ 1092 enum { /* hot key scan codes (derived from ACPI DSDT) */
1093 TP_ACPI_HOTKEYSCAN_FNF1 = 0, 1093 TP_ACPI_HOTKEYSCAN_FNF1 = 0,
1094 TP_ACPI_HOTKEYSCAN_FNF2, 1094 TP_ACPI_HOTKEYSCAN_FNF2,
1095 TP_ACPI_HOTKEYSCAN_FNF3, 1095 TP_ACPI_HOTKEYSCAN_FNF3,
1096 TP_ACPI_HOTKEYSCAN_FNF4, 1096 TP_ACPI_HOTKEYSCAN_FNF4,
1097 TP_ACPI_HOTKEYSCAN_FNF5, 1097 TP_ACPI_HOTKEYSCAN_FNF5,
1098 TP_ACPI_HOTKEYSCAN_FNF6, 1098 TP_ACPI_HOTKEYSCAN_FNF6,
1099 TP_ACPI_HOTKEYSCAN_FNF7, 1099 TP_ACPI_HOTKEYSCAN_FNF7,
1100 TP_ACPI_HOTKEYSCAN_FNF8, 1100 TP_ACPI_HOTKEYSCAN_FNF8,
1101 TP_ACPI_HOTKEYSCAN_FNF9, 1101 TP_ACPI_HOTKEYSCAN_FNF9,
1102 TP_ACPI_HOTKEYSCAN_FNF10, 1102 TP_ACPI_HOTKEYSCAN_FNF10,
1103 TP_ACPI_HOTKEYSCAN_FNF11, 1103 TP_ACPI_HOTKEYSCAN_FNF11,
1104 TP_ACPI_HOTKEYSCAN_FNF12, 1104 TP_ACPI_HOTKEYSCAN_FNF12,
1105 TP_ACPI_HOTKEYSCAN_FNBACKSPACE, 1105 TP_ACPI_HOTKEYSCAN_FNBACKSPACE,
1106 TP_ACPI_HOTKEYSCAN_FNINSERT, 1106 TP_ACPI_HOTKEYSCAN_FNINSERT,
1107 TP_ACPI_HOTKEYSCAN_FNDELETE, 1107 TP_ACPI_HOTKEYSCAN_FNDELETE,
1108 TP_ACPI_HOTKEYSCAN_FNHOME, 1108 TP_ACPI_HOTKEYSCAN_FNHOME,
1109 TP_ACPI_HOTKEYSCAN_FNEND, 1109 TP_ACPI_HOTKEYSCAN_FNEND,
1110 TP_ACPI_HOTKEYSCAN_FNPAGEUP, 1110 TP_ACPI_HOTKEYSCAN_FNPAGEUP,
1111 TP_ACPI_HOTKEYSCAN_FNPAGEDOWN, 1111 TP_ACPI_HOTKEYSCAN_FNPAGEDOWN,
1112 TP_ACPI_HOTKEYSCAN_FNSPACE, 1112 TP_ACPI_HOTKEYSCAN_FNSPACE,
1113 TP_ACPI_HOTKEYSCAN_VOLUMEUP, 1113 TP_ACPI_HOTKEYSCAN_VOLUMEUP,
1114 TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, 1114 TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,
1115 TP_ACPI_HOTKEYSCAN_MUTE, 1115 TP_ACPI_HOTKEYSCAN_MUTE,
1116 TP_ACPI_HOTKEYSCAN_THINKPAD, 1116 TP_ACPI_HOTKEYSCAN_THINKPAD,
1117 }; 1117 };
1118 1118
1119 enum { /* Keys available through NVRAM polling */ 1119 enum { /* Keys available through NVRAM polling */
1120 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U, 1120 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U,
1121 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U, 1121 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U,
1122 }; 1122 };
1123 1123
1124 enum { /* Positions of some of the keys in hotkey masks */ 1124 enum { /* Positions of some of the keys in hotkey masks */
1125 TP_ACPI_HKEY_DISPSWTCH_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF7, 1125 TP_ACPI_HKEY_DISPSWTCH_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF7,
1126 TP_ACPI_HKEY_DISPXPAND_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF8, 1126 TP_ACPI_HKEY_DISPXPAND_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF8,
1127 TP_ACPI_HKEY_HIBERNATE_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF12, 1127 TP_ACPI_HKEY_HIBERNATE_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNF12,
1128 TP_ACPI_HKEY_BRGHTUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNHOME, 1128 TP_ACPI_HKEY_BRGHTUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNHOME,
1129 TP_ACPI_HKEY_BRGHTDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNEND, 1129 TP_ACPI_HKEY_BRGHTDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNEND,
1130 TP_ACPI_HKEY_THNKLGHT_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNPAGEUP, 1130 TP_ACPI_HKEY_THNKLGHT_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNPAGEUP,
1131 TP_ACPI_HKEY_ZOOM_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNSPACE, 1131 TP_ACPI_HKEY_ZOOM_MASK = 1 << TP_ACPI_HOTKEYSCAN_FNSPACE,
1132 TP_ACPI_HKEY_VOLUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEUP, 1132 TP_ACPI_HKEY_VOLUP_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEUP,
1133 TP_ACPI_HKEY_VOLDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, 1133 TP_ACPI_HKEY_VOLDWN_MASK = 1 << TP_ACPI_HOTKEYSCAN_VOLUMEDOWN,
1134 TP_ACPI_HKEY_MUTE_MASK = 1 << TP_ACPI_HOTKEYSCAN_MUTE, 1134 TP_ACPI_HKEY_MUTE_MASK = 1 << TP_ACPI_HOTKEYSCAN_MUTE,
1135 TP_ACPI_HKEY_THINKPAD_MASK = 1 << TP_ACPI_HOTKEYSCAN_THINKPAD, 1135 TP_ACPI_HKEY_THINKPAD_MASK = 1 << TP_ACPI_HOTKEYSCAN_THINKPAD,
1136 }; 1136 };
1137 1137
1138 enum { /* NVRAM to ACPI HKEY group map */ 1138 enum { /* NVRAM to ACPI HKEY group map */
1139 TP_NVRAM_HKEY_GROUP_HK2 = TP_ACPI_HKEY_THINKPAD_MASK | 1139 TP_NVRAM_HKEY_GROUP_HK2 = TP_ACPI_HKEY_THINKPAD_MASK |
1140 TP_ACPI_HKEY_ZOOM_MASK | 1140 TP_ACPI_HKEY_ZOOM_MASK |
1141 TP_ACPI_HKEY_DISPSWTCH_MASK | 1141 TP_ACPI_HKEY_DISPSWTCH_MASK |
1142 TP_ACPI_HKEY_HIBERNATE_MASK, 1142 TP_ACPI_HKEY_HIBERNATE_MASK,
1143 TP_NVRAM_HKEY_GROUP_BRIGHTNESS = TP_ACPI_HKEY_BRGHTUP_MASK | 1143 TP_NVRAM_HKEY_GROUP_BRIGHTNESS = TP_ACPI_HKEY_BRGHTUP_MASK |
1144 TP_ACPI_HKEY_BRGHTDWN_MASK, 1144 TP_ACPI_HKEY_BRGHTDWN_MASK,
1145 TP_NVRAM_HKEY_GROUP_VOLUME = TP_ACPI_HKEY_VOLUP_MASK | 1145 TP_NVRAM_HKEY_GROUP_VOLUME = TP_ACPI_HKEY_VOLUP_MASK |
1146 TP_ACPI_HKEY_VOLDWN_MASK | 1146 TP_ACPI_HKEY_VOLDWN_MASK |
1147 TP_ACPI_HKEY_MUTE_MASK, 1147 TP_ACPI_HKEY_MUTE_MASK,
1148 }; 1148 };
1149 1149
1150 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1150 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1151 struct tp_nvram_state { 1151 struct tp_nvram_state {
1152 u16 thinkpad_toggle:1; 1152 u16 thinkpad_toggle:1;
1153 u16 zoom_toggle:1; 1153 u16 zoom_toggle:1;
1154 u16 display_toggle:1; 1154 u16 display_toggle:1;
1155 u16 thinklight_toggle:1; 1155 u16 thinklight_toggle:1;
1156 u16 hibernate_toggle:1; 1156 u16 hibernate_toggle:1;
1157 u16 displayexp_toggle:1; 1157 u16 displayexp_toggle:1;
1158 u16 display_state:1; 1158 u16 display_state:1;
1159 u16 brightness_toggle:1; 1159 u16 brightness_toggle:1;
1160 u16 volume_toggle:1; 1160 u16 volume_toggle:1;
1161 u16 mute:1; 1161 u16 mute:1;
1162 1162
1163 u8 brightness_level; 1163 u8 brightness_level;
1164 u8 volume_level; 1164 u8 volume_level;
1165 }; 1165 };
1166 1166
1167 static struct task_struct *tpacpi_hotkey_task; 1167 static struct task_struct *tpacpi_hotkey_task;
1168 static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */ 1168 static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */
1169 static int hotkey_poll_freq = 10; /* Hz */ 1169 static int hotkey_poll_freq = 10; /* Hz */
1170 static struct mutex hotkey_thread_mutex; 1170 static struct mutex hotkey_thread_mutex;
1171 static struct mutex hotkey_thread_data_mutex; 1171 static struct mutex hotkey_thread_data_mutex;
1172 static unsigned int hotkey_config_change; 1172 static unsigned int hotkey_config_change;
1173 1173
1174 #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1174 #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1175 1175
1176 #define hotkey_source_mask 0U 1176 #define hotkey_source_mask 0U
1177 1177
1178 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1178 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1179 1179
1180 static struct mutex hotkey_mutex; 1180 static struct mutex hotkey_mutex;
1181 1181
1182 static enum { /* Reasons for waking up */ 1182 static enum { /* Reasons for waking up */
1183 TP_ACPI_WAKEUP_NONE = 0, /* None or unknown */ 1183 TP_ACPI_WAKEUP_NONE = 0, /* None or unknown */
1184 TP_ACPI_WAKEUP_BAYEJ, /* Bay ejection request */ 1184 TP_ACPI_WAKEUP_BAYEJ, /* Bay ejection request */
1185 TP_ACPI_WAKEUP_UNDOCK, /* Undock request */ 1185 TP_ACPI_WAKEUP_UNDOCK, /* Undock request */
1186 } hotkey_wakeup_reason; 1186 } hotkey_wakeup_reason;
1187 1187
1188 static int hotkey_autosleep_ack; 1188 static int hotkey_autosleep_ack;
1189 1189
1190 static int hotkey_orig_status; 1190 static int hotkey_orig_status;
1191 static u32 hotkey_orig_mask; 1191 static u32 hotkey_orig_mask;
1192 static u32 hotkey_all_mask; 1192 static u32 hotkey_all_mask;
1193 static u32 hotkey_reserved_mask; 1193 static u32 hotkey_reserved_mask;
1194 static u32 hotkey_mask; 1194 static u32 hotkey_mask;
1195 1195
1196 static unsigned int hotkey_report_mode; 1196 static unsigned int hotkey_report_mode;
1197 1197
1198 static u16 *hotkey_keycode_map; 1198 static u16 *hotkey_keycode_map;
1199 1199
1200 static struct attribute_set *hotkey_dev_attributes; 1200 static struct attribute_set *hotkey_dev_attributes;
1201 1201
1202 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1202 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1203 #define HOTKEY_CONFIG_CRITICAL_START \ 1203 #define HOTKEY_CONFIG_CRITICAL_START \
1204 do { \ 1204 do { \
1205 mutex_lock(&hotkey_thread_data_mutex); \ 1205 mutex_lock(&hotkey_thread_data_mutex); \
1206 hotkey_config_change++; \ 1206 hotkey_config_change++; \
1207 } while (0); 1207 } while (0);
1208 #define HOTKEY_CONFIG_CRITICAL_END \ 1208 #define HOTKEY_CONFIG_CRITICAL_END \
1209 mutex_unlock(&hotkey_thread_data_mutex); 1209 mutex_unlock(&hotkey_thread_data_mutex);
1210 #else 1210 #else
1211 #define HOTKEY_CONFIG_CRITICAL_START 1211 #define HOTKEY_CONFIG_CRITICAL_START
1212 #define HOTKEY_CONFIG_CRITICAL_END 1212 #define HOTKEY_CONFIG_CRITICAL_END
1213 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1213 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1214 1214
1215 /* HKEY.MHKG() return bits */ 1215 /* HKEY.MHKG() return bits */
1216 #define TP_HOTKEY_TABLET_MASK (1 << 3) 1216 #define TP_HOTKEY_TABLET_MASK (1 << 3)
1217 1217
1218 static int hotkey_get_wlsw(int *status) 1218 static int hotkey_get_wlsw(int *status)
1219 { 1219 {
1220 if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) 1220 if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
1221 return -EIO; 1221 return -EIO;
1222 return 0; 1222 return 0;
1223 } 1223 }
1224 1224
1225 static int hotkey_get_tablet_mode(int *status) 1225 static int hotkey_get_tablet_mode(int *status)
1226 { 1226 {
1227 int s; 1227 int s;
1228 1228
1229 if (!acpi_evalf(hkey_handle, &s, "MHKG", "d")) 1229 if (!acpi_evalf(hkey_handle, &s, "MHKG", "d"))
1230 return -EIO; 1230 return -EIO;
1231 1231
1232 *status = ((s & TP_HOTKEY_TABLET_MASK) != 0); 1232 *status = ((s & TP_HOTKEY_TABLET_MASK) != 0);
1233 return 0; 1233 return 0;
1234 } 1234 }
1235 1235
1236 /* 1236 /*
1237 * Call with hotkey_mutex held 1237 * Call with hotkey_mutex held
1238 */ 1238 */
1239 static int hotkey_mask_get(void) 1239 static int hotkey_mask_get(void)
1240 { 1240 {
1241 u32 m = 0; 1241 u32 m = 0;
1242 1242
1243 if (tp_features.hotkey_mask) { 1243 if (tp_features.hotkey_mask) {
1244 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d")) 1244 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d"))
1245 return -EIO; 1245 return -EIO;
1246 } 1246 }
1247 hotkey_mask = m | (hotkey_source_mask & hotkey_mask); 1247 hotkey_mask = m | (hotkey_source_mask & hotkey_mask);
1248 1248
1249 return 0; 1249 return 0;
1250 } 1250 }
1251 1251
1252 /* 1252 /*
1253 * Call with hotkey_mutex held 1253 * Call with hotkey_mutex held
1254 */ 1254 */
1255 static int hotkey_mask_set(u32 mask) 1255 static int hotkey_mask_set(u32 mask)
1256 { 1256 {
1257 int i; 1257 int i;
1258 int rc = 0; 1258 int rc = 0;
1259 1259
1260 if (tp_features.hotkey_mask) { 1260 if (tp_features.hotkey_mask) {
1261 if (!tp_warned.hotkey_mask_ff && 1261 if (!tp_warned.hotkey_mask_ff &&
1262 (mask == 0xffff || mask == 0xffffff || 1262 (mask == 0xffff || mask == 0xffffff ||
1263 mask == 0xffffffff)) { 1263 mask == 0xffffffff)) {
1264 tp_warned.hotkey_mask_ff = 1; 1264 tp_warned.hotkey_mask_ff = 1;
1265 printk(TPACPI_NOTICE 1265 printk(TPACPI_NOTICE
1266 "setting the hotkey mask to 0x%08x is likely " 1266 "setting the hotkey mask to 0x%08x is likely "
1267 "not the best way to go about it\n", mask); 1267 "not the best way to go about it\n", mask);
1268 printk(TPACPI_NOTICE 1268 printk(TPACPI_NOTICE
1269 "please consider using the driver defaults, " 1269 "please consider using the driver defaults, "
1270 "and refer to up-to-date thinkpad-acpi " 1270 "and refer to up-to-date thinkpad-acpi "
1271 "documentation\n"); 1271 "documentation\n");
1272 } 1272 }
1273 1273
1274 HOTKEY_CONFIG_CRITICAL_START 1274 HOTKEY_CONFIG_CRITICAL_START
1275 for (i = 0; i < 32; i++) { 1275 for (i = 0; i < 32; i++) {
1276 u32 m = 1 << i; 1276 u32 m = 1 << i;
1277 /* enable in firmware mask only keys not in NVRAM 1277 /* enable in firmware mask only keys not in NVRAM
1278 * mode, but enable the key in the cached hotkey_mask 1278 * mode, but enable the key in the cached hotkey_mask
1279 * regardless of mode, or the key will end up 1279 * regardless of mode, or the key will end up
1280 * disabled by hotkey_mask_get() */ 1280 * disabled by hotkey_mask_get() */
1281 if (!acpi_evalf(hkey_handle, 1281 if (!acpi_evalf(hkey_handle,
1282 NULL, "MHKM", "vdd", i + 1, 1282 NULL, "MHKM", "vdd", i + 1,
1283 !!((mask & ~hotkey_source_mask) & m))) { 1283 !!((mask & ~hotkey_source_mask) & m))) {
1284 rc = -EIO; 1284 rc = -EIO;
1285 break; 1285 break;
1286 } else { 1286 } else {
1287 hotkey_mask = (hotkey_mask & ~m) | (mask & m); 1287 hotkey_mask = (hotkey_mask & ~m) | (mask & m);
1288 } 1288 }
1289 } 1289 }
1290 HOTKEY_CONFIG_CRITICAL_END 1290 HOTKEY_CONFIG_CRITICAL_END
1291 1291
1292 /* hotkey_mask_get must be called unconditionally below */ 1292 /* hotkey_mask_get must be called unconditionally below */
1293 if (!hotkey_mask_get() && !rc && 1293 if (!hotkey_mask_get() && !rc &&
1294 (hotkey_mask & ~hotkey_source_mask) != 1294 (hotkey_mask & ~hotkey_source_mask) !=
1295 (mask & ~hotkey_source_mask)) { 1295 (mask & ~hotkey_source_mask)) {
1296 printk(TPACPI_NOTICE 1296 printk(TPACPI_NOTICE
1297 "requested hot key mask 0x%08x, but " 1297 "requested hot key mask 0x%08x, but "
1298 "firmware forced it to 0x%08x\n", 1298 "firmware forced it to 0x%08x\n",
1299 mask, hotkey_mask); 1299 mask, hotkey_mask);
1300 } 1300 }
1301 } else { 1301 } else {
1302 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1302 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1303 HOTKEY_CONFIG_CRITICAL_START 1303 HOTKEY_CONFIG_CRITICAL_START
1304 hotkey_mask = mask & hotkey_source_mask; 1304 hotkey_mask = mask & hotkey_source_mask;
1305 HOTKEY_CONFIG_CRITICAL_END 1305 HOTKEY_CONFIG_CRITICAL_END
1306 hotkey_mask_get(); 1306 hotkey_mask_get();
1307 if (hotkey_mask != mask) { 1307 if (hotkey_mask != mask) {
1308 printk(TPACPI_NOTICE 1308 printk(TPACPI_NOTICE
1309 "requested hot key mask 0x%08x, " 1309 "requested hot key mask 0x%08x, "
1310 "forced to 0x%08x (NVRAM poll mask is " 1310 "forced to 0x%08x (NVRAM poll mask is "
1311 "0x%08x): no firmware mask support\n", 1311 "0x%08x): no firmware mask support\n",
1312 mask, hotkey_mask, hotkey_source_mask); 1312 mask, hotkey_mask, hotkey_source_mask);
1313 } 1313 }
1314 #else 1314 #else
1315 hotkey_mask_get(); 1315 hotkey_mask_get();
1316 rc = -ENXIO; 1316 rc = -ENXIO;
1317 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1317 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1318 } 1318 }
1319 1319
1320 return rc; 1320 return rc;
1321 } 1321 }
1322 1322
1323 static int hotkey_status_get(int *status) 1323 static int hotkey_status_get(int *status)
1324 { 1324 {
1325 if (!acpi_evalf(hkey_handle, status, "DHKC", "d")) 1325 if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
1326 return -EIO; 1326 return -EIO;
1327 1327
1328 return 0; 1328 return 0;
1329 } 1329 }
1330 1330
1331 static int hotkey_status_set(int status) 1331 static int hotkey_status_set(int status)
1332 { 1332 {
1333 if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status)) 1333 if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
1334 return -EIO; 1334 return -EIO;
1335 1335
1336 return 0; 1336 return 0;
1337 } 1337 }
1338 1338
1339 static void tpacpi_input_send_tabletsw(void) 1339 static void tpacpi_input_send_tabletsw(void)
1340 { 1340 {
1341 int state; 1341 int state;
1342 1342
1343 if (tp_features.hotkey_tablet && 1343 if (tp_features.hotkey_tablet &&
1344 !hotkey_get_tablet_mode(&state)) { 1344 !hotkey_get_tablet_mode(&state)) {
1345 mutex_lock(&tpacpi_inputdev_send_mutex); 1345 mutex_lock(&tpacpi_inputdev_send_mutex);
1346 1346
1347 input_report_switch(tpacpi_inputdev, 1347 input_report_switch(tpacpi_inputdev,
1348 SW_TABLET_MODE, !!state); 1348 SW_TABLET_MODE, !!state);
1349 input_sync(tpacpi_inputdev); 1349 input_sync(tpacpi_inputdev);
1350 1350
1351 mutex_unlock(&tpacpi_inputdev_send_mutex); 1351 mutex_unlock(&tpacpi_inputdev_send_mutex);
1352 } 1352 }
1353 } 1353 }
1354 1354
1355 static void tpacpi_input_send_key(unsigned int scancode) 1355 static void tpacpi_input_send_key(unsigned int scancode)
1356 { 1356 {
1357 unsigned int keycode; 1357 unsigned int keycode;
1358 1358
1359 keycode = hotkey_keycode_map[scancode]; 1359 keycode = hotkey_keycode_map[scancode];
1360 1360
1361 if (keycode != KEY_RESERVED) { 1361 if (keycode != KEY_RESERVED) {
1362 mutex_lock(&tpacpi_inputdev_send_mutex); 1362 mutex_lock(&tpacpi_inputdev_send_mutex);
1363 1363
1364 input_report_key(tpacpi_inputdev, keycode, 1); 1364 input_report_key(tpacpi_inputdev, keycode, 1);
1365 if (keycode == KEY_UNKNOWN) 1365 if (keycode == KEY_UNKNOWN)
1366 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, 1366 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
1367 scancode); 1367 scancode);
1368 input_sync(tpacpi_inputdev); 1368 input_sync(tpacpi_inputdev);
1369 1369
1370 input_report_key(tpacpi_inputdev, keycode, 0); 1370 input_report_key(tpacpi_inputdev, keycode, 0);
1371 if (keycode == KEY_UNKNOWN) 1371 if (keycode == KEY_UNKNOWN)
1372 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, 1372 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
1373 scancode); 1373 scancode);
1374 input_sync(tpacpi_inputdev); 1374 input_sync(tpacpi_inputdev);
1375 1375
1376 mutex_unlock(&tpacpi_inputdev_send_mutex); 1376 mutex_unlock(&tpacpi_inputdev_send_mutex);
1377 } 1377 }
1378 } 1378 }
1379 1379
1380 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1380 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1381 static struct tp_acpi_drv_struct ibm_hotkey_acpidriver; 1381 static struct tp_acpi_drv_struct ibm_hotkey_acpidriver;
1382 1382
1383 static void tpacpi_hotkey_send_key(unsigned int scancode) 1383 static void tpacpi_hotkey_send_key(unsigned int scancode)
1384 { 1384 {
1385 tpacpi_input_send_key(scancode); 1385 tpacpi_input_send_key(scancode);
1386 if (hotkey_report_mode < 2) { 1386 if (hotkey_report_mode < 2) {
1387 acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device, 1387 acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device,
1388 0x80, 0x1001 + scancode); 1388 0x80, 0x1001 + scancode);
1389 } 1389 }
1390 } 1390 }
1391 1391
1392 static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m) 1392 static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m)
1393 { 1393 {
1394 u8 d; 1394 u8 d;
1395 1395
1396 if (m & TP_NVRAM_HKEY_GROUP_HK2) { 1396 if (m & TP_NVRAM_HKEY_GROUP_HK2) {
1397 d = nvram_read_byte(TP_NVRAM_ADDR_HK2); 1397 d = nvram_read_byte(TP_NVRAM_ADDR_HK2);
1398 n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD); 1398 n->thinkpad_toggle = !!(d & TP_NVRAM_MASK_HKT_THINKPAD);
1399 n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM); 1399 n->zoom_toggle = !!(d & TP_NVRAM_MASK_HKT_ZOOM);
1400 n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY); 1400 n->display_toggle = !!(d & TP_NVRAM_MASK_HKT_DISPLAY);
1401 n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE); 1401 n->hibernate_toggle = !!(d & TP_NVRAM_MASK_HKT_HIBERNATE);
1402 } 1402 }
1403 if (m & TP_ACPI_HKEY_THNKLGHT_MASK) { 1403 if (m & TP_ACPI_HKEY_THNKLGHT_MASK) {
1404 d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT); 1404 d = nvram_read_byte(TP_NVRAM_ADDR_THINKLIGHT);
1405 n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT); 1405 n->thinklight_toggle = !!(d & TP_NVRAM_MASK_THINKLIGHT);
1406 } 1406 }
1407 if (m & TP_ACPI_HKEY_DISPXPAND_MASK) { 1407 if (m & TP_ACPI_HKEY_DISPXPAND_MASK) {
1408 d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO); 1408 d = nvram_read_byte(TP_NVRAM_ADDR_VIDEO);
1409 n->displayexp_toggle = 1409 n->displayexp_toggle =
1410 !!(d & TP_NVRAM_MASK_HKT_DISPEXPND); 1410 !!(d & TP_NVRAM_MASK_HKT_DISPEXPND);
1411 } 1411 }
1412 if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) { 1412 if (m & TP_NVRAM_HKEY_GROUP_BRIGHTNESS) {
1413 d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS); 1413 d = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
1414 n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) 1414 n->brightness_level = (d & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
1415 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; 1415 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
1416 n->brightness_toggle = 1416 n->brightness_toggle =
1417 !!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS); 1417 !!(d & TP_NVRAM_MASK_HKT_BRIGHTNESS);
1418 } 1418 }
1419 if (m & TP_NVRAM_HKEY_GROUP_VOLUME) { 1419 if (m & TP_NVRAM_HKEY_GROUP_VOLUME) {
1420 d = nvram_read_byte(TP_NVRAM_ADDR_MIXER); 1420 d = nvram_read_byte(TP_NVRAM_ADDR_MIXER);
1421 n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME) 1421 n->volume_level = (d & TP_NVRAM_MASK_LEVEL_VOLUME)
1422 >> TP_NVRAM_POS_LEVEL_VOLUME; 1422 >> TP_NVRAM_POS_LEVEL_VOLUME;
1423 n->mute = !!(d & TP_NVRAM_MASK_MUTE); 1423 n->mute = !!(d & TP_NVRAM_MASK_MUTE);
1424 n->volume_toggle = !!(d & TP_NVRAM_MASK_HKT_VOLUME); 1424 n->volume_toggle = !!(d & TP_NVRAM_MASK_HKT_VOLUME);
1425 } 1425 }
1426 } 1426 }
1427 1427
1428 #define TPACPI_COMPARE_KEY(__scancode, __member) \ 1428 #define TPACPI_COMPARE_KEY(__scancode, __member) \
1429 do { \ 1429 do { \
1430 if ((mask & (1 << __scancode)) && \ 1430 if ((mask & (1 << __scancode)) && \
1431 oldn->__member != newn->__member) \ 1431 oldn->__member != newn->__member) \
1432 tpacpi_hotkey_send_key(__scancode); \ 1432 tpacpi_hotkey_send_key(__scancode); \
1433 } while (0) 1433 } while (0)
1434 1434
1435 #define TPACPI_MAY_SEND_KEY(__scancode) \ 1435 #define TPACPI_MAY_SEND_KEY(__scancode) \
1436 do { if (mask & (1 << __scancode)) \ 1436 do { if (mask & (1 << __scancode)) \
1437 tpacpi_hotkey_send_key(__scancode); } while (0) 1437 tpacpi_hotkey_send_key(__scancode); } while (0)
1438 1438
1439 static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, 1439 static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
1440 struct tp_nvram_state *newn, 1440 struct tp_nvram_state *newn,
1441 u32 mask) 1441 u32 mask)
1442 { 1442 {
1443 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle); 1443 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);
1444 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); 1444 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle);
1445 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle); 1445 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle);
1446 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF12, hibernate_toggle); 1446 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF12, hibernate_toggle);
1447 1447
1448 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNPAGEUP, thinklight_toggle); 1448 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNPAGEUP, thinklight_toggle);
1449 1449
1450 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF8, displayexp_toggle); 1450 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF8, displayexp_toggle);
1451 1451
1452 /* handle volume */ 1452 /* handle volume */
1453 if (oldn->volume_toggle != newn->volume_toggle) { 1453 if (oldn->volume_toggle != newn->volume_toggle) {
1454 if (oldn->mute != newn->mute) { 1454 if (oldn->mute != newn->mute) {
1455 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE); 1455 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE);
1456 } 1456 }
1457 if (oldn->volume_level > newn->volume_level) { 1457 if (oldn->volume_level > newn->volume_level) {
1458 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); 1458 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
1459 } else if (oldn->volume_level < newn->volume_level) { 1459 } else if (oldn->volume_level < newn->volume_level) {
1460 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); 1460 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
1461 } else if (oldn->mute == newn->mute) { 1461 } else if (oldn->mute == newn->mute) {
1462 /* repeated key presses that didn't change state */ 1462 /* repeated key presses that didn't change state */
1463 if (newn->mute) { 1463 if (newn->mute) {
1464 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE); 1464 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE);
1465 } else if (newn->volume_level != 0) { 1465 } else if (newn->volume_level != 0) {
1466 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); 1466 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
1467 } else { 1467 } else {
1468 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); 1468 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
1469 } 1469 }
1470 } 1470 }
1471 } 1471 }
1472 1472
1473 /* handle brightness */ 1473 /* handle brightness */
1474 if (oldn->brightness_toggle != newn->brightness_toggle) { 1474 if (oldn->brightness_toggle != newn->brightness_toggle) {
1475 if (oldn->brightness_level < newn->brightness_level) { 1475 if (oldn->brightness_level < newn->brightness_level) {
1476 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); 1476 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
1477 } else if (oldn->brightness_level > newn->brightness_level) { 1477 } else if (oldn->brightness_level > newn->brightness_level) {
1478 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); 1478 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
1479 } else { 1479 } else {
1480 /* repeated key presses that didn't change state */ 1480 /* repeated key presses that didn't change state */
1481 if (newn->brightness_level != 0) { 1481 if (newn->brightness_level != 0) {
1482 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); 1482 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
1483 } else { 1483 } else {
1484 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); 1484 TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
1485 } 1485 }
1486 } 1486 }
1487 } 1487 }
1488 } 1488 }
1489 1489
1490 #undef TPACPI_COMPARE_KEY 1490 #undef TPACPI_COMPARE_KEY
1491 #undef TPACPI_MAY_SEND_KEY 1491 #undef TPACPI_MAY_SEND_KEY
1492 1492
1493 static int hotkey_kthread(void *data) 1493 static int hotkey_kthread(void *data)
1494 { 1494 {
1495 struct tp_nvram_state s[2]; 1495 struct tp_nvram_state s[2];
1496 u32 mask; 1496 u32 mask;
1497 unsigned int si, so; 1497 unsigned int si, so;
1498 unsigned long t; 1498 unsigned long t;
1499 unsigned int change_detector, must_reset; 1499 unsigned int change_detector, must_reset;
1500 1500
1501 mutex_lock(&hotkey_thread_mutex); 1501 mutex_lock(&hotkey_thread_mutex);
1502 1502
1503 if (tpacpi_lifecycle == TPACPI_LIFE_EXITING) 1503 if (tpacpi_lifecycle == TPACPI_LIFE_EXITING)
1504 goto exit; 1504 goto exit;
1505 1505
1506 set_freezable(); 1506 set_freezable();
1507 1507
1508 so = 0; 1508 so = 0;
1509 si = 1; 1509 si = 1;
1510 t = 0; 1510 t = 0;
1511 1511
1512 /* Initial state for compares */ 1512 /* Initial state for compares */
1513 mutex_lock(&hotkey_thread_data_mutex); 1513 mutex_lock(&hotkey_thread_data_mutex);
1514 change_detector = hotkey_config_change; 1514 change_detector = hotkey_config_change;
1515 mask = hotkey_source_mask & hotkey_mask; 1515 mask = hotkey_source_mask & hotkey_mask;
1516 mutex_unlock(&hotkey_thread_data_mutex); 1516 mutex_unlock(&hotkey_thread_data_mutex);
1517 hotkey_read_nvram(&s[so], mask); 1517 hotkey_read_nvram(&s[so], mask);
1518 1518
1519 while (!kthread_should_stop() && hotkey_poll_freq) { 1519 while (!kthread_should_stop() && hotkey_poll_freq) {
1520 if (t == 0) 1520 if (t == 0)
1521 t = 1000/hotkey_poll_freq; 1521 t = 1000/hotkey_poll_freq;
1522 t = msleep_interruptible(t); 1522 t = msleep_interruptible(t);
1523 if (unlikely(kthread_should_stop())) 1523 if (unlikely(kthread_should_stop()))
1524 break; 1524 break;
1525 must_reset = try_to_freeze(); 1525 must_reset = try_to_freeze();
1526 if (t > 0 && !must_reset) 1526 if (t > 0 && !must_reset)
1527 continue; 1527 continue;
1528 1528
1529 mutex_lock(&hotkey_thread_data_mutex); 1529 mutex_lock(&hotkey_thread_data_mutex);
1530 if (must_reset || hotkey_config_change != change_detector) { 1530 if (must_reset || hotkey_config_change != change_detector) {
1531 /* forget old state on thaw or config change */ 1531 /* forget old state on thaw or config change */
1532 si = so; 1532 si = so;
1533 t = 0; 1533 t = 0;
1534 change_detector = hotkey_config_change; 1534 change_detector = hotkey_config_change;
1535 } 1535 }
1536 mask = hotkey_source_mask & hotkey_mask; 1536 mask = hotkey_source_mask & hotkey_mask;
1537 mutex_unlock(&hotkey_thread_data_mutex); 1537 mutex_unlock(&hotkey_thread_data_mutex);
1538 1538
1539 if (likely(mask)) { 1539 if (likely(mask)) {
1540 hotkey_read_nvram(&s[si], mask); 1540 hotkey_read_nvram(&s[si], mask);
1541 if (likely(si != so)) { 1541 if (likely(si != so)) {
1542 hotkey_compare_and_issue_event(&s[so], &s[si], 1542 hotkey_compare_and_issue_event(&s[so], &s[si],
1543 mask); 1543 mask);
1544 } 1544 }
1545 } 1545 }
1546 1546
1547 so = si; 1547 so = si;
1548 si ^= 1; 1548 si ^= 1;
1549 } 1549 }
1550 1550
1551 exit: 1551 exit:
1552 mutex_unlock(&hotkey_thread_mutex); 1552 mutex_unlock(&hotkey_thread_mutex);
1553 return 0; 1553 return 0;
1554 } 1554 }
1555 1555
1556 static void hotkey_poll_stop_sync(void) 1556 static void hotkey_poll_stop_sync(void)
1557 { 1557 {
1558 if (tpacpi_hotkey_task) { 1558 if (tpacpi_hotkey_task) {
1559 if (frozen(tpacpi_hotkey_task) || 1559 if (frozen(tpacpi_hotkey_task) ||
1560 freezing(tpacpi_hotkey_task)) 1560 freezing(tpacpi_hotkey_task))
1561 thaw_process(tpacpi_hotkey_task); 1561 thaw_process(tpacpi_hotkey_task);
1562 1562
1563 kthread_stop(tpacpi_hotkey_task); 1563 kthread_stop(tpacpi_hotkey_task);
1564 tpacpi_hotkey_task = NULL; 1564 tpacpi_hotkey_task = NULL;
1565 mutex_lock(&hotkey_thread_mutex); 1565 mutex_lock(&hotkey_thread_mutex);
1566 /* at this point, the thread did exit */ 1566 /* at this point, the thread did exit */
1567 mutex_unlock(&hotkey_thread_mutex); 1567 mutex_unlock(&hotkey_thread_mutex);
1568 } 1568 }
1569 } 1569 }
1570 1570
1571 /* call with hotkey_mutex held */ 1571 /* call with hotkey_mutex held */
1572 static void hotkey_poll_setup(int may_warn) 1572 static void hotkey_poll_setup(int may_warn)
1573 { 1573 {
1574 if ((hotkey_source_mask & hotkey_mask) != 0 && 1574 if ((hotkey_source_mask & hotkey_mask) != 0 &&
1575 hotkey_poll_freq > 0 && 1575 hotkey_poll_freq > 0 &&
1576 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { 1576 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) {
1577 if (!tpacpi_hotkey_task) { 1577 if (!tpacpi_hotkey_task) {
1578 tpacpi_hotkey_task = kthread_run(hotkey_kthread, 1578 tpacpi_hotkey_task = kthread_run(hotkey_kthread,
1579 NULL, TPACPI_NVRAM_KTHREAD_NAME); 1579 NULL, TPACPI_NVRAM_KTHREAD_NAME);
1580 if (IS_ERR(tpacpi_hotkey_task)) { 1580 if (IS_ERR(tpacpi_hotkey_task)) {
1581 tpacpi_hotkey_task = NULL; 1581 tpacpi_hotkey_task = NULL;
1582 printk(TPACPI_ERR 1582 printk(TPACPI_ERR
1583 "could not create kernel thread " 1583 "could not create kernel thread "
1584 "for hotkey polling\n"); 1584 "for hotkey polling\n");
1585 } 1585 }
1586 } 1586 }
1587 } else { 1587 } else {
1588 hotkey_poll_stop_sync(); 1588 hotkey_poll_stop_sync();
1589 if (may_warn && 1589 if (may_warn &&
1590 hotkey_source_mask != 0 && hotkey_poll_freq == 0) { 1590 hotkey_source_mask != 0 && hotkey_poll_freq == 0) {
1591 printk(TPACPI_NOTICE 1591 printk(TPACPI_NOTICE
1592 "hot keys 0x%08x require polling, " 1592 "hot keys 0x%08x require polling, "
1593 "which is currently disabled\n", 1593 "which is currently disabled\n",
1594 hotkey_source_mask); 1594 hotkey_source_mask);
1595 } 1595 }
1596 } 1596 }
1597 } 1597 }
1598 1598
1599 static void hotkey_poll_setup_safe(int may_warn) 1599 static void hotkey_poll_setup_safe(int may_warn)
1600 { 1600 {
1601 mutex_lock(&hotkey_mutex); 1601 mutex_lock(&hotkey_mutex);
1602 hotkey_poll_setup(may_warn); 1602 hotkey_poll_setup(may_warn);
1603 mutex_unlock(&hotkey_mutex); 1603 mutex_unlock(&hotkey_mutex);
1604 } 1604 }
1605 1605
1606 #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1606 #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1607 1607
1608 static void hotkey_poll_setup_safe(int __unused) 1608 static void hotkey_poll_setup_safe(int __unused)
1609 { 1609 {
1610 } 1610 }
1611 1611
1612 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1612 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1613 1613
1614 static int hotkey_inputdev_open(struct input_dev *dev) 1614 static int hotkey_inputdev_open(struct input_dev *dev)
1615 { 1615 {
1616 switch (tpacpi_lifecycle) { 1616 switch (tpacpi_lifecycle) {
1617 case TPACPI_LIFE_INIT: 1617 case TPACPI_LIFE_INIT:
1618 /* 1618 /*
1619 * hotkey_init will call hotkey_poll_setup_safe 1619 * hotkey_init will call hotkey_poll_setup_safe
1620 * at the appropriate moment 1620 * at the appropriate moment
1621 */ 1621 */
1622 return 0; 1622 return 0;
1623 case TPACPI_LIFE_EXITING: 1623 case TPACPI_LIFE_EXITING:
1624 return -EBUSY; 1624 return -EBUSY;
1625 case TPACPI_LIFE_RUNNING: 1625 case TPACPI_LIFE_RUNNING:
1626 hotkey_poll_setup_safe(0); 1626 hotkey_poll_setup_safe(0);
1627 return 0; 1627 return 0;
1628 } 1628 }
1629 1629
1630 /* Should only happen if tpacpi_lifecycle is corrupt */ 1630 /* Should only happen if tpacpi_lifecycle is corrupt */
1631 BUG(); 1631 BUG();
1632 return -EBUSY; 1632 return -EBUSY;
1633 } 1633 }
1634 1634
1635 static void hotkey_inputdev_close(struct input_dev *dev) 1635 static void hotkey_inputdev_close(struct input_dev *dev)
1636 { 1636 {
1637 /* disable hotkey polling when possible */ 1637 /* disable hotkey polling when possible */
1638 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) 1638 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING)
1639 hotkey_poll_setup_safe(0); 1639 hotkey_poll_setup_safe(0);
1640 } 1640 }
1641 1641
1642 /* sysfs hotkey enable ------------------------------------------------- */ 1642 /* sysfs hotkey enable ------------------------------------------------- */
1643 static ssize_t hotkey_enable_show(struct device *dev, 1643 static ssize_t hotkey_enable_show(struct device *dev,
1644 struct device_attribute *attr, 1644 struct device_attribute *attr,
1645 char *buf) 1645 char *buf)
1646 { 1646 {
1647 int res, status; 1647 int res, status;
1648 1648
1649 res = hotkey_status_get(&status); 1649 res = hotkey_status_get(&status);
1650 if (res) 1650 if (res)
1651 return res; 1651 return res;
1652 1652
1653 return snprintf(buf, PAGE_SIZE, "%d\n", status); 1653 return snprintf(buf, PAGE_SIZE, "%d\n", status);
1654 } 1654 }
1655 1655
1656 static ssize_t hotkey_enable_store(struct device *dev, 1656 static ssize_t hotkey_enable_store(struct device *dev,
1657 struct device_attribute *attr, 1657 struct device_attribute *attr,
1658 const char *buf, size_t count) 1658 const char *buf, size_t count)
1659 { 1659 {
1660 unsigned long t; 1660 unsigned long t;
1661 int res; 1661 int res;
1662 1662
1663 if (parse_strtoul(buf, 1, &t)) 1663 if (parse_strtoul(buf, 1, &t))
1664 return -EINVAL; 1664 return -EINVAL;
1665 1665
1666 res = hotkey_status_set(t); 1666 res = hotkey_status_set(t);
1667 1667
1668 return (res) ? res : count; 1668 return (res) ? res : count;
1669 } 1669 }
1670 1670
1671 static struct device_attribute dev_attr_hotkey_enable = 1671 static struct device_attribute dev_attr_hotkey_enable =
1672 __ATTR(hotkey_enable, S_IWUSR | S_IRUGO, 1672 __ATTR(hotkey_enable, S_IWUSR | S_IRUGO,
1673 hotkey_enable_show, hotkey_enable_store); 1673 hotkey_enable_show, hotkey_enable_store);
1674 1674
1675 /* sysfs hotkey mask --------------------------------------------------- */ 1675 /* sysfs hotkey mask --------------------------------------------------- */
1676 static ssize_t hotkey_mask_show(struct device *dev, 1676 static ssize_t hotkey_mask_show(struct device *dev,
1677 struct device_attribute *attr, 1677 struct device_attribute *attr,
1678 char *buf) 1678 char *buf)
1679 { 1679 {
1680 int res; 1680 int res;
1681 1681
1682 if (mutex_lock_interruptible(&hotkey_mutex)) 1682 if (mutex_lock_interruptible(&hotkey_mutex))
1683 return -ERESTARTSYS; 1683 return -ERESTARTSYS;
1684 res = hotkey_mask_get(); 1684 res = hotkey_mask_get();
1685 mutex_unlock(&hotkey_mutex); 1685 mutex_unlock(&hotkey_mutex);
1686 1686
1687 return (res)? 1687 return (res)?
1688 res : snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_mask); 1688 res : snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_mask);
1689 } 1689 }
1690 1690
1691 static ssize_t hotkey_mask_store(struct device *dev, 1691 static ssize_t hotkey_mask_store(struct device *dev,
1692 struct device_attribute *attr, 1692 struct device_attribute *attr,
1693 const char *buf, size_t count) 1693 const char *buf, size_t count)
1694 { 1694 {
1695 unsigned long t; 1695 unsigned long t;
1696 int res; 1696 int res;
1697 1697
1698 if (parse_strtoul(buf, 0xffffffffUL, &t)) 1698 if (parse_strtoul(buf, 0xffffffffUL, &t))
1699 return -EINVAL; 1699 return -EINVAL;
1700 1700
1701 if (mutex_lock_interruptible(&hotkey_mutex)) 1701 if (mutex_lock_interruptible(&hotkey_mutex))
1702 return -ERESTARTSYS; 1702 return -ERESTARTSYS;
1703 1703
1704 res = hotkey_mask_set(t); 1704 res = hotkey_mask_set(t);
1705 1705
1706 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1706 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1707 hotkey_poll_setup(1); 1707 hotkey_poll_setup(1);
1708 #endif 1708 #endif
1709 1709
1710 mutex_unlock(&hotkey_mutex); 1710 mutex_unlock(&hotkey_mutex);
1711 1711
1712 return (res) ? res : count; 1712 return (res) ? res : count;
1713 } 1713 }
1714 1714
1715 static struct device_attribute dev_attr_hotkey_mask = 1715 static struct device_attribute dev_attr_hotkey_mask =
1716 __ATTR(hotkey_mask, S_IWUSR | S_IRUGO, 1716 __ATTR(hotkey_mask, S_IWUSR | S_IRUGO,
1717 hotkey_mask_show, hotkey_mask_store); 1717 hotkey_mask_show, hotkey_mask_store);
1718 1718
1719 /* sysfs hotkey bios_enabled ------------------------------------------- */ 1719 /* sysfs hotkey bios_enabled ------------------------------------------- */
1720 static ssize_t hotkey_bios_enabled_show(struct device *dev, 1720 static ssize_t hotkey_bios_enabled_show(struct device *dev,
1721 struct device_attribute *attr, 1721 struct device_attribute *attr,
1722 char *buf) 1722 char *buf)
1723 { 1723 {
1724 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status); 1724 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
1725 } 1725 }
1726 1726
1727 static struct device_attribute dev_attr_hotkey_bios_enabled = 1727 static struct device_attribute dev_attr_hotkey_bios_enabled =
1728 __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL); 1728 __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
1729 1729
1730 /* sysfs hotkey bios_mask ---------------------------------------------- */ 1730 /* sysfs hotkey bios_mask ---------------------------------------------- */
1731 static ssize_t hotkey_bios_mask_show(struct device *dev, 1731 static ssize_t hotkey_bios_mask_show(struct device *dev,
1732 struct device_attribute *attr, 1732 struct device_attribute *attr,
1733 char *buf) 1733 char *buf)
1734 { 1734 {
1735 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); 1735 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
1736 } 1736 }
1737 1737
1738 static struct device_attribute dev_attr_hotkey_bios_mask = 1738 static struct device_attribute dev_attr_hotkey_bios_mask =
1739 __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); 1739 __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
1740 1740
1741 /* sysfs hotkey all_mask ----------------------------------------------- */ 1741 /* sysfs hotkey all_mask ----------------------------------------------- */
1742 static ssize_t hotkey_all_mask_show(struct device *dev, 1742 static ssize_t hotkey_all_mask_show(struct device *dev,
1743 struct device_attribute *attr, 1743 struct device_attribute *attr,
1744 char *buf) 1744 char *buf)
1745 { 1745 {
1746 return snprintf(buf, PAGE_SIZE, "0x%08x\n", 1746 return snprintf(buf, PAGE_SIZE, "0x%08x\n",
1747 hotkey_all_mask | hotkey_source_mask); 1747 hotkey_all_mask | hotkey_source_mask);
1748 } 1748 }
1749 1749
1750 static struct device_attribute dev_attr_hotkey_all_mask = 1750 static struct device_attribute dev_attr_hotkey_all_mask =
1751 __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL); 1751 __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL);
1752 1752
1753 /* sysfs hotkey recommended_mask --------------------------------------- */ 1753 /* sysfs hotkey recommended_mask --------------------------------------- */
1754 static ssize_t hotkey_recommended_mask_show(struct device *dev, 1754 static ssize_t hotkey_recommended_mask_show(struct device *dev,
1755 struct device_attribute *attr, 1755 struct device_attribute *attr,
1756 char *buf) 1756 char *buf)
1757 { 1757 {
1758 return snprintf(buf, PAGE_SIZE, "0x%08x\n", 1758 return snprintf(buf, PAGE_SIZE, "0x%08x\n",
1759 (hotkey_all_mask | hotkey_source_mask) 1759 (hotkey_all_mask | hotkey_source_mask)
1760 & ~hotkey_reserved_mask); 1760 & ~hotkey_reserved_mask);
1761 } 1761 }
1762 1762
1763 static struct device_attribute dev_attr_hotkey_recommended_mask = 1763 static struct device_attribute dev_attr_hotkey_recommended_mask =
1764 __ATTR(hotkey_recommended_mask, S_IRUGO, 1764 __ATTR(hotkey_recommended_mask, S_IRUGO,
1765 hotkey_recommended_mask_show, NULL); 1765 hotkey_recommended_mask_show, NULL);
1766 1766
1767 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1767 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1768 1768
1769 /* sysfs hotkey hotkey_source_mask ------------------------------------- */ 1769 /* sysfs hotkey hotkey_source_mask ------------------------------------- */
1770 static ssize_t hotkey_source_mask_show(struct device *dev, 1770 static ssize_t hotkey_source_mask_show(struct device *dev,
1771 struct device_attribute *attr, 1771 struct device_attribute *attr,
1772 char *buf) 1772 char *buf)
1773 { 1773 {
1774 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_source_mask); 1774 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_source_mask);
1775 } 1775 }
1776 1776
1777 static ssize_t hotkey_source_mask_store(struct device *dev, 1777 static ssize_t hotkey_source_mask_store(struct device *dev,
1778 struct device_attribute *attr, 1778 struct device_attribute *attr,
1779 const char *buf, size_t count) 1779 const char *buf, size_t count)
1780 { 1780 {
1781 unsigned long t; 1781 unsigned long t;
1782 1782
1783 if (parse_strtoul(buf, 0xffffffffUL, &t) || 1783 if (parse_strtoul(buf, 0xffffffffUL, &t) ||
1784 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0)) 1784 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0))
1785 return -EINVAL; 1785 return -EINVAL;
1786 1786
1787 if (mutex_lock_interruptible(&hotkey_mutex)) 1787 if (mutex_lock_interruptible(&hotkey_mutex))
1788 return -ERESTARTSYS; 1788 return -ERESTARTSYS;
1789 1789
1790 HOTKEY_CONFIG_CRITICAL_START 1790 HOTKEY_CONFIG_CRITICAL_START
1791 hotkey_source_mask = t; 1791 hotkey_source_mask = t;
1792 HOTKEY_CONFIG_CRITICAL_END 1792 HOTKEY_CONFIG_CRITICAL_END
1793 1793
1794 hotkey_poll_setup(1); 1794 hotkey_poll_setup(1);
1795 1795
1796 mutex_unlock(&hotkey_mutex); 1796 mutex_unlock(&hotkey_mutex);
1797 1797
1798 return count; 1798 return count;
1799 } 1799 }
1800 1800
1801 static struct device_attribute dev_attr_hotkey_source_mask = 1801 static struct device_attribute dev_attr_hotkey_source_mask =
1802 __ATTR(hotkey_source_mask, S_IWUSR | S_IRUGO, 1802 __ATTR(hotkey_source_mask, S_IWUSR | S_IRUGO,
1803 hotkey_source_mask_show, hotkey_source_mask_store); 1803 hotkey_source_mask_show, hotkey_source_mask_store);
1804 1804
1805 /* sysfs hotkey hotkey_poll_freq --------------------------------------- */ 1805 /* sysfs hotkey hotkey_poll_freq --------------------------------------- */
1806 static ssize_t hotkey_poll_freq_show(struct device *dev, 1806 static ssize_t hotkey_poll_freq_show(struct device *dev,
1807 struct device_attribute *attr, 1807 struct device_attribute *attr,
1808 char *buf) 1808 char *buf)
1809 { 1809 {
1810 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_poll_freq); 1810 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_poll_freq);
1811 } 1811 }
1812 1812
1813 static ssize_t hotkey_poll_freq_store(struct device *dev, 1813 static ssize_t hotkey_poll_freq_store(struct device *dev,
1814 struct device_attribute *attr, 1814 struct device_attribute *attr,
1815 const char *buf, size_t count) 1815 const char *buf, size_t count)
1816 { 1816 {
1817 unsigned long t; 1817 unsigned long t;
1818 1818
1819 if (parse_strtoul(buf, 25, &t)) 1819 if (parse_strtoul(buf, 25, &t))
1820 return -EINVAL; 1820 return -EINVAL;
1821 1821
1822 if (mutex_lock_interruptible(&hotkey_mutex)) 1822 if (mutex_lock_interruptible(&hotkey_mutex))
1823 return -ERESTARTSYS; 1823 return -ERESTARTSYS;
1824 1824
1825 hotkey_poll_freq = t; 1825 hotkey_poll_freq = t;
1826 1826
1827 hotkey_poll_setup(1); 1827 hotkey_poll_setup(1);
1828 mutex_unlock(&hotkey_mutex); 1828 mutex_unlock(&hotkey_mutex);
1829 1829
1830 return count; 1830 return count;
1831 } 1831 }
1832 1832
1833 static struct device_attribute dev_attr_hotkey_poll_freq = 1833 static struct device_attribute dev_attr_hotkey_poll_freq =
1834 __ATTR(hotkey_poll_freq, S_IWUSR | S_IRUGO, 1834 __ATTR(hotkey_poll_freq, S_IWUSR | S_IRUGO,
1835 hotkey_poll_freq_show, hotkey_poll_freq_store); 1835 hotkey_poll_freq_show, hotkey_poll_freq_store);
1836 1836
1837 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1837 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1838 1838
1839 /* sysfs hotkey radio_sw (pollable) ------------------------------------ */ 1839 /* sysfs hotkey radio_sw (pollable) ------------------------------------ */
1840 static ssize_t hotkey_radio_sw_show(struct device *dev, 1840 static ssize_t hotkey_radio_sw_show(struct device *dev,
1841 struct device_attribute *attr, 1841 struct device_attribute *attr,
1842 char *buf) 1842 char *buf)
1843 { 1843 {
1844 int res, s; 1844 int res, s;
1845 res = hotkey_get_wlsw(&s); 1845 res = hotkey_get_wlsw(&s);
1846 if (res < 0) 1846 if (res < 0)
1847 return res; 1847 return res;
1848 1848
1849 return snprintf(buf, PAGE_SIZE, "%d\n", !!s); 1849 return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
1850 } 1850 }
1851 1851
1852 static struct device_attribute dev_attr_hotkey_radio_sw = 1852 static struct device_attribute dev_attr_hotkey_radio_sw =
1853 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); 1853 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
1854 1854
1855 static void hotkey_radio_sw_notify_change(void) 1855 static void hotkey_radio_sw_notify_change(void)
1856 { 1856 {
1857 if (tp_features.hotkey_wlsw) 1857 if (tp_features.hotkey_wlsw)
1858 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 1858 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
1859 "hotkey_radio_sw"); 1859 "hotkey_radio_sw");
1860 } 1860 }
1861 1861
1862 /* sysfs hotkey tablet mode (pollable) --------------------------------- */ 1862 /* sysfs hotkey tablet mode (pollable) --------------------------------- */
1863 static ssize_t hotkey_tablet_mode_show(struct device *dev, 1863 static ssize_t hotkey_tablet_mode_show(struct device *dev,
1864 struct device_attribute *attr, 1864 struct device_attribute *attr,
1865 char *buf) 1865 char *buf)
1866 { 1866 {
1867 int res, s; 1867 int res, s;
1868 res = hotkey_get_tablet_mode(&s); 1868 res = hotkey_get_tablet_mode(&s);
1869 if (res < 0) 1869 if (res < 0)
1870 return res; 1870 return res;
1871 1871
1872 return snprintf(buf, PAGE_SIZE, "%d\n", !!s); 1872 return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
1873 } 1873 }
1874 1874
1875 static struct device_attribute dev_attr_hotkey_tablet_mode = 1875 static struct device_attribute dev_attr_hotkey_tablet_mode =
1876 __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL); 1876 __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL);
1877 1877
1878 static void hotkey_tablet_mode_notify_change(void) 1878 static void hotkey_tablet_mode_notify_change(void)
1879 { 1879 {
1880 if (tp_features.hotkey_tablet) 1880 if (tp_features.hotkey_tablet)
1881 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 1881 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
1882 "hotkey_tablet_mode"); 1882 "hotkey_tablet_mode");
1883 } 1883 }
1884 1884
1885 /* sysfs hotkey report_mode -------------------------------------------- */ 1885 /* sysfs hotkey report_mode -------------------------------------------- */
1886 static ssize_t hotkey_report_mode_show(struct device *dev, 1886 static ssize_t hotkey_report_mode_show(struct device *dev,
1887 struct device_attribute *attr, 1887 struct device_attribute *attr,
1888 char *buf) 1888 char *buf)
1889 { 1889 {
1890 return snprintf(buf, PAGE_SIZE, "%d\n", 1890 return snprintf(buf, PAGE_SIZE, "%d\n",
1891 (hotkey_report_mode != 0) ? hotkey_report_mode : 1); 1891 (hotkey_report_mode != 0) ? hotkey_report_mode : 1);
1892 } 1892 }
1893 1893
1894 static struct device_attribute dev_attr_hotkey_report_mode = 1894 static struct device_attribute dev_attr_hotkey_report_mode =
1895 __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL); 1895 __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL);
1896 1896
1897 /* sysfs wakeup reason (pollable) -------------------------------------- */ 1897 /* sysfs wakeup reason (pollable) -------------------------------------- */
1898 static ssize_t hotkey_wakeup_reason_show(struct device *dev, 1898 static ssize_t hotkey_wakeup_reason_show(struct device *dev,
1899 struct device_attribute *attr, 1899 struct device_attribute *attr,
1900 char *buf) 1900 char *buf)
1901 { 1901 {
1902 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason); 1902 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason);
1903 } 1903 }
1904 1904
1905 static struct device_attribute dev_attr_hotkey_wakeup_reason = 1905 static struct device_attribute dev_attr_hotkey_wakeup_reason =
1906 __ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL); 1906 __ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL);
1907 1907
1908 static void hotkey_wakeup_reason_notify_change(void) 1908 static void hotkey_wakeup_reason_notify_change(void)
1909 { 1909 {
1910 if (tp_features.hotkey_mask) 1910 if (tp_features.hotkey_mask)
1911 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 1911 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
1912 "wakeup_reason"); 1912 "wakeup_reason");
1913 } 1913 }
1914 1914
1915 /* sysfs wakeup hotunplug_complete (pollable) -------------------------- */ 1915 /* sysfs wakeup hotunplug_complete (pollable) -------------------------- */
1916 static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev, 1916 static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev,
1917 struct device_attribute *attr, 1917 struct device_attribute *attr,
1918 char *buf) 1918 char *buf)
1919 { 1919 {
1920 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack); 1920 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack);
1921 } 1921 }
1922 1922
1923 static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete = 1923 static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete =
1924 __ATTR(wakeup_hotunplug_complete, S_IRUGO, 1924 __ATTR(wakeup_hotunplug_complete, S_IRUGO,
1925 hotkey_wakeup_hotunplug_complete_show, NULL); 1925 hotkey_wakeup_hotunplug_complete_show, NULL);
1926 1926
1927 static void hotkey_wakeup_hotunplug_complete_notify_change(void) 1927 static void hotkey_wakeup_hotunplug_complete_notify_change(void)
1928 { 1928 {
1929 if (tp_features.hotkey_mask) 1929 if (tp_features.hotkey_mask)
1930 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 1930 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
1931 "wakeup_hotunplug_complete"); 1931 "wakeup_hotunplug_complete");
1932 } 1932 }
1933 1933
1934 /* --------------------------------------------------------------------- */ 1934 /* --------------------------------------------------------------------- */
1935 1935
1936 static struct attribute *hotkey_attributes[] __initdata = { 1936 static struct attribute *hotkey_attributes[] __initdata = {
1937 &dev_attr_hotkey_enable.attr, 1937 &dev_attr_hotkey_enable.attr,
1938 &dev_attr_hotkey_bios_enabled.attr, 1938 &dev_attr_hotkey_bios_enabled.attr,
1939 &dev_attr_hotkey_report_mode.attr, 1939 &dev_attr_hotkey_report_mode.attr,
1940 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1940 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1941 &dev_attr_hotkey_mask.attr, 1941 &dev_attr_hotkey_mask.attr,
1942 &dev_attr_hotkey_all_mask.attr, 1942 &dev_attr_hotkey_all_mask.attr,
1943 &dev_attr_hotkey_recommended_mask.attr, 1943 &dev_attr_hotkey_recommended_mask.attr,
1944 &dev_attr_hotkey_source_mask.attr, 1944 &dev_attr_hotkey_source_mask.attr,
1945 &dev_attr_hotkey_poll_freq.attr, 1945 &dev_attr_hotkey_poll_freq.attr,
1946 #endif 1946 #endif
1947 }; 1947 };
1948 1948
1949 static struct attribute *hotkey_mask_attributes[] __initdata = { 1949 static struct attribute *hotkey_mask_attributes[] __initdata = {
1950 &dev_attr_hotkey_bios_mask.attr, 1950 &dev_attr_hotkey_bios_mask.attr,
1951 #ifndef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1951 #ifndef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1952 &dev_attr_hotkey_mask.attr, 1952 &dev_attr_hotkey_mask.attr,
1953 &dev_attr_hotkey_all_mask.attr, 1953 &dev_attr_hotkey_all_mask.attr,
1954 &dev_attr_hotkey_recommended_mask.attr, 1954 &dev_attr_hotkey_recommended_mask.attr,
1955 #endif 1955 #endif
1956 &dev_attr_hotkey_wakeup_reason.attr, 1956 &dev_attr_hotkey_wakeup_reason.attr,
1957 &dev_attr_hotkey_wakeup_hotunplug_complete.attr, 1957 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
1958 }; 1958 };
1959 1959
1960 static void bluetooth_update_rfk(void); 1960 static void bluetooth_update_rfk(void);
1961 static void wan_update_rfk(void); 1961 static void wan_update_rfk(void);
1962 static void tpacpi_send_radiosw_update(void) 1962 static void tpacpi_send_radiosw_update(void)
1963 { 1963 {
1964 int wlsw; 1964 int wlsw;
1965 1965
1966 /* Sync these BEFORE sending any rfkill events */ 1966 /* Sync these BEFORE sending any rfkill events */
1967 if (tp_features.bluetooth) 1967 if (tp_features.bluetooth)
1968 bluetooth_update_rfk(); 1968 bluetooth_update_rfk();
1969 if (tp_features.wan) 1969 if (tp_features.wan)
1970 wan_update_rfk(); 1970 wan_update_rfk();
1971 1971
1972 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { 1972 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
1973 mutex_lock(&tpacpi_inputdev_send_mutex); 1973 mutex_lock(&tpacpi_inputdev_send_mutex);
1974 1974
1975 input_report_switch(tpacpi_inputdev, 1975 input_report_switch(tpacpi_inputdev,
1976 SW_RFKILL_ALL, !!wlsw); 1976 SW_RFKILL_ALL, !!wlsw);
1977 input_sync(tpacpi_inputdev); 1977 input_sync(tpacpi_inputdev);
1978 1978
1979 mutex_unlock(&tpacpi_inputdev_send_mutex); 1979 mutex_unlock(&tpacpi_inputdev_send_mutex);
1980 } 1980 }
1981 hotkey_radio_sw_notify_change(); 1981 hotkey_radio_sw_notify_change();
1982 } 1982 }
1983 1983
1984 static void hotkey_exit(void) 1984 static void hotkey_exit(void)
1985 { 1985 {
1986 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 1986 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1987 hotkey_poll_stop_sync(); 1987 hotkey_poll_stop_sync();
1988 #endif 1988 #endif
1989 1989
1990 if (hotkey_dev_attributes) 1990 if (hotkey_dev_attributes)
1991 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); 1991 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
1992 1992
1993 kfree(hotkey_keycode_map); 1993 kfree(hotkey_keycode_map);
1994 1994
1995 if (tp_features.hotkey) { 1995 if (tp_features.hotkey) {
1996 dbg_printk(TPACPI_DBG_EXIT, 1996 dbg_printk(TPACPI_DBG_EXIT,
1997 "restoring original hot key mask\n"); 1997 "restoring original hot key mask\n");
1998 /* no short-circuit boolean operator below! */ 1998 /* no short-circuit boolean operator below! */
1999 if ((hotkey_mask_set(hotkey_orig_mask) | 1999 if ((hotkey_mask_set(hotkey_orig_mask) |
2000 hotkey_status_set(hotkey_orig_status)) != 0) 2000 hotkey_status_set(hotkey_orig_status)) != 0)
2001 printk(TPACPI_ERR 2001 printk(TPACPI_ERR
2002 "failed to restore hot key mask " 2002 "failed to restore hot key mask "
2003 "to BIOS defaults\n"); 2003 "to BIOS defaults\n");
2004 } 2004 }
2005 } 2005 }
2006 2006
2007 static int __init hotkey_init(struct ibm_init_struct *iibm) 2007 static int __init hotkey_init(struct ibm_init_struct *iibm)
2008 { 2008 {
2009 /* Requirements for changing the default keymaps: 2009 /* Requirements for changing the default keymaps:
2010 * 2010 *
2011 * 1. Many of the keys are mapped to KEY_RESERVED for very 2011 * 1. Many of the keys are mapped to KEY_RESERVED for very
2012 * good reasons. Do not change them unless you have deep 2012 * good reasons. Do not change them unless you have deep
2013 * knowledge on the IBM and Lenovo ThinkPad firmware for 2013 * knowledge on the IBM and Lenovo ThinkPad firmware for
2014 * the various ThinkPad models. The driver behaves 2014 * the various ThinkPad models. The driver behaves
2015 * differently for KEY_RESERVED: such keys have their 2015 * differently for KEY_RESERVED: such keys have their
2016 * hot key mask *unset* in mask_recommended, and also 2016 * hot key mask *unset* in mask_recommended, and also
2017 * in the initial hot key mask programmed into the 2017 * in the initial hot key mask programmed into the
2018 * firmware at driver load time, which means the firm- 2018 * firmware at driver load time, which means the firm-
2019 * ware may react very differently if you change them to 2019 * ware may react very differently if you change them to
2020 * something else; 2020 * something else;
2021 * 2021 *
2022 * 2. You must be subscribed to the linux-thinkpad and 2022 * 2. You must be subscribed to the linux-thinkpad and
2023 * ibm-acpi-devel mailing lists, and you should read the 2023 * ibm-acpi-devel mailing lists, and you should read the
2024 * list archives since 2007 if you want to change the 2024 * list archives since 2007 if you want to change the
2025 * keymaps. This requirement exists so that you will 2025 * keymaps. This requirement exists so that you will
2026 * know the past history of problems with the thinkpad- 2026 * know the past history of problems with the thinkpad-
2027 * acpi driver keymaps, and also that you will be 2027 * acpi driver keymaps, and also that you will be
2028 * listening to any bug reports; 2028 * listening to any bug reports;
2029 * 2029 *
2030 * 3. Do not send thinkpad-acpi specific patches directly to 2030 * 3. Do not send thinkpad-acpi specific patches directly to
2031 * for merging, *ever*. Send them to the linux-acpi 2031 * for merging, *ever*. Send them to the linux-acpi
2032 * mailinglist for comments. Merging is to be done only 2032 * mailinglist for comments. Merging is to be done only
2033 * through acpi-test and the ACPI maintainer. 2033 * through acpi-test and the ACPI maintainer.
2034 * 2034 *
2035 * If the above is too much to ask, don't change the keymap. 2035 * If the above is too much to ask, don't change the keymap.
2036 * Ask the thinkpad-acpi maintainer to do it, instead. 2036 * Ask the thinkpad-acpi maintainer to do it, instead.
2037 */ 2037 */
2038 static u16 ibm_keycode_map[] __initdata = { 2038 static u16 ibm_keycode_map[] __initdata = {
2039 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ 2039 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
2040 KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP, 2040 KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP,
2041 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, 2041 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
2042 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, 2042 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
2043 2043
2044 /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */ 2044 /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */
2045 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ 2045 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
2046 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 2046 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
2047 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 2047 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
2048 2048
2049 /* brightness: firmware always reacts to them, unless 2049 /* brightness: firmware always reacts to them, unless
2050 * X.org did some tricks in the radeon BIOS scratch 2050 * X.org did some tricks in the radeon BIOS scratch
2051 * registers of *some* models */ 2051 * registers of *some* models */
2052 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 2052 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
2053 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 2053 KEY_RESERVED, /* 0x10: FN+END (brightness down) */
2054 2054
2055 /* Thinklight: firmware always react to it */ 2055 /* Thinklight: firmware always react to it */
2056 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ 2056 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
2057 2057
2058 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ 2058 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
2059 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ 2059 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
2060 2060
2061 /* Volume: firmware always react to it and reprograms 2061 /* Volume: firmware always react to it and reprograms
2062 * the built-in *extra* mixer. Never map it to control 2062 * the built-in *extra* mixer. Never map it to control
2063 * another mixer by default. */ 2063 * another mixer by default. */
2064 KEY_RESERVED, /* 0x14: VOLUME UP */ 2064 KEY_RESERVED, /* 0x14: VOLUME UP */
2065 KEY_RESERVED, /* 0x15: VOLUME DOWN */ 2065 KEY_RESERVED, /* 0x15: VOLUME DOWN */
2066 KEY_RESERVED, /* 0x16: MUTE */ 2066 KEY_RESERVED, /* 0x16: MUTE */
2067 2067
2068 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ 2068 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
2069 2069
2070 /* (assignments unknown, please report if found) */ 2070 /* (assignments unknown, please report if found) */
2071 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 2071 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
2072 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 2072 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
2073 }; 2073 };
2074 static u16 lenovo_keycode_map[] __initdata = { 2074 static u16 lenovo_keycode_map[] __initdata = {
2075 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ 2075 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
2076 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, 2076 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP,
2077 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, 2077 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
2078 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, 2078 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
2079 2079
2080 /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */ 2080 /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */
2081 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ 2081 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
2082 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 2082 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
2083 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 2083 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
2084 2084
2085 /* These either have to go through ACPI video, or 2085 /* These either have to go through ACPI video, or
2086 * act like in the IBM ThinkPads, so don't ever 2086 * act like in the IBM ThinkPads, so don't ever
2087 * enable them by default */ 2087 * enable them by default */
2088 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 2088 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
2089 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 2089 KEY_RESERVED, /* 0x10: FN+END (brightness down) */
2090 2090
2091 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ 2091 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
2092 2092
2093 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ 2093 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
2094 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ 2094 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
2095 2095
2096 /* Volume: z60/z61, T60 (BIOS version?): firmware always 2096 /* Volume: z60/z61, T60 (BIOS version?): firmware always
2097 * react to it and reprograms the built-in *extra* mixer. 2097 * react to it and reprograms the built-in *extra* mixer.
2098 * Never map it to control another mixer by default. 2098 * Never map it to control another mixer by default.
2099 * 2099 *
2100 * T60?, T61, R60?, R61: firmware and EC tries to send 2100 * T60?, T61, R60?, R61: firmware and EC tries to send
2101 * these over the regular keyboard, so these are no-ops, 2101 * these over the regular keyboard, so these are no-ops,
2102 * but there are still weird bugs re. MUTE, so do not 2102 * but there are still weird bugs re. MUTE, so do not
2103 * change unless you get test reports from all Lenovo 2103 * change unless you get test reports from all Lenovo
2104 * models. May cause the BIOS to interfere with the 2104 * models. May cause the BIOS to interfere with the
2105 * HDA mixer. 2105 * HDA mixer.
2106 */ 2106 */
2107 KEY_RESERVED, /* 0x14: VOLUME UP */ 2107 KEY_RESERVED, /* 0x14: VOLUME UP */
2108 KEY_RESERVED, /* 0x15: VOLUME DOWN */ 2108 KEY_RESERVED, /* 0x15: VOLUME DOWN */
2109 KEY_RESERVED, /* 0x16: MUTE */ 2109 KEY_RESERVED, /* 0x16: MUTE */
2110 2110
2111 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ 2111 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
2112 2112
2113 /* (assignments unknown, please report if found) */ 2113 /* (assignments unknown, please report if found) */
2114 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 2114 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
2115 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 2115 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
2116 }; 2116 };
2117 2117
2118 #define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map) 2118 #define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map)
2119 #define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map) 2119 #define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map)
2120 #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0]) 2120 #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0])
2121 2121
2122 int res, i; 2122 int res, i;
2123 int status; 2123 int status;
2124 int hkeyv; 2124 int hkeyv;
2125 2125
2126 vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); 2126 vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
2127 2127
2128 BUG_ON(!tpacpi_inputdev); 2128 BUG_ON(!tpacpi_inputdev);
2129 BUG_ON(tpacpi_inputdev->open != NULL || 2129 BUG_ON(tpacpi_inputdev->open != NULL ||
2130 tpacpi_inputdev->close != NULL); 2130 tpacpi_inputdev->close != NULL);
2131 2131
2132 TPACPI_ACPIHANDLE_INIT(hkey); 2132 TPACPI_ACPIHANDLE_INIT(hkey);
2133 mutex_init(&hotkey_mutex); 2133 mutex_init(&hotkey_mutex);
2134 2134
2135 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2135 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2136 mutex_init(&hotkey_thread_mutex); 2136 mutex_init(&hotkey_thread_mutex);
2137 mutex_init(&hotkey_thread_data_mutex); 2137 mutex_init(&hotkey_thread_data_mutex);
2138 #endif 2138 #endif
2139 2139
2140 /* hotkey not supported on 570 */ 2140 /* hotkey not supported on 570 */
2141 tp_features.hotkey = hkey_handle != NULL; 2141 tp_features.hotkey = hkey_handle != NULL;
2142 2142
2143 vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", 2143 vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
2144 str_supported(tp_features.hotkey)); 2144 str_supported(tp_features.hotkey));
2145 2145
2146 if (!tp_features.hotkey) 2146 if (!tp_features.hotkey)
2147 return 1; 2147 return 1;
2148 2148
2149 tpacpi_disable_brightness_delay(); 2149 tpacpi_disable_brightness_delay();
2150 2150
2151 hotkey_dev_attributes = create_attr_set(13, NULL); 2151 hotkey_dev_attributes = create_attr_set(13, NULL);
2152 if (!hotkey_dev_attributes) 2152 if (!hotkey_dev_attributes)
2153 return -ENOMEM; 2153 return -ENOMEM;
2154 res = add_many_to_attr_set(hotkey_dev_attributes, 2154 res = add_many_to_attr_set(hotkey_dev_attributes,
2155 hotkey_attributes, 2155 hotkey_attributes,
2156 ARRAY_SIZE(hotkey_attributes)); 2156 ARRAY_SIZE(hotkey_attributes));
2157 if (res) 2157 if (res)
2158 goto err_exit; 2158 goto err_exit;
2159 2159
2160 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 2160 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
2161 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking 2161 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking
2162 for HKEY interface version 0x100 */ 2162 for HKEY interface version 0x100 */
2163 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { 2163 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
2164 if ((hkeyv >> 8) != 1) { 2164 if ((hkeyv >> 8) != 1) {
2165 printk(TPACPI_ERR "unknown version of the " 2165 printk(TPACPI_ERR "unknown version of the "
2166 "HKEY interface: 0x%x\n", hkeyv); 2166 "HKEY interface: 0x%x\n", hkeyv);
2167 printk(TPACPI_ERR "please report this to %s\n", 2167 printk(TPACPI_ERR "please report this to %s\n",
2168 TPACPI_MAIL); 2168 TPACPI_MAIL);
2169 } else { 2169 } else {
2170 /* 2170 /*
2171 * MHKV 0x100 in A31, R40, R40e, 2171 * MHKV 0x100 in A31, R40, R40e,
2172 * T4x, X31, and later 2172 * T4x, X31, and later
2173 */ 2173 */
2174 tp_features.hotkey_mask = 1; 2174 tp_features.hotkey_mask = 1;
2175 } 2175 }
2176 } 2176 }
2177 2177
2178 vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", 2178 vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
2179 str_supported(tp_features.hotkey_mask)); 2179 str_supported(tp_features.hotkey_mask));
2180 2180
2181 if (tp_features.hotkey_mask) { 2181 if (tp_features.hotkey_mask) {
2182 if (!acpi_evalf(hkey_handle, &hotkey_all_mask, 2182 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
2183 "MHKA", "qd")) { 2183 "MHKA", "qd")) {
2184 printk(TPACPI_ERR 2184 printk(TPACPI_ERR
2185 "missing MHKA handler, " 2185 "missing MHKA handler, "
2186 "please report this to %s\n", 2186 "please report this to %s\n",
2187 TPACPI_MAIL); 2187 TPACPI_MAIL);
2188 /* FN+F12, FN+F4, FN+F3 */ 2188 /* FN+F12, FN+F4, FN+F3 */
2189 hotkey_all_mask = 0x080cU; 2189 hotkey_all_mask = 0x080cU;
2190 } 2190 }
2191 } 2191 }
2192 2192
2193 /* hotkey_source_mask *must* be zero for 2193 /* hotkey_source_mask *must* be zero for
2194 * the first hotkey_mask_get */ 2194 * the first hotkey_mask_get */
2195 res = hotkey_status_get(&hotkey_orig_status); 2195 res = hotkey_status_get(&hotkey_orig_status);
2196 if (res) 2196 if (res)
2197 goto err_exit; 2197 goto err_exit;
2198 2198
2199 if (tp_features.hotkey_mask) { 2199 if (tp_features.hotkey_mask) {
2200 res = hotkey_mask_get(); 2200 res = hotkey_mask_get();
2201 if (res) 2201 if (res)
2202 goto err_exit; 2202 goto err_exit;
2203 2203
2204 hotkey_orig_mask = hotkey_mask; 2204 hotkey_orig_mask = hotkey_mask;
2205 res = add_many_to_attr_set( 2205 res = add_many_to_attr_set(
2206 hotkey_dev_attributes, 2206 hotkey_dev_attributes,
2207 hotkey_mask_attributes, 2207 hotkey_mask_attributes,
2208 ARRAY_SIZE(hotkey_mask_attributes)); 2208 ARRAY_SIZE(hotkey_mask_attributes));
2209 if (res) 2209 if (res)
2210 goto err_exit; 2210 goto err_exit;
2211 } 2211 }
2212 2212
2213 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2213 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2214 if (tp_features.hotkey_mask) { 2214 if (tp_features.hotkey_mask) {
2215 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK 2215 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
2216 & ~hotkey_all_mask; 2216 & ~hotkey_all_mask;
2217 } else { 2217 } else {
2218 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; 2218 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
2219 } 2219 }
2220 2220
2221 vdbg_printk(TPACPI_DBG_INIT, 2221 vdbg_printk(TPACPI_DBG_INIT,
2222 "hotkey source mask 0x%08x, polling freq %d\n", 2222 "hotkey source mask 0x%08x, polling freq %d\n",
2223 hotkey_source_mask, hotkey_poll_freq); 2223 hotkey_source_mask, hotkey_poll_freq);
2224 #endif 2224 #endif
2225 2225
2226 /* Not all thinkpads have a hardware radio switch */ 2226 /* Not all thinkpads have a hardware radio switch */
2227 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { 2227 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
2228 tp_features.hotkey_wlsw = 1; 2228 tp_features.hotkey_wlsw = 1;
2229 printk(TPACPI_INFO 2229 printk(TPACPI_INFO
2230 "radio switch found; radios are %s\n", 2230 "radio switch found; radios are %s\n",
2231 enabled(status, 0)); 2231 enabled(status, 0));
2232 } 2232 }
2233 if (tp_features.hotkey_wlsw) 2233 if (tp_features.hotkey_wlsw)
2234 res = add_to_attr_set(hotkey_dev_attributes, 2234 res = add_to_attr_set(hotkey_dev_attributes,
2235 &dev_attr_hotkey_radio_sw.attr); 2235 &dev_attr_hotkey_radio_sw.attr);
2236 2236
2237 /* For X41t, X60t, X61t Tablets... */ 2237 /* For X41t, X60t, X61t Tablets... */
2238 if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { 2238 if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
2239 tp_features.hotkey_tablet = 1; 2239 tp_features.hotkey_tablet = 1;
2240 printk(TPACPI_INFO 2240 printk(TPACPI_INFO
2241 "possible tablet mode switch found; " 2241 "possible tablet mode switch found; "
2242 "ThinkPad in %s mode\n", 2242 "ThinkPad in %s mode\n",
2243 (status & TP_HOTKEY_TABLET_MASK)? 2243 (status & TP_HOTKEY_TABLET_MASK)?
2244 "tablet" : "laptop"); 2244 "tablet" : "laptop");
2245 res = add_to_attr_set(hotkey_dev_attributes, 2245 res = add_to_attr_set(hotkey_dev_attributes,
2246 &dev_attr_hotkey_tablet_mode.attr); 2246 &dev_attr_hotkey_tablet_mode.attr);
2247 } 2247 }
2248 2248
2249 if (!res) 2249 if (!res)
2250 res = register_attr_set_with_sysfs( 2250 res = register_attr_set_with_sysfs(
2251 hotkey_dev_attributes, 2251 hotkey_dev_attributes,
2252 &tpacpi_pdev->dev.kobj); 2252 &tpacpi_pdev->dev.kobj);
2253 if (res) 2253 if (res)
2254 goto err_exit; 2254 goto err_exit;
2255 2255
2256 /* Set up key map */ 2256 /* Set up key map */
2257 2257
2258 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, 2258 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
2259 GFP_KERNEL); 2259 GFP_KERNEL);
2260 if (!hotkey_keycode_map) { 2260 if (!hotkey_keycode_map) {
2261 printk(TPACPI_ERR 2261 printk(TPACPI_ERR
2262 "failed to allocate memory for key map\n"); 2262 "failed to allocate memory for key map\n");
2263 res = -ENOMEM; 2263 res = -ENOMEM;
2264 goto err_exit; 2264 goto err_exit;
2265 } 2265 }
2266 2266
2267 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { 2267 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
2268 dbg_printk(TPACPI_DBG_INIT, 2268 dbg_printk(TPACPI_DBG_INIT,
2269 "using Lenovo default hot key map\n"); 2269 "using Lenovo default hot key map\n");
2270 memcpy(hotkey_keycode_map, &lenovo_keycode_map, 2270 memcpy(hotkey_keycode_map, &lenovo_keycode_map,
2271 TPACPI_HOTKEY_MAP_SIZE); 2271 TPACPI_HOTKEY_MAP_SIZE);
2272 } else { 2272 } else {
2273 dbg_printk(TPACPI_DBG_INIT, 2273 dbg_printk(TPACPI_DBG_INIT,
2274 "using IBM default hot key map\n"); 2274 "using IBM default hot key map\n");
2275 memcpy(hotkey_keycode_map, &ibm_keycode_map, 2275 memcpy(hotkey_keycode_map, &ibm_keycode_map,
2276 TPACPI_HOTKEY_MAP_SIZE); 2276 TPACPI_HOTKEY_MAP_SIZE);
2277 } 2277 }
2278 2278
2279 set_bit(EV_KEY, tpacpi_inputdev->evbit); 2279 set_bit(EV_KEY, tpacpi_inputdev->evbit);
2280 set_bit(EV_MSC, tpacpi_inputdev->evbit); 2280 set_bit(EV_MSC, tpacpi_inputdev->evbit);
2281 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); 2281 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
2282 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; 2282 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
2283 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; 2283 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
2284 tpacpi_inputdev->keycode = hotkey_keycode_map; 2284 tpacpi_inputdev->keycode = hotkey_keycode_map;
2285 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { 2285 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
2286 if (hotkey_keycode_map[i] != KEY_RESERVED) { 2286 if (hotkey_keycode_map[i] != KEY_RESERVED) {
2287 set_bit(hotkey_keycode_map[i], 2287 set_bit(hotkey_keycode_map[i],
2288 tpacpi_inputdev->keybit); 2288 tpacpi_inputdev->keybit);
2289 } else { 2289 } else {
2290 if (i < sizeof(hotkey_reserved_mask)*8) 2290 if (i < sizeof(hotkey_reserved_mask)*8)
2291 hotkey_reserved_mask |= 1 << i; 2291 hotkey_reserved_mask |= 1 << i;
2292 } 2292 }
2293 } 2293 }
2294 2294
2295 if (tp_features.hotkey_wlsw) { 2295 if (tp_features.hotkey_wlsw) {
2296 set_bit(EV_SW, tpacpi_inputdev->evbit); 2296 set_bit(EV_SW, tpacpi_inputdev->evbit);
2297 set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit); 2297 set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit);
2298 } 2298 }
2299 if (tp_features.hotkey_tablet) { 2299 if (tp_features.hotkey_tablet) {
2300 set_bit(EV_SW, tpacpi_inputdev->evbit); 2300 set_bit(EV_SW, tpacpi_inputdev->evbit);
2301 set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); 2301 set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit);
2302 } 2302 }
2303 2303
2304 /* Do not issue duplicate brightness change events to 2304 /* Do not issue duplicate brightness change events to
2305 * userspace */ 2305 * userspace */
2306 if (!tp_features.bright_acpimode) 2306 if (!tp_features.bright_acpimode)
2307 /* update bright_acpimode... */ 2307 /* update bright_acpimode... */
2308 tpacpi_check_std_acpi_brightness_support(); 2308 tpacpi_check_std_acpi_brightness_support();
2309 2309
2310 if (tp_features.bright_acpimode) { 2310 if (tp_features.bright_acpimode) {
2311 printk(TPACPI_INFO 2311 printk(TPACPI_INFO
2312 "This ThinkPad has standard ACPI backlight " 2312 "This ThinkPad has standard ACPI backlight "
2313 "brightness control, supported by the ACPI " 2313 "brightness control, supported by the ACPI "
2314 "video driver\n"); 2314 "video driver\n");
2315 printk(TPACPI_NOTICE 2315 printk(TPACPI_NOTICE
2316 "Disabling thinkpad-acpi brightness events " 2316 "Disabling thinkpad-acpi brightness events "
2317 "by default...\n"); 2317 "by default...\n");
2318 2318
2319 /* The hotkey_reserved_mask change below is not 2319 /* The hotkey_reserved_mask change below is not
2320 * necessary while the keys are at KEY_RESERVED in the 2320 * necessary while the keys are at KEY_RESERVED in the
2321 * default map, but better safe than sorry, leave it 2321 * default map, but better safe than sorry, leave it
2322 * here as a marker of what we have to do, especially 2322 * here as a marker of what we have to do, especially
2323 * when we finally become able to set this at runtime 2323 * when we finally become able to set this at runtime
2324 * on response to X.org requests */ 2324 * on response to X.org requests */
2325 hotkey_reserved_mask |= 2325 hotkey_reserved_mask |=
2326 (1 << TP_ACPI_HOTKEYSCAN_FNHOME) 2326 (1 << TP_ACPI_HOTKEYSCAN_FNHOME)
2327 | (1 << TP_ACPI_HOTKEYSCAN_FNEND); 2327 | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
2328 } 2328 }
2329 2329
2330 dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); 2330 dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n");
2331 res = hotkey_status_set(1); 2331 res = hotkey_status_set(1);
2332 if (res) { 2332 if (res) {
2333 hotkey_exit(); 2333 hotkey_exit();
2334 return res; 2334 return res;
2335 } 2335 }
2336 res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) 2336 res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask)
2337 & ~hotkey_reserved_mask) 2337 & ~hotkey_reserved_mask)
2338 | hotkey_orig_mask); 2338 | hotkey_orig_mask);
2339 if (res < 0 && res != -ENXIO) { 2339 if (res < 0 && res != -ENXIO) {
2340 hotkey_exit(); 2340 hotkey_exit();
2341 return res; 2341 return res;
2342 } 2342 }
2343 2343
2344 dbg_printk(TPACPI_DBG_INIT, 2344 dbg_printk(TPACPI_DBG_INIT,
2345 "legacy hot key reporting over procfs %s\n", 2345 "legacy hot key reporting over procfs %s\n",
2346 (hotkey_report_mode < 2) ? 2346 (hotkey_report_mode < 2) ?
2347 "enabled" : "disabled"); 2347 "enabled" : "disabled");
2348 2348
2349 tpacpi_inputdev->open = &hotkey_inputdev_open; 2349 tpacpi_inputdev->open = &hotkey_inputdev_open;
2350 tpacpi_inputdev->close = &hotkey_inputdev_close; 2350 tpacpi_inputdev->close = &hotkey_inputdev_close;
2351 2351
2352 hotkey_poll_setup_safe(1); 2352 hotkey_poll_setup_safe(1);
2353 tpacpi_send_radiosw_update(); 2353 tpacpi_send_radiosw_update();
2354 tpacpi_input_send_tabletsw(); 2354 tpacpi_input_send_tabletsw();
2355 2355
2356 return 0; 2356 return 0;
2357 2357
2358 err_exit: 2358 err_exit:
2359 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); 2359 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj);
2360 hotkey_dev_attributes = NULL; 2360 hotkey_dev_attributes = NULL;
2361 2361
2362 return (res < 0)? res : 1; 2362 return (res < 0)? res : 1;
2363 } 2363 }
2364 2364
2365 static void hotkey_notify(struct ibm_struct *ibm, u32 event) 2365 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
2366 { 2366 {
2367 u32 hkey; 2367 u32 hkey;
2368 unsigned int scancode; 2368 unsigned int scancode;
2369 int send_acpi_ev; 2369 int send_acpi_ev;
2370 int ignore_acpi_ev; 2370 int ignore_acpi_ev;
2371 int unk_ev; 2371 int unk_ev;
2372 2372
2373 if (event != 0x80) { 2373 if (event != 0x80) {
2374 printk(TPACPI_ERR 2374 printk(TPACPI_ERR
2375 "unknown HKEY notification event %d\n", event); 2375 "unknown HKEY notification event %d\n", event);
2376 /* forward it to userspace, maybe it knows how to handle it */ 2376 /* forward it to userspace, maybe it knows how to handle it */
2377 acpi_bus_generate_netlink_event( 2377 acpi_bus_generate_netlink_event(
2378 ibm->acpi->device->pnp.device_class, 2378 ibm->acpi->device->pnp.device_class,
2379 ibm->acpi->device->dev.bus_id, 2379 ibm->acpi->device->dev.bus_id,
2380 event, 0); 2380 event, 0);
2381 return; 2381 return;
2382 } 2382 }
2383 2383
2384 while (1) { 2384 while (1) {
2385 if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { 2385 if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
2386 printk(TPACPI_ERR "failed to retrieve HKEY event\n"); 2386 printk(TPACPI_ERR "failed to retrieve HKEY event\n");
2387 return; 2387 return;
2388 } 2388 }
2389 2389
2390 if (hkey == 0) { 2390 if (hkey == 0) {
2391 /* queue empty */ 2391 /* queue empty */
2392 return; 2392 return;
2393 } 2393 }
2394 2394
2395 send_acpi_ev = 1; 2395 send_acpi_ev = 1;
2396 ignore_acpi_ev = 0; 2396 ignore_acpi_ev = 0;
2397 unk_ev = 0; 2397 unk_ev = 0;
2398 2398
2399 switch (hkey >> 12) { 2399 switch (hkey >> 12) {
2400 case 1: 2400 case 1:
2401 /* 0x1000-0x1FFF: key presses */ 2401 /* 0x1000-0x1FFF: key presses */
2402 scancode = hkey & 0xfff; 2402 scancode = hkey & 0xfff;
2403 if (scancode > 0 && scancode < 0x21) { 2403 if (scancode > 0 && scancode < 0x21) {
2404 scancode--; 2404 scancode--;
2405 if (!(hotkey_source_mask & (1 << scancode))) { 2405 if (!(hotkey_source_mask & (1 << scancode))) {
2406 tpacpi_input_send_key(scancode); 2406 tpacpi_input_send_key(scancode);
2407 send_acpi_ev = 0; 2407 send_acpi_ev = 0;
2408 } else { 2408 } else {
2409 ignore_acpi_ev = 1; 2409 ignore_acpi_ev = 1;
2410 } 2410 }
2411 } else { 2411 } else {
2412 unk_ev = 1; 2412 unk_ev = 1;
2413 } 2413 }
2414 break; 2414 break;
2415 case 2: 2415 case 2:
2416 /* Wakeup reason */ 2416 /* Wakeup reason */
2417 switch (hkey) { 2417 switch (hkey) {
2418 case 0x2304: /* suspend, undock */ 2418 case 0x2304: /* suspend, undock */
2419 case 0x2404: /* hibernation, undock */ 2419 case 0x2404: /* hibernation, undock */
2420 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK; 2420 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK;
2421 ignore_acpi_ev = 1; 2421 ignore_acpi_ev = 1;
2422 break; 2422 break;
2423 case 0x2305: /* suspend, bay eject */ 2423 case 0x2305: /* suspend, bay eject */
2424 case 0x2405: /* hibernation, bay eject */ 2424 case 0x2405: /* hibernation, bay eject */
2425 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ; 2425 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ;
2426 ignore_acpi_ev = 1; 2426 ignore_acpi_ev = 1;
2427 break; 2427 break;
2428 default: 2428 default:
2429 unk_ev = 1; 2429 unk_ev = 1;
2430 } 2430 }
2431 if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) { 2431 if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) {
2432 printk(TPACPI_INFO 2432 printk(TPACPI_INFO
2433 "woke up due to a hot-unplug " 2433 "woke up due to a hot-unplug "
2434 "request...\n"); 2434 "request...\n");
2435 hotkey_wakeup_reason_notify_change(); 2435 hotkey_wakeup_reason_notify_change();
2436 } 2436 }
2437 break; 2437 break;
2438 case 3: 2438 case 3:
2439 /* bay-related wakeups */ 2439 /* bay-related wakeups */
2440 if (hkey == 0x3003) { 2440 if (hkey == 0x3003) {
2441 hotkey_autosleep_ack = 1; 2441 hotkey_autosleep_ack = 1;
2442 printk(TPACPI_INFO 2442 printk(TPACPI_INFO
2443 "bay ejected\n"); 2443 "bay ejected\n");
2444 hotkey_wakeup_hotunplug_complete_notify_change(); 2444 hotkey_wakeup_hotunplug_complete_notify_change();
2445 } else { 2445 } else {
2446 unk_ev = 1; 2446 unk_ev = 1;
2447 } 2447 }
2448 break; 2448 break;
2449 case 4: 2449 case 4:
2450 /* dock-related wakeups */ 2450 /* dock-related wakeups */
2451 if (hkey == 0x4003) { 2451 if (hkey == 0x4003) {
2452 hotkey_autosleep_ack = 1; 2452 hotkey_autosleep_ack = 1;
2453 printk(TPACPI_INFO 2453 printk(TPACPI_INFO
2454 "undocked\n"); 2454 "undocked\n");
2455 hotkey_wakeup_hotunplug_complete_notify_change(); 2455 hotkey_wakeup_hotunplug_complete_notify_change();
2456 } else { 2456 } else {
2457 unk_ev = 1; 2457 unk_ev = 1;
2458 } 2458 }
2459 break; 2459 break;
2460 case 5: 2460 case 5:
2461 /* 0x5000-0x5FFF: human interface helpers */ 2461 /* 0x5000-0x5FFF: human interface helpers */
2462 switch (hkey) { 2462 switch (hkey) {
2463 case 0x5010: /* Lenovo new BIOS: brightness changed */ 2463 case 0x5010: /* Lenovo new BIOS: brightness changed */
2464 case 0x500b: /* X61t: tablet pen inserted into bay */ 2464 case 0x500b: /* X61t: tablet pen inserted into bay */
2465 case 0x500c: /* X61t: tablet pen removed from bay */ 2465 case 0x500c: /* X61t: tablet pen removed from bay */
2466 break; 2466 break;
2467 case 0x5009: /* X41t-X61t: swivel up (tablet mode) */ 2467 case 0x5009: /* X41t-X61t: swivel up (tablet mode) */
2468 case 0x500a: /* X41t-X61t: swivel down (normal mode) */ 2468 case 0x500a: /* X41t-X61t: swivel down (normal mode) */
2469 tpacpi_input_send_tabletsw(); 2469 tpacpi_input_send_tabletsw();
2470 hotkey_tablet_mode_notify_change(); 2470 hotkey_tablet_mode_notify_change();
2471 send_acpi_ev = 0; 2471 send_acpi_ev = 0;
2472 break; 2472 break;
2473 case 0x5001: 2473 case 0x5001:
2474 case 0x5002: 2474 case 0x5002:
2475 /* LID switch events. Do not propagate */ 2475 /* LID switch events. Do not propagate */
2476 ignore_acpi_ev = 1; 2476 ignore_acpi_ev = 1;
2477 break; 2477 break;
2478 default: 2478 default:
2479 unk_ev = 1; 2479 unk_ev = 1;
2480 } 2480 }
2481 break; 2481 break;
2482 case 7: 2482 case 7:
2483 /* 0x7000-0x7FFF: misc */ 2483 /* 0x7000-0x7FFF: misc */
2484 if (tp_features.hotkey_wlsw && hkey == 0x7000) { 2484 if (tp_features.hotkey_wlsw && hkey == 0x7000) {
2485 tpacpi_send_radiosw_update(); 2485 tpacpi_send_radiosw_update();
2486 send_acpi_ev = 0; 2486 send_acpi_ev = 0;
2487 break; 2487 break;
2488 } 2488 }
2489 /* fallthrough to default */ 2489 /* fallthrough to default */
2490 default: 2490 default:
2491 unk_ev = 1; 2491 unk_ev = 1;
2492 } 2492 }
2493 if (unk_ev) { 2493 if (unk_ev) {
2494 printk(TPACPI_NOTICE 2494 printk(TPACPI_NOTICE
2495 "unhandled HKEY event 0x%04x\n", hkey); 2495 "unhandled HKEY event 0x%04x\n", hkey);
2496 } 2496 }
2497 2497
2498 /* Legacy events */ 2498 /* Legacy events */
2499 if (!ignore_acpi_ev && 2499 if (!ignore_acpi_ev &&
2500 (send_acpi_ev || hotkey_report_mode < 2)) { 2500 (send_acpi_ev || hotkey_report_mode < 2)) {
2501 acpi_bus_generate_proc_event(ibm->acpi->device, 2501 acpi_bus_generate_proc_event(ibm->acpi->device,
2502 event, hkey); 2502 event, hkey);
2503 } 2503 }
2504 2504
2505 /* netlink events */ 2505 /* netlink events */
2506 if (!ignore_acpi_ev && send_acpi_ev) { 2506 if (!ignore_acpi_ev && send_acpi_ev) {
2507 acpi_bus_generate_netlink_event( 2507 acpi_bus_generate_netlink_event(
2508 ibm->acpi->device->pnp.device_class, 2508 ibm->acpi->device->pnp.device_class,
2509 ibm->acpi->device->dev.bus_id, 2509 ibm->acpi->device->dev.bus_id,
2510 event, hkey); 2510 event, hkey);
2511 } 2511 }
2512 } 2512 }
2513 } 2513 }
2514 2514
2515 static void hotkey_suspend(pm_message_t state) 2515 static void hotkey_suspend(pm_message_t state)
2516 { 2516 {
2517 /* Do these on suspend, we get the events on early resume! */ 2517 /* Do these on suspend, we get the events on early resume! */
2518 hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE; 2518 hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE;
2519 hotkey_autosleep_ack = 0; 2519 hotkey_autosleep_ack = 0;
2520 } 2520 }
2521 2521
2522 static void hotkey_resume(void) 2522 static void hotkey_resume(void)
2523 { 2523 {
2524 tpacpi_disable_brightness_delay(); 2524 tpacpi_disable_brightness_delay();
2525 2525
2526 if (hotkey_mask_get()) 2526 if (hotkey_mask_get())
2527 printk(TPACPI_ERR 2527 printk(TPACPI_ERR
2528 "error while trying to read hot key mask " 2528 "error while trying to read hot key mask "
2529 "from firmware\n"); 2529 "from firmware\n");
2530 tpacpi_send_radiosw_update(); 2530 tpacpi_send_radiosw_update();
2531 hotkey_tablet_mode_notify_change(); 2531 hotkey_tablet_mode_notify_change();
2532 hotkey_wakeup_reason_notify_change(); 2532 hotkey_wakeup_reason_notify_change();
2533 hotkey_wakeup_hotunplug_complete_notify_change(); 2533 hotkey_wakeup_hotunplug_complete_notify_change();
2534 hotkey_poll_setup_safe(0); 2534 hotkey_poll_setup_safe(0);
2535 } 2535 }
2536 2536
2537 /* procfs -------------------------------------------------------------- */ 2537 /* procfs -------------------------------------------------------------- */
2538 static int hotkey_read(char *p) 2538 static int hotkey_read(char *p)
2539 { 2539 {
2540 int res, status; 2540 int res, status;
2541 int len = 0; 2541 int len = 0;
2542 2542
2543 if (!tp_features.hotkey) { 2543 if (!tp_features.hotkey) {
2544 len += sprintf(p + len, "status:\t\tnot supported\n"); 2544 len += sprintf(p + len, "status:\t\tnot supported\n");
2545 return len; 2545 return len;
2546 } 2546 }
2547 2547
2548 if (mutex_lock_interruptible(&hotkey_mutex)) 2548 if (mutex_lock_interruptible(&hotkey_mutex))
2549 return -ERESTARTSYS; 2549 return -ERESTARTSYS;
2550 res = hotkey_status_get(&status); 2550 res = hotkey_status_get(&status);
2551 if (!res) 2551 if (!res)
2552 res = hotkey_mask_get(); 2552 res = hotkey_mask_get();
2553 mutex_unlock(&hotkey_mutex); 2553 mutex_unlock(&hotkey_mutex);
2554 if (res) 2554 if (res)
2555 return res; 2555 return res;
2556 2556
2557 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 2557 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
2558 if (tp_features.hotkey_mask) { 2558 if (tp_features.hotkey_mask) {
2559 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask); 2559 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask);
2560 len += sprintf(p + len, 2560 len += sprintf(p + len,
2561 "commands:\tenable, disable, reset, <mask>\n"); 2561 "commands:\tenable, disable, reset, <mask>\n");
2562 } else { 2562 } else {
2563 len += sprintf(p + len, "mask:\t\tnot supported\n"); 2563 len += sprintf(p + len, "mask:\t\tnot supported\n");
2564 len += sprintf(p + len, "commands:\tenable, disable, reset\n"); 2564 len += sprintf(p + len, "commands:\tenable, disable, reset\n");
2565 } 2565 }
2566 2566
2567 return len; 2567 return len;
2568 } 2568 }
2569 2569
2570 static int hotkey_write(char *buf) 2570 static int hotkey_write(char *buf)
2571 { 2571 {
2572 int res, status; 2572 int res, status;
2573 u32 mask; 2573 u32 mask;
2574 char *cmd; 2574 char *cmd;
2575 2575
2576 if (!tp_features.hotkey) 2576 if (!tp_features.hotkey)
2577 return -ENODEV; 2577 return -ENODEV;
2578 2578
2579 if (mutex_lock_interruptible(&hotkey_mutex)) 2579 if (mutex_lock_interruptible(&hotkey_mutex))
2580 return -ERESTARTSYS; 2580 return -ERESTARTSYS;
2581 2581
2582 status = -1; 2582 status = -1;
2583 mask = hotkey_mask; 2583 mask = hotkey_mask;
2584 2584
2585 res = 0; 2585 res = 0;
2586 while ((cmd = next_cmd(&buf))) { 2586 while ((cmd = next_cmd(&buf))) {
2587 if (strlencmp(cmd, "enable") == 0) { 2587 if (strlencmp(cmd, "enable") == 0) {
2588 status = 1; 2588 status = 1;
2589 } else if (strlencmp(cmd, "disable") == 0) { 2589 } else if (strlencmp(cmd, "disable") == 0) {
2590 status = 0; 2590 status = 0;
2591 } else if (strlencmp(cmd, "reset") == 0) { 2591 } else if (strlencmp(cmd, "reset") == 0) {
2592 status = hotkey_orig_status; 2592 status = hotkey_orig_status;
2593 mask = hotkey_orig_mask; 2593 mask = hotkey_orig_mask;
2594 } else if (sscanf(cmd, "0x%x", &mask) == 1) { 2594 } else if (sscanf(cmd, "0x%x", &mask) == 1) {
2595 /* mask set */ 2595 /* mask set */
2596 } else if (sscanf(cmd, "%x", &mask) == 1) { 2596 } else if (sscanf(cmd, "%x", &mask) == 1) {
2597 /* mask set */ 2597 /* mask set */
2598 } else { 2598 } else {
2599 res = -EINVAL; 2599 res = -EINVAL;
2600 goto errexit; 2600 goto errexit;
2601 } 2601 }
2602 } 2602 }
2603 if (status != -1) 2603 if (status != -1)
2604 res = hotkey_status_set(status); 2604 res = hotkey_status_set(status);
2605 2605
2606 if (!res && mask != hotkey_mask) 2606 if (!res && mask != hotkey_mask)
2607 res = hotkey_mask_set(mask); 2607 res = hotkey_mask_set(mask);
2608 2608
2609 errexit: 2609 errexit:
2610 mutex_unlock(&hotkey_mutex); 2610 mutex_unlock(&hotkey_mutex);
2611 return res; 2611 return res;
2612 } 2612 }
2613 2613
2614 static const struct acpi_device_id ibm_htk_device_ids[] = { 2614 static const struct acpi_device_id ibm_htk_device_ids[] = {
2615 {TPACPI_ACPI_HKEY_HID, 0}, 2615 {TPACPI_ACPI_HKEY_HID, 0},
2616 {"", 0}, 2616 {"", 0},
2617 }; 2617 };
2618 2618
2619 static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = { 2619 static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
2620 .hid = ibm_htk_device_ids, 2620 .hid = ibm_htk_device_ids,
2621 .notify = hotkey_notify, 2621 .notify = hotkey_notify,
2622 .handle = &hkey_handle, 2622 .handle = &hkey_handle,
2623 .type = ACPI_DEVICE_NOTIFY, 2623 .type = ACPI_DEVICE_NOTIFY,
2624 }; 2624 };
2625 2625
2626 static struct ibm_struct hotkey_driver_data = { 2626 static struct ibm_struct hotkey_driver_data = {
2627 .name = "hotkey", 2627 .name = "hotkey",
2628 .read = hotkey_read, 2628 .read = hotkey_read,
2629 .write = hotkey_write, 2629 .write = hotkey_write,
2630 .exit = hotkey_exit, 2630 .exit = hotkey_exit,
2631 .resume = hotkey_resume, 2631 .resume = hotkey_resume,
2632 .suspend = hotkey_suspend, 2632 .suspend = hotkey_suspend,
2633 .acpi = &ibm_hotkey_acpidriver, 2633 .acpi = &ibm_hotkey_acpidriver,
2634 }; 2634 };
2635 2635
2636 /************************************************************************* 2636 /*************************************************************************
2637 * Bluetooth subdriver 2637 * Bluetooth subdriver
2638 */ 2638 */
2639 2639
2640 enum { 2640 enum {
2641 /* ACPI GBDC/SBDC bits */ 2641 /* ACPI GBDC/SBDC bits */
2642 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ 2642 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
2643 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ 2643 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */
2644 TP_ACPI_BLUETOOTH_UNK = 0x04, /* unknown function */ 2644 TP_ACPI_BLUETOOTH_UNK = 0x04, /* unknown function */
2645 }; 2645 };
2646 2646
2647 static struct rfkill *tpacpi_bluetooth_rfkill; 2647 static struct rfkill *tpacpi_bluetooth_rfkill;
2648 2648
2649 static int bluetooth_get_radiosw(void) 2649 static int bluetooth_get_radiosw(void)
2650 { 2650 {
2651 int status; 2651 int status;
2652 2652
2653 if (!tp_features.bluetooth) 2653 if (!tp_features.bluetooth)
2654 return -ENODEV; 2654 return -ENODEV;
2655 2655
2656 /* WLSW overrides bluetooth in firmware/hardware, reflect that */ 2656 /* WLSW overrides bluetooth in firmware/hardware, reflect that */
2657 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) 2657 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
2658 return RFKILL_STATE_HARD_BLOCKED; 2658 return RFKILL_STATE_HARD_BLOCKED;
2659 2659
2660 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 2660 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
2661 return -EIO; 2661 return -EIO;
2662 2662
2663 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ? 2663 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ?
2664 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 2664 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
2665 } 2665 }
2666 2666
2667 static void bluetooth_update_rfk(void) 2667 static void bluetooth_update_rfk(void)
2668 { 2668 {
2669 int status; 2669 int status;
2670 2670
2671 if (!tpacpi_bluetooth_rfkill) 2671 if (!tpacpi_bluetooth_rfkill)
2672 return; 2672 return;
2673 2673
2674 status = bluetooth_get_radiosw(); 2674 status = bluetooth_get_radiosw();
2675 if (status < 0) 2675 if (status < 0)
2676 return; 2676 return;
2677 rfkill_force_state(tpacpi_bluetooth_rfkill, status); 2677 rfkill_force_state(tpacpi_bluetooth_rfkill, status);
2678 } 2678 }
2679 2679
2680 static int bluetooth_set_radiosw(int radio_on, int update_rfk) 2680 static int bluetooth_set_radiosw(int radio_on, int update_rfk)
2681 { 2681 {
2682 int status; 2682 int status;
2683 2683
2684 if (!tp_features.bluetooth) 2684 if (!tp_features.bluetooth)
2685 return -ENODEV; 2685 return -ENODEV;
2686 2686
2687 /* WLSW overrides bluetooth in firmware/hardware, but there is no 2687 /* WLSW overrides bluetooth in firmware/hardware, but there is no
2688 * reason to risk weird behaviour. */ 2688 * reason to risk weird behaviour. */
2689 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status 2689 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
2690 && radio_on) 2690 && radio_on)
2691 return -EPERM; 2691 return -EPERM;
2692 2692
2693 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 2693 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
2694 return -EIO; 2694 return -EIO;
2695 if (radio_on) 2695 if (radio_on)
2696 status |= TP_ACPI_BLUETOOTH_RADIOSSW; 2696 status |= TP_ACPI_BLUETOOTH_RADIOSSW;
2697 else 2697 else
2698 status &= ~TP_ACPI_BLUETOOTH_RADIOSSW; 2698 status &= ~TP_ACPI_BLUETOOTH_RADIOSSW;
2699 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 2699 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
2700 return -EIO; 2700 return -EIO;
2701 2701
2702 if (update_rfk) 2702 if (update_rfk)
2703 bluetooth_update_rfk(); 2703 bluetooth_update_rfk();
2704 2704
2705 return 0; 2705 return 0;
2706 } 2706 }
2707 2707
2708 /* sysfs bluetooth enable ---------------------------------------------- */ 2708 /* sysfs bluetooth enable ---------------------------------------------- */
2709 static ssize_t bluetooth_enable_show(struct device *dev, 2709 static ssize_t bluetooth_enable_show(struct device *dev,
2710 struct device_attribute *attr, 2710 struct device_attribute *attr,
2711 char *buf) 2711 char *buf)
2712 { 2712 {
2713 int status; 2713 int status;
2714 2714
2715 status = bluetooth_get_radiosw(); 2715 status = bluetooth_get_radiosw();
2716 if (status < 0) 2716 if (status < 0)
2717 return status; 2717 return status;
2718 2718
2719 return snprintf(buf, PAGE_SIZE, "%d\n", 2719 return snprintf(buf, PAGE_SIZE, "%d\n",
2720 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0); 2720 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
2721 } 2721 }
2722 2722
2723 static ssize_t bluetooth_enable_store(struct device *dev, 2723 static ssize_t bluetooth_enable_store(struct device *dev,
2724 struct device_attribute *attr, 2724 struct device_attribute *attr,
2725 const char *buf, size_t count) 2725 const char *buf, size_t count)
2726 { 2726 {
2727 unsigned long t; 2727 unsigned long t;
2728 int res; 2728 int res;
2729 2729
2730 if (parse_strtoul(buf, 1, &t)) 2730 if (parse_strtoul(buf, 1, &t))
2731 return -EINVAL; 2731 return -EINVAL;
2732 2732
2733 res = bluetooth_set_radiosw(t, 1); 2733 res = bluetooth_set_radiosw(t, 1);
2734 2734
2735 return (res) ? res : count; 2735 return (res) ? res : count;
2736 } 2736 }
2737 2737
2738 static struct device_attribute dev_attr_bluetooth_enable = 2738 static struct device_attribute dev_attr_bluetooth_enable =
2739 __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO, 2739 __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO,
2740 bluetooth_enable_show, bluetooth_enable_store); 2740 bluetooth_enable_show, bluetooth_enable_store);
2741 2741
2742 /* --------------------------------------------------------------------- */ 2742 /* --------------------------------------------------------------------- */
2743 2743
2744 static struct attribute *bluetooth_attributes[] = { 2744 static struct attribute *bluetooth_attributes[] = {
2745 &dev_attr_bluetooth_enable.attr, 2745 &dev_attr_bluetooth_enable.attr,
2746 NULL 2746 NULL
2747 }; 2747 };
2748 2748
2749 static const struct attribute_group bluetooth_attr_group = { 2749 static const struct attribute_group bluetooth_attr_group = {
2750 .attrs = bluetooth_attributes, 2750 .attrs = bluetooth_attributes,
2751 }; 2751 };
2752 2752
2753 static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state) 2753 static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state)
2754 { 2754 {
2755 int bts = bluetooth_get_radiosw(); 2755 int bts = bluetooth_get_radiosw();
2756 2756
2757 if (bts < 0) 2757 if (bts < 0)
2758 return bts; 2758 return bts;
2759 2759
2760 *state = bts; 2760 *state = bts;
2761 return 0; 2761 return 0;
2762 } 2762 }
2763 2763
2764 static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state) 2764 static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
2765 { 2765 {
2766 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); 2766 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
2767 } 2767 }
2768 2768
2769 static void bluetooth_exit(void) 2769 static void bluetooth_exit(void)
2770 { 2770 {
2771 if (tpacpi_bluetooth_rfkill) 2771 if (tpacpi_bluetooth_rfkill)
2772 rfkill_unregister(tpacpi_bluetooth_rfkill); 2772 rfkill_unregister(tpacpi_bluetooth_rfkill);
2773 2773
2774 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 2774 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
2775 &bluetooth_attr_group); 2775 &bluetooth_attr_group);
2776 } 2776 }
2777 2777
2778 static int __init bluetooth_init(struct ibm_init_struct *iibm) 2778 static int __init bluetooth_init(struct ibm_init_struct *iibm)
2779 { 2779 {
2780 int res; 2780 int res;
2781 int status = 0; 2781 int status = 0;
2782 2782
2783 vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n"); 2783 vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
2784 2784
2785 TPACPI_ACPIHANDLE_INIT(hkey); 2785 TPACPI_ACPIHANDLE_INIT(hkey);
2786 2786
2787 /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 2787 /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
2788 G4x, R30, R31, R40e, R50e, T20-22, X20-21 */ 2788 G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
2789 tp_features.bluetooth = hkey_handle && 2789 tp_features.bluetooth = hkey_handle &&
2790 acpi_evalf(hkey_handle, &status, "GBDC", "qd"); 2790 acpi_evalf(hkey_handle, &status, "GBDC", "qd");
2791 2791
2792 vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n", 2792 vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
2793 str_supported(tp_features.bluetooth), 2793 str_supported(tp_features.bluetooth),
2794 status); 2794 status);
2795 2795
2796 if (tp_features.bluetooth && 2796 if (tp_features.bluetooth &&
2797 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { 2797 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
2798 /* no bluetooth hardware present in system */ 2798 /* no bluetooth hardware present in system */
2799 tp_features.bluetooth = 0; 2799 tp_features.bluetooth = 0;
2800 dbg_printk(TPACPI_DBG_INIT, 2800 dbg_printk(TPACPI_DBG_INIT,
2801 "bluetooth hardware not installed\n"); 2801 "bluetooth hardware not installed\n");
2802 } 2802 }
2803 2803
2804 if (!tp_features.bluetooth) 2804 if (!tp_features.bluetooth)
2805 return 1; 2805 return 1;
2806 2806
2807 res = sysfs_create_group(&tpacpi_pdev->dev.kobj, 2807 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
2808 &bluetooth_attr_group); 2808 &bluetooth_attr_group);
2809 if (res) 2809 if (res)
2810 return res; 2810 return res;
2811 2811
2812 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, 2812 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
2813 &tpacpi_bluetooth_rfkill, 2813 &tpacpi_bluetooth_rfkill,
2814 RFKILL_TYPE_BLUETOOTH, 2814 RFKILL_TYPE_BLUETOOTH,
2815 "tpacpi_bluetooth_sw", 2815 "tpacpi_bluetooth_sw",
2816 tpacpi_bluetooth_rfk_set, 2816 tpacpi_bluetooth_rfk_set,
2817 tpacpi_bluetooth_rfk_get); 2817 tpacpi_bluetooth_rfk_get);
2818 if (res) { 2818 if (res) {
2819 bluetooth_exit(); 2819 bluetooth_exit();
2820 return res; 2820 return res;
2821 } 2821 }
2822 2822
2823 return 0; 2823 return 0;
2824 } 2824 }
2825 2825
2826 /* procfs -------------------------------------------------------------- */ 2826 /* procfs -------------------------------------------------------------- */
2827 static int bluetooth_read(char *p) 2827 static int bluetooth_read(char *p)
2828 { 2828 {
2829 int len = 0; 2829 int len = 0;
2830 int status = bluetooth_get_radiosw(); 2830 int status = bluetooth_get_radiosw();
2831 2831
2832 if (!tp_features.bluetooth) 2832 if (!tp_features.bluetooth)
2833 len += sprintf(p + len, "status:\t\tnot supported\n"); 2833 len += sprintf(p + len, "status:\t\tnot supported\n");
2834 else { 2834 else {
2835 len += sprintf(p + len, "status:\t\t%s\n", 2835 len += sprintf(p + len, "status:\t\t%s\n",
2836 (status == RFKILL_STATE_UNBLOCKED) ? 2836 (status == RFKILL_STATE_UNBLOCKED) ?
2837 "enabled" : "disabled"); 2837 "enabled" : "disabled");
2838 len += sprintf(p + len, "commands:\tenable, disable\n"); 2838 len += sprintf(p + len, "commands:\tenable, disable\n");
2839 } 2839 }
2840 2840
2841 return len; 2841 return len;
2842 } 2842 }
2843 2843
2844 static int bluetooth_write(char *buf) 2844 static int bluetooth_write(char *buf)
2845 { 2845 {
2846 char *cmd; 2846 char *cmd;
2847 2847
2848 if (!tp_features.bluetooth) 2848 if (!tp_features.bluetooth)
2849 return -ENODEV; 2849 return -ENODEV;
2850 2850
2851 while ((cmd = next_cmd(&buf))) { 2851 while ((cmd = next_cmd(&buf))) {
2852 if (strlencmp(cmd, "enable") == 0) { 2852 if (strlencmp(cmd, "enable") == 0) {
2853 bluetooth_set_radiosw(1, 1); 2853 bluetooth_set_radiosw(1, 1);
2854 } else if (strlencmp(cmd, "disable") == 0) { 2854 } else if (strlencmp(cmd, "disable") == 0) {
2855 bluetooth_set_radiosw(0, 1); 2855 bluetooth_set_radiosw(0, 1);
2856 } else 2856 } else
2857 return -EINVAL; 2857 return -EINVAL;
2858 } 2858 }
2859 2859
2860 return 0; 2860 return 0;
2861 } 2861 }
2862 2862
2863 static struct ibm_struct bluetooth_driver_data = { 2863 static struct ibm_struct bluetooth_driver_data = {
2864 .name = "bluetooth", 2864 .name = "bluetooth",
2865 .read = bluetooth_read, 2865 .read = bluetooth_read,
2866 .write = bluetooth_write, 2866 .write = bluetooth_write,
2867 .exit = bluetooth_exit, 2867 .exit = bluetooth_exit,
2868 }; 2868 };
2869 2869
2870 /************************************************************************* 2870 /*************************************************************************
2871 * Wan subdriver 2871 * Wan subdriver
2872 */ 2872 */
2873 2873
2874 enum { 2874 enum {
2875 /* ACPI GWAN/SWAN bits */ 2875 /* ACPI GWAN/SWAN bits */
2876 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ 2876 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
2877 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ 2877 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */
2878 TP_ACPI_WANCARD_UNK = 0x04, /* unknown function */ 2878 TP_ACPI_WANCARD_UNK = 0x04, /* unknown function */
2879 }; 2879 };
2880 2880
2881 static struct rfkill *tpacpi_wan_rfkill; 2881 static struct rfkill *tpacpi_wan_rfkill;
2882 2882
2883 static int wan_get_radiosw(void) 2883 static int wan_get_radiosw(void)
2884 { 2884 {
2885 int status; 2885 int status;
2886 2886
2887 if (!tp_features.wan) 2887 if (!tp_features.wan)
2888 return -ENODEV; 2888 return -ENODEV;
2889 2889
2890 /* WLSW overrides WWAN in firmware/hardware, reflect that */ 2890 /* WLSW overrides WWAN in firmware/hardware, reflect that */
2891 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) 2891 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
2892 return RFKILL_STATE_HARD_BLOCKED; 2892 return RFKILL_STATE_HARD_BLOCKED;
2893 2893
2894 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 2894 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
2895 return -EIO; 2895 return -EIO;
2896 2896
2897 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ? 2897 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ?
2898 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 2898 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
2899 } 2899 }
2900 2900
2901 static void wan_update_rfk(void) 2901 static void wan_update_rfk(void)
2902 { 2902 {
2903 int status; 2903 int status;
2904 2904
2905 if (!tpacpi_wan_rfkill) 2905 if (!tpacpi_wan_rfkill)
2906 return; 2906 return;
2907 2907
2908 status = wan_get_radiosw(); 2908 status = wan_get_radiosw();
2909 if (status < 0) 2909 if (status < 0)
2910 return; 2910 return;
2911 rfkill_force_state(tpacpi_wan_rfkill, status); 2911 rfkill_force_state(tpacpi_wan_rfkill, status);
2912 } 2912 }
2913 2913
2914 static int wan_set_radiosw(int radio_on, int update_rfk) 2914 static int wan_set_radiosw(int radio_on, int update_rfk)
2915 { 2915 {
2916 int status; 2916 int status;
2917 2917
2918 if (!tp_features.wan) 2918 if (!tp_features.wan)
2919 return -ENODEV; 2919 return -ENODEV;
2920 2920
2921 /* WLSW overrides bluetooth in firmware/hardware, but there is no 2921 /* WLSW overrides bluetooth in firmware/hardware, but there is no
2922 * reason to risk weird behaviour. */ 2922 * reason to risk weird behaviour. */
2923 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status 2923 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
2924 && radio_on) 2924 && radio_on)
2925 return -EPERM; 2925 return -EPERM;
2926 2926
2927 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 2927 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
2928 return -EIO; 2928 return -EIO;
2929 if (radio_on) 2929 if (radio_on)
2930 status |= TP_ACPI_WANCARD_RADIOSSW; 2930 status |= TP_ACPI_WANCARD_RADIOSSW;
2931 else 2931 else
2932 status &= ~TP_ACPI_WANCARD_RADIOSSW; 2932 status &= ~TP_ACPI_WANCARD_RADIOSSW;
2933 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 2933 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
2934 return -EIO; 2934 return -EIO;
2935 2935
2936 if (update_rfk) 2936 if (update_rfk)
2937 wan_update_rfk(); 2937 wan_update_rfk();
2938 2938
2939 return 0; 2939 return 0;
2940 } 2940 }
2941 2941
2942 /* sysfs wan enable ---------------------------------------------------- */ 2942 /* sysfs wan enable ---------------------------------------------------- */
2943 static ssize_t wan_enable_show(struct device *dev, 2943 static ssize_t wan_enable_show(struct device *dev,
2944 struct device_attribute *attr, 2944 struct device_attribute *attr,
2945 char *buf) 2945 char *buf)
2946 { 2946 {
2947 int status; 2947 int status;
2948 2948
2949 status = wan_get_radiosw(); 2949 status = wan_get_radiosw();
2950 if (status < 0) 2950 if (status < 0)
2951 return status; 2951 return status;
2952 2952
2953 return snprintf(buf, PAGE_SIZE, "%d\n", 2953 return snprintf(buf, PAGE_SIZE, "%d\n",
2954 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0); 2954 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
2955 } 2955 }
2956 2956
2957 static ssize_t wan_enable_store(struct device *dev, 2957 static ssize_t wan_enable_store(struct device *dev,
2958 struct device_attribute *attr, 2958 struct device_attribute *attr,
2959 const char *buf, size_t count) 2959 const char *buf, size_t count)
2960 { 2960 {
2961 unsigned long t; 2961 unsigned long t;
2962 int res; 2962 int res;
2963 2963
2964 if (parse_strtoul(buf, 1, &t)) 2964 if (parse_strtoul(buf, 1, &t))
2965 return -EINVAL; 2965 return -EINVAL;
2966 2966
2967 res = wan_set_radiosw(t, 1); 2967 res = wan_set_radiosw(t, 1);
2968 2968
2969 return (res) ? res : count; 2969 return (res) ? res : count;
2970 } 2970 }
2971 2971
2972 static struct device_attribute dev_attr_wan_enable = 2972 static struct device_attribute dev_attr_wan_enable =
2973 __ATTR(wwan_enable, S_IWUSR | S_IRUGO, 2973 __ATTR(wwan_enable, S_IWUSR | S_IRUGO,
2974 wan_enable_show, wan_enable_store); 2974 wan_enable_show, wan_enable_store);
2975 2975
2976 /* --------------------------------------------------------------------- */ 2976 /* --------------------------------------------------------------------- */
2977 2977
2978 static struct attribute *wan_attributes[] = { 2978 static struct attribute *wan_attributes[] = {
2979 &dev_attr_wan_enable.attr, 2979 &dev_attr_wan_enable.attr,
2980 NULL 2980 NULL
2981 }; 2981 };
2982 2982
2983 static const struct attribute_group wan_attr_group = { 2983 static const struct attribute_group wan_attr_group = {
2984 .attrs = wan_attributes, 2984 .attrs = wan_attributes,
2985 }; 2985 };
2986 2986
2987 static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state) 2987 static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state)
2988 { 2988 {
2989 int wans = wan_get_radiosw(); 2989 int wans = wan_get_radiosw();
2990 2990
2991 if (wans < 0) 2991 if (wans < 0)
2992 return wans; 2992 return wans;
2993 2993
2994 *state = wans; 2994 *state = wans;
2995 return 0; 2995 return 0;
2996 } 2996 }
2997 2997
2998 static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state) 2998 static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
2999 { 2999 {
3000 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); 3000 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3001 } 3001 }
3002 3002
3003 static void wan_exit(void) 3003 static void wan_exit(void)
3004 { 3004 {
3005 if (tpacpi_wan_rfkill) 3005 if (tpacpi_wan_rfkill)
3006 rfkill_unregister(tpacpi_wan_rfkill); 3006 rfkill_unregister(tpacpi_wan_rfkill);
3007 3007
3008 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3008 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3009 &wan_attr_group); 3009 &wan_attr_group);
3010 } 3010 }
3011 3011
3012 static int __init wan_init(struct ibm_init_struct *iibm) 3012 static int __init wan_init(struct ibm_init_struct *iibm)
3013 { 3013 {
3014 int res; 3014 int res;
3015 int status = 0; 3015 int status = 0;
3016 3016
3017 vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n"); 3017 vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
3018 3018
3019 TPACPI_ACPIHANDLE_INIT(hkey); 3019 TPACPI_ACPIHANDLE_INIT(hkey);
3020 3020
3021 tp_features.wan = hkey_handle && 3021 tp_features.wan = hkey_handle &&
3022 acpi_evalf(hkey_handle, &status, "GWAN", "qd"); 3022 acpi_evalf(hkey_handle, &status, "GWAN", "qd");
3023 3023
3024 vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n", 3024 vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
3025 str_supported(tp_features.wan), 3025 str_supported(tp_features.wan),
3026 status); 3026 status);
3027 3027
3028 if (tp_features.wan && 3028 if (tp_features.wan &&
3029 !(status & TP_ACPI_WANCARD_HWPRESENT)) { 3029 !(status & TP_ACPI_WANCARD_HWPRESENT)) {
3030 /* no wan hardware present in system */ 3030 /* no wan hardware present in system */
3031 tp_features.wan = 0; 3031 tp_features.wan = 0;
3032 dbg_printk(TPACPI_DBG_INIT, 3032 dbg_printk(TPACPI_DBG_INIT,
3033 "wan hardware not installed\n"); 3033 "wan hardware not installed\n");
3034 } 3034 }
3035 3035
3036 if (!tp_features.wan) 3036 if (!tp_features.wan)
3037 return 1; 3037 return 1;
3038 3038
3039 res = sysfs_create_group(&tpacpi_pdev->dev.kobj, 3039 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3040 &wan_attr_group); 3040 &wan_attr_group);
3041 if (res) 3041 if (res)
3042 return res; 3042 return res;
3043 3043
3044 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, 3044 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
3045 &tpacpi_wan_rfkill, 3045 &tpacpi_wan_rfkill,
3046 RFKILL_TYPE_WWAN, 3046 RFKILL_TYPE_WWAN,
3047 "tpacpi_wwan_sw", 3047 "tpacpi_wwan_sw",
3048 tpacpi_wan_rfk_set, 3048 tpacpi_wan_rfk_set,
3049 tpacpi_wan_rfk_get); 3049 tpacpi_wan_rfk_get);
3050 if (res) { 3050 if (res) {
3051 wan_exit(); 3051 wan_exit();
3052 return res; 3052 return res;
3053 } 3053 }
3054 3054
3055 return 0; 3055 return 0;
3056 } 3056 }
3057 3057
3058 /* procfs -------------------------------------------------------------- */ 3058 /* procfs -------------------------------------------------------------- */
3059 static int wan_read(char *p) 3059 static int wan_read(char *p)
3060 { 3060 {
3061 int len = 0; 3061 int len = 0;
3062 int status = wan_get_radiosw(); 3062 int status = wan_get_radiosw();
3063 3063
3064 if (!tp_features.wan) 3064 if (!tp_features.wan)
3065 len += sprintf(p + len, "status:\t\tnot supported\n"); 3065 len += sprintf(p + len, "status:\t\tnot supported\n");
3066 else { 3066 else {
3067 len += sprintf(p + len, "status:\t\t%s\n", 3067 len += sprintf(p + len, "status:\t\t%s\n",
3068 (status == RFKILL_STATE_UNBLOCKED) ? 3068 (status == RFKILL_STATE_UNBLOCKED) ?
3069 "enabled" : "disabled"); 3069 "enabled" : "disabled");
3070 len += sprintf(p + len, "commands:\tenable, disable\n"); 3070 len += sprintf(p + len, "commands:\tenable, disable\n");
3071 } 3071 }
3072 3072
3073 return len; 3073 return len;
3074 } 3074 }
3075 3075
3076 static int wan_write(char *buf) 3076 static int wan_write(char *buf)
3077 { 3077 {
3078 char *cmd; 3078 char *cmd;
3079 3079
3080 if (!tp_features.wan) 3080 if (!tp_features.wan)
3081 return -ENODEV; 3081 return -ENODEV;
3082 3082
3083 while ((cmd = next_cmd(&buf))) { 3083 while ((cmd = next_cmd(&buf))) {
3084 if (strlencmp(cmd, "enable") == 0) { 3084 if (strlencmp(cmd, "enable") == 0) {
3085 wan_set_radiosw(1, 1); 3085 wan_set_radiosw(1, 1);
3086 } else if (strlencmp(cmd, "disable") == 0) { 3086 } else if (strlencmp(cmd, "disable") == 0) {
3087 wan_set_radiosw(0, 1); 3087 wan_set_radiosw(0, 1);
3088 } else 3088 } else
3089 return -EINVAL; 3089 return -EINVAL;
3090 } 3090 }
3091 3091
3092 return 0; 3092 return 0;
3093 } 3093 }
3094 3094
3095 static struct ibm_struct wan_driver_data = { 3095 static struct ibm_struct wan_driver_data = {
3096 .name = "wan", 3096 .name = "wan",
3097 .read = wan_read, 3097 .read = wan_read,
3098 .write = wan_write, 3098 .write = wan_write,
3099 .exit = wan_exit, 3099 .exit = wan_exit,
3100 }; 3100 };
3101 3101
3102 /************************************************************************* 3102 /*************************************************************************
3103 * Video subdriver 3103 * Video subdriver
3104 */ 3104 */
3105 3105
3106 #ifdef CONFIG_THINKPAD_ACPI_VIDEO 3106 #ifdef CONFIG_THINKPAD_ACPI_VIDEO
3107 3107
3108 enum video_access_mode { 3108 enum video_access_mode {
3109 TPACPI_VIDEO_NONE = 0, 3109 TPACPI_VIDEO_NONE = 0,
3110 TPACPI_VIDEO_570, /* 570 */ 3110 TPACPI_VIDEO_570, /* 570 */
3111 TPACPI_VIDEO_770, /* 600e/x, 770e, 770x */ 3111 TPACPI_VIDEO_770, /* 600e/x, 770e, 770x */
3112 TPACPI_VIDEO_NEW, /* all others */ 3112 TPACPI_VIDEO_NEW, /* all others */
3113 }; 3113 };
3114 3114
3115 enum { /* video status flags, based on VIDEO_570 */ 3115 enum { /* video status flags, based on VIDEO_570 */
3116 TP_ACPI_VIDEO_S_LCD = 0x01, /* LCD output enabled */ 3116 TP_ACPI_VIDEO_S_LCD = 0x01, /* LCD output enabled */
3117 TP_ACPI_VIDEO_S_CRT = 0x02, /* CRT output enabled */ 3117 TP_ACPI_VIDEO_S_CRT = 0x02, /* CRT output enabled */
3118 TP_ACPI_VIDEO_S_DVI = 0x08, /* DVI output enabled */ 3118 TP_ACPI_VIDEO_S_DVI = 0x08, /* DVI output enabled */
3119 }; 3119 };
3120 3120
3121 enum { /* TPACPI_VIDEO_570 constants */ 3121 enum { /* TPACPI_VIDEO_570 constants */
3122 TP_ACPI_VIDEO_570_PHSCMD = 0x87, /* unknown magic constant :( */ 3122 TP_ACPI_VIDEO_570_PHSCMD = 0x87, /* unknown magic constant :( */
3123 TP_ACPI_VIDEO_570_PHSMASK = 0x03, /* PHS bits that map to 3123 TP_ACPI_VIDEO_570_PHSMASK = 0x03, /* PHS bits that map to
3124 * video_status_flags */ 3124 * video_status_flags */
3125 TP_ACPI_VIDEO_570_PHS2CMD = 0x8b, /* unknown magic constant :( */ 3125 TP_ACPI_VIDEO_570_PHS2CMD = 0x8b, /* unknown magic constant :( */
3126 TP_ACPI_VIDEO_570_PHS2SET = 0x80, /* unknown magic constant :( */ 3126 TP_ACPI_VIDEO_570_PHS2SET = 0x80, /* unknown magic constant :( */
3127 }; 3127 };
3128 3128
3129 static enum video_access_mode video_supported; 3129 static enum video_access_mode video_supported;
3130 static int video_orig_autosw; 3130 static int video_orig_autosw;
3131 3131
3132 static int video_autosw_get(void); 3132 static int video_autosw_get(void);
3133 static int video_autosw_set(int enable); 3133 static int video_autosw_set(int enable);
3134 3134
3135 TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */ 3135 TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */
3136 3136
3137 static int __init video_init(struct ibm_init_struct *iibm) 3137 static int __init video_init(struct ibm_init_struct *iibm)
3138 { 3138 {
3139 int ivga; 3139 int ivga;
3140 3140
3141 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n"); 3141 vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n");
3142 3142
3143 TPACPI_ACPIHANDLE_INIT(vid); 3143 TPACPI_ACPIHANDLE_INIT(vid);
3144 TPACPI_ACPIHANDLE_INIT(vid2); 3144 TPACPI_ACPIHANDLE_INIT(vid2);
3145 3145
3146 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga) 3146 if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga)
3147 /* G41, assume IVGA doesn't change */ 3147 /* G41, assume IVGA doesn't change */
3148 vid_handle = vid2_handle; 3148 vid_handle = vid2_handle;
3149 3149
3150 if (!vid_handle) 3150 if (!vid_handle)
3151 /* video switching not supported on R30, R31 */ 3151 /* video switching not supported on R30, R31 */
3152 video_supported = TPACPI_VIDEO_NONE; 3152 video_supported = TPACPI_VIDEO_NONE;
3153 else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) 3153 else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
3154 /* 570 */ 3154 /* 570 */
3155 video_supported = TPACPI_VIDEO_570; 3155 video_supported = TPACPI_VIDEO_570;
3156 else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) 3156 else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
3157 /* 600e/x, 770e, 770x */ 3157 /* 600e/x, 770e, 770x */
3158 video_supported = TPACPI_VIDEO_770; 3158 video_supported = TPACPI_VIDEO_770;
3159 else 3159 else
3160 /* all others */ 3160 /* all others */
3161 video_supported = TPACPI_VIDEO_NEW; 3161 video_supported = TPACPI_VIDEO_NEW;
3162 3162
3163 vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n", 3163 vdbg_printk(TPACPI_DBG_INIT, "video is %s, mode %d\n",
3164 str_supported(video_supported != TPACPI_VIDEO_NONE), 3164 str_supported(video_supported != TPACPI_VIDEO_NONE),
3165 video_supported); 3165 video_supported);
3166 3166
3167 return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1; 3167 return (video_supported != TPACPI_VIDEO_NONE)? 0 : 1;
3168 } 3168 }
3169 3169
3170 static void video_exit(void) 3170 static void video_exit(void)
3171 { 3171 {
3172 dbg_printk(TPACPI_DBG_EXIT, 3172 dbg_printk(TPACPI_DBG_EXIT,
3173 "restoring original video autoswitch mode\n"); 3173 "restoring original video autoswitch mode\n");
3174 if (video_autosw_set(video_orig_autosw)) 3174 if (video_autosw_set(video_orig_autosw))
3175 printk(TPACPI_ERR "error while trying to restore original " 3175 printk(TPACPI_ERR "error while trying to restore original "
3176 "video autoswitch mode\n"); 3176 "video autoswitch mode\n");
3177 } 3177 }
3178 3178
3179 static int video_outputsw_get(void) 3179 static int video_outputsw_get(void)
3180 { 3180 {
3181 int status = 0; 3181 int status = 0;
3182 int i; 3182 int i;
3183 3183
3184 switch (video_supported) { 3184 switch (video_supported) {
3185 case TPACPI_VIDEO_570: 3185 case TPACPI_VIDEO_570:
3186 if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 3186 if (!acpi_evalf(NULL, &i, "\\_SB.PHS", "dd",
3187 TP_ACPI_VIDEO_570_PHSCMD)) 3187 TP_ACPI_VIDEO_570_PHSCMD))
3188 return -EIO; 3188 return -EIO;
3189 status = i & TP_ACPI_VIDEO_570_PHSMASK; 3189 status = i & TP_ACPI_VIDEO_570_PHSMASK;
3190 break; 3190 break;
3191 case TPACPI_VIDEO_770: 3191 case TPACPI_VIDEO_770:
3192 if (!acpi_evalf(NULL, &i, "\\VCDL", "d")) 3192 if (!acpi_evalf(NULL, &i, "\\VCDL", "d"))
3193 return -EIO; 3193 return -EIO;
3194 if (i) 3194 if (i)
3195 status |= TP_ACPI_VIDEO_S_LCD; 3195 status |= TP_ACPI_VIDEO_S_LCD;
3196 if (!acpi_evalf(NULL, &i, "\\VCDC", "d")) 3196 if (!acpi_evalf(NULL, &i, "\\VCDC", "d"))
3197 return -EIO; 3197 return -EIO;
3198 if (i) 3198 if (i)
3199 status |= TP_ACPI_VIDEO_S_CRT; 3199 status |= TP_ACPI_VIDEO_S_CRT;
3200 break; 3200 break;
3201 case TPACPI_VIDEO_NEW: 3201 case TPACPI_VIDEO_NEW:
3202 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) || 3202 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1) ||
3203 !acpi_evalf(NULL, &i, "\\VCDC", "d")) 3203 !acpi_evalf(NULL, &i, "\\VCDC", "d"))
3204 return -EIO; 3204 return -EIO;
3205 if (i) 3205 if (i)
3206 status |= TP_ACPI_VIDEO_S_CRT; 3206 status |= TP_ACPI_VIDEO_S_CRT;
3207 3207
3208 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) || 3208 if (!acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0) ||
3209 !acpi_evalf(NULL, &i, "\\VCDL", "d")) 3209 !acpi_evalf(NULL, &i, "\\VCDL", "d"))
3210 return -EIO; 3210 return -EIO;
3211 if (i) 3211 if (i)
3212 status |= TP_ACPI_VIDEO_S_LCD; 3212 status |= TP_ACPI_VIDEO_S_LCD;
3213 if (!acpi_evalf(NULL, &i, "\\VCDD", "d")) 3213 if (!acpi_evalf(NULL, &i, "\\VCDD", "d"))
3214 return -EIO; 3214 return -EIO;
3215 if (i) 3215 if (i)
3216 status |= TP_ACPI_VIDEO_S_DVI; 3216 status |= TP_ACPI_VIDEO_S_DVI;
3217 break; 3217 break;
3218 default: 3218 default:
3219 return -ENOSYS; 3219 return -ENOSYS;
3220 } 3220 }
3221 3221
3222 return status; 3222 return status;
3223 } 3223 }
3224 3224
3225 static int video_outputsw_set(int status) 3225 static int video_outputsw_set(int status)
3226 { 3226 {
3227 int autosw; 3227 int autosw;
3228 int res = 0; 3228 int res = 0;
3229 3229
3230 switch (video_supported) { 3230 switch (video_supported) {
3231 case TPACPI_VIDEO_570: 3231 case TPACPI_VIDEO_570:
3232 res = acpi_evalf(NULL, NULL, 3232 res = acpi_evalf(NULL, NULL,
3233 "\\_SB.PHS2", "vdd", 3233 "\\_SB.PHS2", "vdd",
3234 TP_ACPI_VIDEO_570_PHS2CMD, 3234 TP_ACPI_VIDEO_570_PHS2CMD,
3235 status | TP_ACPI_VIDEO_570_PHS2SET); 3235 status | TP_ACPI_VIDEO_570_PHS2SET);
3236 break; 3236 break;
3237 case TPACPI_VIDEO_770: 3237 case TPACPI_VIDEO_770:
3238 autosw = video_autosw_get(); 3238 autosw = video_autosw_get();
3239 if (autosw < 0) 3239 if (autosw < 0)
3240 return autosw; 3240 return autosw;
3241 3241
3242 res = video_autosw_set(1); 3242 res = video_autosw_set(1);
3243 if (res) 3243 if (res)
3244 return res; 3244 return res;
3245 res = acpi_evalf(vid_handle, NULL, 3245 res = acpi_evalf(vid_handle, NULL,
3246 "ASWT", "vdd", status * 0x100, 0); 3246 "ASWT", "vdd", status * 0x100, 0);
3247 if (!autosw && video_autosw_set(autosw)) { 3247 if (!autosw && video_autosw_set(autosw)) {
3248 printk(TPACPI_ERR 3248 printk(TPACPI_ERR
3249 "video auto-switch left enabled due to error\n"); 3249 "video auto-switch left enabled due to error\n");
3250 return -EIO; 3250 return -EIO;
3251 } 3251 }
3252 break; 3252 break;
3253 case TPACPI_VIDEO_NEW: 3253 case TPACPI_VIDEO_NEW:
3254 res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) && 3254 res = acpi_evalf(NULL, NULL, "\\VUPS", "vd", 0x80) &&
3255 acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1); 3255 acpi_evalf(NULL, NULL, "\\VSDS", "vdd", status, 1);
3256 break; 3256 break;
3257 default: 3257 default:
3258 return -ENOSYS; 3258 return -ENOSYS;
3259 } 3259 }
3260 3260
3261 return (res)? 0 : -EIO; 3261 return (res)? 0 : -EIO;
3262 } 3262 }
3263 3263
3264 static int video_autosw_get(void) 3264 static int video_autosw_get(void)
3265 { 3265 {
3266 int autosw = 0; 3266 int autosw = 0;
3267 3267
3268 switch (video_supported) { 3268 switch (video_supported) {
3269 case TPACPI_VIDEO_570: 3269 case TPACPI_VIDEO_570:
3270 if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d")) 3270 if (!acpi_evalf(vid_handle, &autosw, "SWIT", "d"))
3271 return -EIO; 3271 return -EIO;
3272 break; 3272 break;
3273 case TPACPI_VIDEO_770: 3273 case TPACPI_VIDEO_770:
3274 case TPACPI_VIDEO_NEW: 3274 case TPACPI_VIDEO_NEW:
3275 if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d")) 3275 if (!acpi_evalf(vid_handle, &autosw, "^VDEE", "d"))
3276 return -EIO; 3276 return -EIO;
3277 break; 3277 break;
3278 default: 3278 default:
3279 return -ENOSYS; 3279 return -ENOSYS;
3280 } 3280 }
3281 3281
3282 return autosw & 1; 3282 return autosw & 1;
3283 } 3283 }
3284 3284
3285 static int video_autosw_set(int enable) 3285 static int video_autosw_set(int enable)
3286 { 3286 {
3287 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0)) 3287 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", (enable)? 1 : 0))
3288 return -EIO; 3288 return -EIO;
3289 return 0; 3289 return 0;
3290 } 3290 }
3291 3291
3292 static int video_outputsw_cycle(void) 3292 static int video_outputsw_cycle(void)
3293 { 3293 {
3294 int autosw = video_autosw_get(); 3294 int autosw = video_autosw_get();
3295 int res; 3295 int res;
3296 3296
3297 if (autosw < 0) 3297 if (autosw < 0)
3298 return autosw; 3298 return autosw;
3299 3299
3300 switch (video_supported) { 3300 switch (video_supported) {
3301 case TPACPI_VIDEO_570: 3301 case TPACPI_VIDEO_570:
3302 res = video_autosw_set(1); 3302 res = video_autosw_set(1);
3303 if (res) 3303 if (res)
3304 return res; 3304 return res;
3305 res = acpi_evalf(ec_handle, NULL, "_Q16", "v"); 3305 res = acpi_evalf(ec_handle, NULL, "_Q16", "v");
3306 break; 3306 break;
3307 case TPACPI_VIDEO_770: 3307 case TPACPI_VIDEO_770:
3308 case TPACPI_VIDEO_NEW: 3308 case TPACPI_VIDEO_NEW:
3309 res = video_autosw_set(1); 3309 res = video_autosw_set(1);
3310 if (res) 3310 if (res)
3311 return res; 3311 return res;
3312 res = acpi_evalf(vid_handle, NULL, "VSWT", "v"); 3312 res = acpi_evalf(vid_handle, NULL, "VSWT", "v");
3313 break; 3313 break;
3314 default: 3314 default:
3315 return -ENOSYS; 3315 return -ENOSYS;
3316 } 3316 }
3317 if (!autosw && video_autosw_set(autosw)) { 3317 if (!autosw && video_autosw_set(autosw)) {
3318 printk(TPACPI_ERR 3318 printk(TPACPI_ERR
3319 "video auto-switch left enabled due to error\n"); 3319 "video auto-switch left enabled due to error\n");
3320 return -EIO; 3320 return -EIO;
3321 } 3321 }
3322 3322
3323 return (res)? 0 : -EIO; 3323 return (res)? 0 : -EIO;
3324 } 3324 }
3325 3325
3326 static int video_expand_toggle(void) 3326 static int video_expand_toggle(void)
3327 { 3327 {
3328 switch (video_supported) { 3328 switch (video_supported) {
3329 case TPACPI_VIDEO_570: 3329 case TPACPI_VIDEO_570:
3330 return acpi_evalf(ec_handle, NULL, "_Q17", "v")? 3330 return acpi_evalf(ec_handle, NULL, "_Q17", "v")?
3331 0 : -EIO; 3331 0 : -EIO;
3332 case TPACPI_VIDEO_770: 3332 case TPACPI_VIDEO_770:
3333 return acpi_evalf(vid_handle, NULL, "VEXP", "v")? 3333 return acpi_evalf(vid_handle, NULL, "VEXP", "v")?
3334 0 : -EIO; 3334 0 : -EIO;
3335 case TPACPI_VIDEO_NEW: 3335 case TPACPI_VIDEO_NEW:
3336 return acpi_evalf(NULL, NULL, "\\VEXP", "v")? 3336 return acpi_evalf(NULL, NULL, "\\VEXP", "v")?
3337 0 : -EIO; 3337 0 : -EIO;
3338 default: 3338 default:
3339 return -ENOSYS; 3339 return -ENOSYS;
3340 } 3340 }
3341 /* not reached */ 3341 /* not reached */
3342 } 3342 }
3343 3343
3344 static int video_read(char *p) 3344 static int video_read(char *p)
3345 { 3345 {
3346 int status, autosw; 3346 int status, autosw;
3347 int len = 0; 3347 int len = 0;
3348 3348
3349 if (video_supported == TPACPI_VIDEO_NONE) { 3349 if (video_supported == TPACPI_VIDEO_NONE) {
3350 len += sprintf(p + len, "status:\t\tnot supported\n"); 3350 len += sprintf(p + len, "status:\t\tnot supported\n");
3351 return len; 3351 return len;
3352 } 3352 }
3353 3353
3354 status = video_outputsw_get(); 3354 status = video_outputsw_get();
3355 if (status < 0) 3355 if (status < 0)
3356 return status; 3356 return status;
3357 3357
3358 autosw = video_autosw_get(); 3358 autosw = video_autosw_get();
3359 if (autosw < 0) 3359 if (autosw < 0)
3360 return autosw; 3360 return autosw;
3361 3361
3362 len += sprintf(p + len, "status:\t\tsupported\n"); 3362 len += sprintf(p + len, "status:\t\tsupported\n");
3363 len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); 3363 len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
3364 len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); 3364 len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
3365 if (video_supported == TPACPI_VIDEO_NEW) 3365 if (video_supported == TPACPI_VIDEO_NEW)
3366 len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); 3366 len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
3367 len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); 3367 len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
3368 len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); 3368 len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
3369 len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); 3369 len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
3370 if (video_supported == TPACPI_VIDEO_NEW) 3370 if (video_supported == TPACPI_VIDEO_NEW)
3371 len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); 3371 len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
3372 len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); 3372 len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
3373 len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); 3373 len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
3374 3374
3375 return len; 3375 return len;
3376 } 3376 }
3377 3377
3378 static int video_write(char *buf) 3378 static int video_write(char *buf)
3379 { 3379 {
3380 char *cmd; 3380 char *cmd;
3381 int enable, disable, status; 3381 int enable, disable, status;
3382 int res; 3382 int res;
3383 3383
3384 if (video_supported == TPACPI_VIDEO_NONE) 3384 if (video_supported == TPACPI_VIDEO_NONE)
3385 return -ENODEV; 3385 return -ENODEV;
3386 3386
3387 enable = 0; 3387 enable = 0;
3388 disable = 0; 3388 disable = 0;
3389 3389
3390 while ((cmd = next_cmd(&buf))) { 3390 while ((cmd = next_cmd(&buf))) {
3391 if (strlencmp(cmd, "lcd_enable") == 0) { 3391 if (strlencmp(cmd, "lcd_enable") == 0) {
3392 enable |= TP_ACPI_VIDEO_S_LCD; 3392 enable |= TP_ACPI_VIDEO_S_LCD;
3393 } else if (strlencmp(cmd, "lcd_disable") == 0) { 3393 } else if (strlencmp(cmd, "lcd_disable") == 0) {
3394 disable |= TP_ACPI_VIDEO_S_LCD; 3394 disable |= TP_ACPI_VIDEO_S_LCD;
3395 } else if (strlencmp(cmd, "crt_enable") == 0) { 3395 } else if (strlencmp(cmd, "crt_enable") == 0) {
3396 enable |= TP_ACPI_VIDEO_S_CRT; 3396 enable |= TP_ACPI_VIDEO_S_CRT;
3397 } else if (strlencmp(cmd, "crt_disable") == 0) { 3397 } else if (strlencmp(cmd, "crt_disable") == 0) {
3398 disable |= TP_ACPI_VIDEO_S_CRT; 3398 disable |= TP_ACPI_VIDEO_S_CRT;
3399 } else if (video_supported == TPACPI_VIDEO_NEW && 3399 } else if (video_supported == TPACPI_VIDEO_NEW &&
3400 strlencmp(cmd, "dvi_enable") == 0) { 3400 strlencmp(cmd, "dvi_enable") == 0) {
3401 enable |= TP_ACPI_VIDEO_S_DVI; 3401 enable |= TP_ACPI_VIDEO_S_DVI;
3402 } else if (video_supported == TPACPI_VIDEO_NEW && 3402 } else if (video_supported == TPACPI_VIDEO_NEW &&
3403 strlencmp(cmd, "dvi_disable") == 0) { 3403 strlencmp(cmd, "dvi_disable") == 0) {
3404 disable |= TP_ACPI_VIDEO_S_DVI; 3404 disable |= TP_ACPI_VIDEO_S_DVI;
3405 } else if (strlencmp(cmd, "auto_enable") == 0) { 3405 } else if (strlencmp(cmd, "auto_enable") == 0) {
3406 res = video_autosw_set(1); 3406 res = video_autosw_set(1);
3407 if (res) 3407 if (res)
3408 return res; 3408 return res;
3409 } else if (strlencmp(cmd, "auto_disable") == 0) { 3409 } else if (strlencmp(cmd, "auto_disable") == 0) {
3410 res = video_autosw_set(0); 3410 res = video_autosw_set(0);
3411 if (res) 3411 if (res)
3412 return res; 3412 return res;
3413 } else if (strlencmp(cmd, "video_switch") == 0) { 3413 } else if (strlencmp(cmd, "video_switch") == 0) {
3414 res = video_outputsw_cycle(); 3414 res = video_outputsw_cycle();
3415 if (res) 3415 if (res)
3416 return res; 3416 return res;
3417 } else if (strlencmp(cmd, "expand_toggle") == 0) { 3417 } else if (strlencmp(cmd, "expand_toggle") == 0) {
3418 res = video_expand_toggle(); 3418 res = video_expand_toggle();
3419 if (res) 3419 if (res)
3420 return res; 3420 return res;
3421 } else 3421 } else
3422 return -EINVAL; 3422 return -EINVAL;
3423 } 3423 }
3424 3424
3425 if (enable || disable) { 3425 if (enable || disable) {
3426 status = video_outputsw_get(); 3426 status = video_outputsw_get();
3427 if (status < 0) 3427 if (status < 0)
3428 return status; 3428 return status;
3429 res = video_outputsw_set((status & ~disable) | enable); 3429 res = video_outputsw_set((status & ~disable) | enable);
3430 if (res) 3430 if (res)
3431 return res; 3431 return res;
3432 } 3432 }
3433 3433
3434 return 0; 3434 return 0;
3435 } 3435 }
3436 3436
3437 static struct ibm_struct video_driver_data = { 3437 static struct ibm_struct video_driver_data = {
3438 .name = "video", 3438 .name = "video",
3439 .read = video_read, 3439 .read = video_read,
3440 .write = video_write, 3440 .write = video_write,
3441 .exit = video_exit, 3441 .exit = video_exit,
3442 }; 3442 };
3443 3443
3444 #endif /* CONFIG_THINKPAD_ACPI_VIDEO */ 3444 #endif /* CONFIG_THINKPAD_ACPI_VIDEO */
3445 3445
3446 /************************************************************************* 3446 /*************************************************************************
3447 * Light (thinklight) subdriver 3447 * Light (thinklight) subdriver
3448 */ 3448 */
3449 3449
3450 TPACPI_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */ 3450 TPACPI_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */
3451 TPACPI_HANDLE(ledb, ec, "LEDB"); /* G4x */ 3451 TPACPI_HANDLE(ledb, ec, "LEDB"); /* G4x */
3452 3452
3453 static int light_get_status(void) 3453 static int light_get_status(void)
3454 { 3454 {
3455 int status = 0; 3455 int status = 0;
3456 3456
3457 if (tp_features.light_status) { 3457 if (tp_features.light_status) {
3458 if (!acpi_evalf(ec_handle, &status, "KBLT", "d")) 3458 if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
3459 return -EIO; 3459 return -EIO;
3460 return (!!status); 3460 return (!!status);
3461 } 3461 }
3462 3462
3463 return -ENXIO; 3463 return -ENXIO;
3464 } 3464 }
3465 3465
3466 static int light_set_status(int status) 3466 static int light_set_status(int status)
3467 { 3467 {
3468 int rc; 3468 int rc;
3469 3469
3470 if (tp_features.light) { 3470 if (tp_features.light) {
3471 if (cmos_handle) { 3471 if (cmos_handle) {
3472 rc = acpi_evalf(cmos_handle, NULL, NULL, "vd", 3472 rc = acpi_evalf(cmos_handle, NULL, NULL, "vd",
3473 (status)? 3473 (status)?
3474 TP_CMOS_THINKLIGHT_ON : 3474 TP_CMOS_THINKLIGHT_ON :
3475 TP_CMOS_THINKLIGHT_OFF); 3475 TP_CMOS_THINKLIGHT_OFF);
3476 } else { 3476 } else {
3477 rc = acpi_evalf(lght_handle, NULL, NULL, "vd", 3477 rc = acpi_evalf(lght_handle, NULL, NULL, "vd",
3478 (status)? 1 : 0); 3478 (status)? 1 : 0);
3479 } 3479 }
3480 return (rc)? 0 : -EIO; 3480 return (rc)? 0 : -EIO;
3481 } 3481 }
3482 3482
3483 return -ENXIO; 3483 return -ENXIO;
3484 } 3484 }
3485 3485
3486 static void light_set_status_worker(struct work_struct *work) 3486 static void light_set_status_worker(struct work_struct *work)
3487 { 3487 {
3488 struct tpacpi_led_classdev *data = 3488 struct tpacpi_led_classdev *data =
3489 container_of(work, struct tpacpi_led_classdev, work); 3489 container_of(work, struct tpacpi_led_classdev, work);
3490 3490
3491 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) 3491 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
3492 light_set_status((data->new_brightness != LED_OFF)); 3492 light_set_status((data->new_brightness != LED_OFF));
3493 } 3493 }
3494 3494
3495 static void light_sysfs_set(struct led_classdev *led_cdev, 3495 static void light_sysfs_set(struct led_classdev *led_cdev,
3496 enum led_brightness brightness) 3496 enum led_brightness brightness)
3497 { 3497 {
3498 struct tpacpi_led_classdev *data = 3498 struct tpacpi_led_classdev *data =
3499 container_of(led_cdev, 3499 container_of(led_cdev,
3500 struct tpacpi_led_classdev, 3500 struct tpacpi_led_classdev,
3501 led_classdev); 3501 led_classdev);
3502 data->new_brightness = brightness; 3502 data->new_brightness = brightness;
3503 queue_work(tpacpi_wq, &data->work); 3503 queue_work(tpacpi_wq, &data->work);
3504 } 3504 }
3505 3505
3506 static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev) 3506 static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
3507 { 3507 {
3508 return (light_get_status() == 1)? LED_FULL : LED_OFF; 3508 return (light_get_status() == 1)? LED_FULL : LED_OFF;
3509 } 3509 }
3510 3510
3511 static struct tpacpi_led_classdev tpacpi_led_thinklight = { 3511 static struct tpacpi_led_classdev tpacpi_led_thinklight = {
3512 .led_classdev = { 3512 .led_classdev = {
3513 .name = "tpacpi::thinklight", 3513 .name = "tpacpi::thinklight",
3514 .brightness_set = &light_sysfs_set, 3514 .brightness_set = &light_sysfs_set,
3515 .brightness_get = &light_sysfs_get, 3515 .brightness_get = &light_sysfs_get,
3516 } 3516 }
3517 }; 3517 };
3518 3518
3519 static int __init light_init(struct ibm_init_struct *iibm) 3519 static int __init light_init(struct ibm_init_struct *iibm)
3520 { 3520 {
3521 int rc; 3521 int rc;
3522 3522
3523 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); 3523 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
3524 3524
3525 TPACPI_ACPIHANDLE_INIT(ledb); 3525 TPACPI_ACPIHANDLE_INIT(ledb);
3526 TPACPI_ACPIHANDLE_INIT(lght); 3526 TPACPI_ACPIHANDLE_INIT(lght);
3527 TPACPI_ACPIHANDLE_INIT(cmos); 3527 TPACPI_ACPIHANDLE_INIT(cmos);
3528 INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker); 3528 INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker);
3529 3529
3530 /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */ 3530 /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
3531 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle; 3531 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
3532 3532
3533 if (tp_features.light) 3533 if (tp_features.light)
3534 /* light status not supported on 3534 /* light status not supported on
3535 570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */ 3535 570, 600e/x, 770e, 770x, G4x, R30, R31, R32, X20 */
3536 tp_features.light_status = 3536 tp_features.light_status =
3537 acpi_evalf(ec_handle, NULL, "KBLT", "qv"); 3537 acpi_evalf(ec_handle, NULL, "KBLT", "qv");
3538 3538
3539 vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n", 3539 vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n",
3540 str_supported(tp_features.light), 3540 str_supported(tp_features.light),
3541 str_supported(tp_features.light_status)); 3541 str_supported(tp_features.light_status));
3542 3542
3543 if (!tp_features.light) 3543 if (!tp_features.light)
3544 return 1; 3544 return 1;
3545 3545
3546 rc = led_classdev_register(&tpacpi_pdev->dev, 3546 rc = led_classdev_register(&tpacpi_pdev->dev,
3547 &tpacpi_led_thinklight.led_classdev); 3547 &tpacpi_led_thinklight.led_classdev);
3548 3548
3549 if (rc < 0) { 3549 if (rc < 0) {
3550 tp_features.light = 0; 3550 tp_features.light = 0;
3551 tp_features.light_status = 0; 3551 tp_features.light_status = 0;
3552 } else { 3552 } else {
3553 rc = 0; 3553 rc = 0;
3554 } 3554 }
3555 3555
3556 return rc; 3556 return rc;
3557 } 3557 }
3558 3558
3559 static void light_exit(void) 3559 static void light_exit(void)
3560 { 3560 {
3561 led_classdev_unregister(&tpacpi_led_thinklight.led_classdev); 3561 led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);
3562 if (work_pending(&tpacpi_led_thinklight.work)) 3562 if (work_pending(&tpacpi_led_thinklight.work))
3563 flush_workqueue(tpacpi_wq); 3563 flush_workqueue(tpacpi_wq);
3564 } 3564 }
3565 3565
3566 static int light_read(char *p) 3566 static int light_read(char *p)
3567 { 3567 {
3568 int len = 0; 3568 int len = 0;
3569 int status; 3569 int status;
3570 3570
3571 if (!tp_features.light) { 3571 if (!tp_features.light) {
3572 len += sprintf(p + len, "status:\t\tnot supported\n"); 3572 len += sprintf(p + len, "status:\t\tnot supported\n");
3573 } else if (!tp_features.light_status) { 3573 } else if (!tp_features.light_status) {
3574 len += sprintf(p + len, "status:\t\tunknown\n"); 3574 len += sprintf(p + len, "status:\t\tunknown\n");
3575 len += sprintf(p + len, "commands:\ton, off\n"); 3575 len += sprintf(p + len, "commands:\ton, off\n");
3576 } else { 3576 } else {
3577 status = light_get_status(); 3577 status = light_get_status();
3578 if (status < 0) 3578 if (status < 0)
3579 return status; 3579 return status;
3580 len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); 3580 len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
3581 len += sprintf(p + len, "commands:\ton, off\n"); 3581 len += sprintf(p + len, "commands:\ton, off\n");
3582 } 3582 }
3583 3583
3584 return len; 3584 return len;
3585 } 3585 }
3586 3586
3587 static int light_write(char *buf) 3587 static int light_write(char *buf)
3588 { 3588 {
3589 char *cmd; 3589 char *cmd;
3590 int newstatus = 0; 3590 int newstatus = 0;
3591 3591
3592 if (!tp_features.light) 3592 if (!tp_features.light)
3593 return -ENODEV; 3593 return -ENODEV;
3594 3594
3595 while ((cmd = next_cmd(&buf))) { 3595 while ((cmd = next_cmd(&buf))) {
3596 if (strlencmp(cmd, "on") == 0) { 3596 if (strlencmp(cmd, "on") == 0) {
3597 newstatus = 1; 3597 newstatus = 1;
3598 } else if (strlencmp(cmd, "off") == 0) { 3598 } else if (strlencmp(cmd, "off") == 0) {
3599 newstatus = 0; 3599 newstatus = 0;
3600 } else 3600 } else
3601 return -EINVAL; 3601 return -EINVAL;
3602 } 3602 }
3603 3603
3604 return light_set_status(newstatus); 3604 return light_set_status(newstatus);
3605 } 3605 }
3606 3606
3607 static struct ibm_struct light_driver_data = { 3607 static struct ibm_struct light_driver_data = {
3608 .name = "light", 3608 .name = "light",
3609 .read = light_read, 3609 .read = light_read,
3610 .write = light_write, 3610 .write = light_write,
3611 .exit = light_exit, 3611 .exit = light_exit,
3612 }; 3612 };
3613 3613
3614 /************************************************************************* 3614 /*************************************************************************
3615 * Dock subdriver 3615 * Dock subdriver
3616 */ 3616 */
3617 3617
3618 #ifdef CONFIG_THINKPAD_ACPI_DOCK 3618 #ifdef CONFIG_THINKPAD_ACPI_DOCK
3619 3619
3620 static void dock_notify(struct ibm_struct *ibm, u32 event); 3620 static void dock_notify(struct ibm_struct *ibm, u32 event);
3621 static int dock_read(char *p); 3621 static int dock_read(char *p);
3622 static int dock_write(char *buf); 3622 static int dock_write(char *buf);
3623 3623
3624 TPACPI_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */ 3624 TPACPI_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */
3625 "\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */ 3625 "\\_SB.PCI0.DOCK", /* 600e/x,770e,770x,A2xm/p,T20-22,X20-21 */
3626 "\\_SB.PCI0.PCI1.DOCK", /* all others */ 3626 "\\_SB.PCI0.PCI1.DOCK", /* all others */
3627 "\\_SB.PCI.ISA.SLCE", /* 570 */ 3627 "\\_SB.PCI.ISA.SLCE", /* 570 */
3628 ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */ 3628 ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
3629 3629
3630 /* don't list other alternatives as we install a notify handler on the 570 */ 3630 /* don't list other alternatives as we install a notify handler on the 570 */
3631 TPACPI_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */ 3631 TPACPI_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */
3632 3632
3633 static const struct acpi_device_id ibm_pci_device_ids[] = { 3633 static const struct acpi_device_id ibm_pci_device_ids[] = {
3634 {PCI_ROOT_HID_STRING, 0}, 3634 {PCI_ROOT_HID_STRING, 0},
3635 {"", 0}, 3635 {"", 0},
3636 }; 3636 };
3637 3637
3638 static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = { 3638 static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
3639 { 3639 {
3640 .notify = dock_notify, 3640 .notify = dock_notify,
3641 .handle = &dock_handle, 3641 .handle = &dock_handle,
3642 .type = ACPI_SYSTEM_NOTIFY, 3642 .type = ACPI_SYSTEM_NOTIFY,
3643 }, 3643 },
3644 { 3644 {
3645 /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING. 3645 /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING.
3646 * We just use it to get notifications of dock hotplug 3646 * We just use it to get notifications of dock hotplug
3647 * in very old thinkpads */ 3647 * in very old thinkpads */
3648 .hid = ibm_pci_device_ids, 3648 .hid = ibm_pci_device_ids,
3649 .notify = dock_notify, 3649 .notify = dock_notify,
3650 .handle = &pci_handle, 3650 .handle = &pci_handle,
3651 .type = ACPI_SYSTEM_NOTIFY, 3651 .type = ACPI_SYSTEM_NOTIFY,
3652 }, 3652 },
3653 }; 3653 };
3654 3654
3655 static struct ibm_struct dock_driver_data[2] = { 3655 static struct ibm_struct dock_driver_data[2] = {
3656 { 3656 {
3657 .name = "dock", 3657 .name = "dock",
3658 .read = dock_read, 3658 .read = dock_read,
3659 .write = dock_write, 3659 .write = dock_write,
3660 .acpi = &ibm_dock_acpidriver[0], 3660 .acpi = &ibm_dock_acpidriver[0],
3661 }, 3661 },
3662 { 3662 {
3663 .name = "dock", 3663 .name = "dock",
3664 .acpi = &ibm_dock_acpidriver[1], 3664 .acpi = &ibm_dock_acpidriver[1],
3665 }, 3665 },
3666 }; 3666 };
3667 3667
3668 #define dock_docked() (_sta(dock_handle) & 1) 3668 #define dock_docked() (_sta(dock_handle) & 1)
3669 3669
3670 static int __init dock_init(struct ibm_init_struct *iibm) 3670 static int __init dock_init(struct ibm_init_struct *iibm)
3671 { 3671 {
3672 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n"); 3672 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver\n");
3673 3673
3674 TPACPI_ACPIHANDLE_INIT(dock); 3674 TPACPI_ACPIHANDLE_INIT(dock);
3675 3675
3676 vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n", 3676 vdbg_printk(TPACPI_DBG_INIT, "dock is %s\n",
3677 str_supported(dock_handle != NULL)); 3677 str_supported(dock_handle != NULL));
3678 3678
3679 return (dock_handle)? 0 : 1; 3679 return (dock_handle)? 0 : 1;
3680 } 3680 }
3681 3681
3682 static int __init dock_init2(struct ibm_init_struct *iibm) 3682 static int __init dock_init2(struct ibm_init_struct *iibm)
3683 { 3683 {
3684 int dock2_needed; 3684 int dock2_needed;
3685 3685
3686 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver part 2\n"); 3686 vdbg_printk(TPACPI_DBG_INIT, "initializing dock subdriver part 2\n");
3687 3687
3688 if (dock_driver_data[0].flags.acpi_driver_registered && 3688 if (dock_driver_data[0].flags.acpi_driver_registered &&
3689 dock_driver_data[0].flags.acpi_notify_installed) { 3689 dock_driver_data[0].flags.acpi_notify_installed) {
3690 TPACPI_ACPIHANDLE_INIT(pci); 3690 TPACPI_ACPIHANDLE_INIT(pci);
3691 dock2_needed = (pci_handle != NULL); 3691 dock2_needed = (pci_handle != NULL);
3692 vdbg_printk(TPACPI_DBG_INIT, 3692 vdbg_printk(TPACPI_DBG_INIT,
3693 "dock PCI handler for the TP 570 is %s\n", 3693 "dock PCI handler for the TP 570 is %s\n",
3694 str_supported(dock2_needed)); 3694 str_supported(dock2_needed));
3695 } else { 3695 } else {
3696 vdbg_printk(TPACPI_DBG_INIT, 3696 vdbg_printk(TPACPI_DBG_INIT,
3697 "dock subdriver part 2 not required\n"); 3697 "dock subdriver part 2 not required\n");
3698 dock2_needed = 0; 3698 dock2_needed = 0;
3699 } 3699 }
3700 3700
3701 return (dock2_needed)? 0 : 1; 3701 return (dock2_needed)? 0 : 1;
3702 } 3702 }
3703 3703
3704 static void dock_notify(struct ibm_struct *ibm, u32 event) 3704 static void dock_notify(struct ibm_struct *ibm, u32 event)
3705 { 3705 {
3706 int docked = dock_docked(); 3706 int docked = dock_docked();
3707 int pci = ibm->acpi->hid && ibm->acpi->device && 3707 int pci = ibm->acpi->hid && ibm->acpi->device &&
3708 acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids); 3708 acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids);
3709 int data; 3709 int data;
3710 3710
3711 if (event == 1 && !pci) /* 570 */ 3711 if (event == 1 && !pci) /* 570 */
3712 data = 1; /* button */ 3712 data = 1; /* button */
3713 else if (event == 1 && pci) /* 570 */ 3713 else if (event == 1 && pci) /* 570 */
3714 data = 3; /* dock */ 3714 data = 3; /* dock */
3715 else if (event == 3 && docked) 3715 else if (event == 3 && docked)
3716 data = 1; /* button */ 3716 data = 1; /* button */
3717 else if (event == 3 && !docked) 3717 else if (event == 3 && !docked)
3718 data = 2; /* undock */ 3718 data = 2; /* undock */
3719 else if (event == 0 && docked) 3719 else if (event == 0 && docked)
3720 data = 3; /* dock */ 3720 data = 3; /* dock */
3721 else { 3721 else {
3722 printk(TPACPI_ERR "unknown dock event %d, status %d\n", 3722 printk(TPACPI_ERR "unknown dock event %d, status %d\n",
3723 event, _sta(dock_handle)); 3723 event, _sta(dock_handle));
3724 data = 0; /* unknown */ 3724 data = 0; /* unknown */
3725 } 3725 }
3726 acpi_bus_generate_proc_event(ibm->acpi->device, event, data); 3726 acpi_bus_generate_proc_event(ibm->acpi->device, event, data);
3727 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 3727 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
3728 ibm->acpi->device->dev.bus_id, 3728 ibm->acpi->device->dev.bus_id,
3729 event, data); 3729 event, data);
3730 } 3730 }
3731 3731
3732 static int dock_read(char *p) 3732 static int dock_read(char *p)
3733 { 3733 {
3734 int len = 0; 3734 int len = 0;
3735 int docked = dock_docked(); 3735 int docked = dock_docked();
3736 3736
3737 if (!dock_handle) 3737 if (!dock_handle)
3738 len += sprintf(p + len, "status:\t\tnot supported\n"); 3738 len += sprintf(p + len, "status:\t\tnot supported\n");
3739 else if (!docked) 3739 else if (!docked)
3740 len += sprintf(p + len, "status:\t\tundocked\n"); 3740 len += sprintf(p + len, "status:\t\tundocked\n");
3741 else { 3741 else {
3742 len += sprintf(p + len, "status:\t\tdocked\n"); 3742 len += sprintf(p + len, "status:\t\tdocked\n");
3743 len += sprintf(p + len, "commands:\tdock, undock\n"); 3743 len += sprintf(p + len, "commands:\tdock, undock\n");
3744 } 3744 }
3745 3745
3746 return len; 3746 return len;
3747 } 3747 }
3748 3748
3749 static int dock_write(char *buf) 3749 static int dock_write(char *buf)
3750 { 3750 {
3751 char *cmd; 3751 char *cmd;
3752 3752
3753 if (!dock_docked()) 3753 if (!dock_docked())
3754 return -ENODEV; 3754 return -ENODEV;
3755 3755
3756 while ((cmd = next_cmd(&buf))) { 3756 while ((cmd = next_cmd(&buf))) {
3757 if (strlencmp(cmd, "undock") == 0) { 3757 if (strlencmp(cmd, "undock") == 0) {
3758 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0) || 3758 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 0) ||
3759 !acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1)) 3759 !acpi_evalf(dock_handle, NULL, "_EJ0", "vd", 1))
3760 return -EIO; 3760 return -EIO;
3761 } else if (strlencmp(cmd, "dock") == 0) { 3761 } else if (strlencmp(cmd, "dock") == 0) {
3762 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1)) 3762 if (!acpi_evalf(dock_handle, NULL, "_DCK", "vd", 1))
3763 return -EIO; 3763 return -EIO;
3764 } else 3764 } else
3765 return -EINVAL; 3765 return -EINVAL;
3766 } 3766 }
3767 3767
3768 return 0; 3768 return 0;
3769 } 3769 }
3770 3770
3771 #endif /* CONFIG_THINKPAD_ACPI_DOCK */ 3771 #endif /* CONFIG_THINKPAD_ACPI_DOCK */
3772 3772
3773 /************************************************************************* 3773 /*************************************************************************
3774 * Bay subdriver 3774 * Bay subdriver
3775 */ 3775 */
3776 3776
3777 #ifdef CONFIG_THINKPAD_ACPI_BAY 3777 #ifdef CONFIG_THINKPAD_ACPI_BAY
3778 3778
3779 TPACPI_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */ 3779 TPACPI_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */
3780 "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */ 3780 "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
3781 "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */ 3781 "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */
3782 "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */ 3782 "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */
3783 ); /* A21e, R30, R31 */ 3783 ); /* A21e, R30, R31 */
3784 TPACPI_HANDLE(bay_ej, bay, "_EJ3", /* 600e/x, A2xm/p, A3x */ 3784 TPACPI_HANDLE(bay_ej, bay, "_EJ3", /* 600e/x, A2xm/p, A3x */
3785 "_EJ0", /* all others */ 3785 "_EJ0", /* all others */
3786 ); /* 570,A21e,G4x,R30,R31,R32,R40e,R50e */ 3786 ); /* 570,A21e,G4x,R30,R31,R32,R40e,R50e */
3787 TPACPI_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */ 3787 TPACPI_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */
3788 "\\_SB.PCI0.IDE0.IDEP.IDPS", /* 600e/x, 770e, 770x */ 3788 "\\_SB.PCI0.IDE0.IDEP.IDPS", /* 600e/x, 770e, 770x */
3789 ); /* all others */ 3789 ); /* all others */
3790 TPACPI_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */ 3790 TPACPI_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */
3791 "_EJ0", /* 770x */ 3791 "_EJ0", /* 770x */
3792 ); /* all others */ 3792 ); /* all others */
3793 3793
3794 static int __init bay_init(struct ibm_init_struct *iibm) 3794 static int __init bay_init(struct ibm_init_struct *iibm)
3795 { 3795 {
3796 vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n"); 3796 vdbg_printk(TPACPI_DBG_INIT, "initializing bay subdriver\n");
3797 3797
3798 TPACPI_ACPIHANDLE_INIT(bay); 3798 TPACPI_ACPIHANDLE_INIT(bay);
3799 if (bay_handle) 3799 if (bay_handle)
3800 TPACPI_ACPIHANDLE_INIT(bay_ej); 3800 TPACPI_ACPIHANDLE_INIT(bay_ej);
3801 TPACPI_ACPIHANDLE_INIT(bay2); 3801 TPACPI_ACPIHANDLE_INIT(bay2);
3802 if (bay2_handle) 3802 if (bay2_handle)
3803 TPACPI_ACPIHANDLE_INIT(bay2_ej); 3803 TPACPI_ACPIHANDLE_INIT(bay2_ej);
3804 3804
3805 tp_features.bay_status = bay_handle && 3805 tp_features.bay_status = bay_handle &&
3806 acpi_evalf(bay_handle, NULL, "_STA", "qv"); 3806 acpi_evalf(bay_handle, NULL, "_STA", "qv");
3807 tp_features.bay_status2 = bay2_handle && 3807 tp_features.bay_status2 = bay2_handle &&
3808 acpi_evalf(bay2_handle, NULL, "_STA", "qv"); 3808 acpi_evalf(bay2_handle, NULL, "_STA", "qv");
3809 3809
3810 tp_features.bay_eject = bay_handle && bay_ej_handle && 3810 tp_features.bay_eject = bay_handle && bay_ej_handle &&
3811 (strlencmp(bay_ej_path, "_EJ0") == 0 || experimental); 3811 (strlencmp(bay_ej_path, "_EJ0") == 0 || experimental);
3812 tp_features.bay_eject2 = bay2_handle && bay2_ej_handle && 3812 tp_features.bay_eject2 = bay2_handle && bay2_ej_handle &&
3813 (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental); 3813 (strlencmp(bay2_ej_path, "_EJ0") == 0 || experimental);
3814 3814
3815 vdbg_printk(TPACPI_DBG_INIT, 3815 vdbg_printk(TPACPI_DBG_INIT,
3816 "bay 1: status %s, eject %s; bay 2: status %s, eject %s\n", 3816 "bay 1: status %s, eject %s; bay 2: status %s, eject %s\n",
3817 str_supported(tp_features.bay_status), 3817 str_supported(tp_features.bay_status),
3818 str_supported(tp_features.bay_eject), 3818 str_supported(tp_features.bay_eject),
3819 str_supported(tp_features.bay_status2), 3819 str_supported(tp_features.bay_status2),
3820 str_supported(tp_features.bay_eject2)); 3820 str_supported(tp_features.bay_eject2));
3821 3821
3822 return (tp_features.bay_status || tp_features.bay_eject || 3822 return (tp_features.bay_status || tp_features.bay_eject ||
3823 tp_features.bay_status2 || tp_features.bay_eject2)? 0 : 1; 3823 tp_features.bay_status2 || tp_features.bay_eject2)? 0 : 1;
3824 } 3824 }
3825 3825
3826 static void bay_notify(struct ibm_struct *ibm, u32 event) 3826 static void bay_notify(struct ibm_struct *ibm, u32 event)
3827 { 3827 {
3828 acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); 3828 acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);
3829 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 3829 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
3830 ibm->acpi->device->dev.bus_id, 3830 ibm->acpi->device->dev.bus_id,
3831 event, 0); 3831 event, 0);
3832 } 3832 }
3833 3833
3834 #define bay_occupied(b) (_sta(b##_handle) & 1) 3834 #define bay_occupied(b) (_sta(b##_handle) & 1)
3835 3835
3836 static int bay_read(char *p) 3836 static int bay_read(char *p)
3837 { 3837 {
3838 int len = 0; 3838 int len = 0;
3839 int occupied = bay_occupied(bay); 3839 int occupied = bay_occupied(bay);
3840 int occupied2 = bay_occupied(bay2); 3840 int occupied2 = bay_occupied(bay2);
3841 int eject, eject2; 3841 int eject, eject2;
3842 3842
3843 len += sprintf(p + len, "status:\t\t%s\n", 3843 len += sprintf(p + len, "status:\t\t%s\n",
3844 tp_features.bay_status ? 3844 tp_features.bay_status ?
3845 (occupied ? "occupied" : "unoccupied") : 3845 (occupied ? "occupied" : "unoccupied") :
3846 "not supported"); 3846 "not supported");
3847 if (tp_features.bay_status2) 3847 if (tp_features.bay_status2)
3848 len += sprintf(p + len, "status2:\t%s\n", occupied2 ? 3848 len += sprintf(p + len, "status2:\t%s\n", occupied2 ?
3849 "occupied" : "unoccupied"); 3849 "occupied" : "unoccupied");
3850 3850
3851 eject = tp_features.bay_eject && occupied; 3851 eject = tp_features.bay_eject && occupied;
3852 eject2 = tp_features.bay_eject2 && occupied2; 3852 eject2 = tp_features.bay_eject2 && occupied2;
3853 3853
3854 if (eject && eject2) 3854 if (eject && eject2)
3855 len += sprintf(p + len, "commands:\teject, eject2\n"); 3855 len += sprintf(p + len, "commands:\teject, eject2\n");
3856 else if (eject) 3856 else if (eject)
3857 len += sprintf(p + len, "commands:\teject\n"); 3857 len += sprintf(p + len, "commands:\teject\n");
3858 else if (eject2) 3858 else if (eject2)
3859 len += sprintf(p + len, "commands:\teject2\n"); 3859 len += sprintf(p + len, "commands:\teject2\n");
3860 3860
3861 return len; 3861 return len;
3862 } 3862 }
3863 3863
3864 static int bay_write(char *buf) 3864 static int bay_write(char *buf)
3865 { 3865 {
3866 char *cmd; 3866 char *cmd;
3867 3867
3868 if (!tp_features.bay_eject && !tp_features.bay_eject2) 3868 if (!tp_features.bay_eject && !tp_features.bay_eject2)
3869 return -ENODEV; 3869 return -ENODEV;
3870 3870
3871 while ((cmd = next_cmd(&buf))) { 3871 while ((cmd = next_cmd(&buf))) {
3872 if (tp_features.bay_eject && strlencmp(cmd, "eject") == 0) { 3872 if (tp_features.bay_eject && strlencmp(cmd, "eject") == 0) {
3873 if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1)) 3873 if (!acpi_evalf(bay_ej_handle, NULL, NULL, "vd", 1))
3874 return -EIO; 3874 return -EIO;
3875 } else if (tp_features.bay_eject2 && 3875 } else if (tp_features.bay_eject2 &&
3876 strlencmp(cmd, "eject2") == 0) { 3876 strlencmp(cmd, "eject2") == 0) {
3877 if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1)) 3877 if (!acpi_evalf(bay2_ej_handle, NULL, NULL, "vd", 1))
3878 return -EIO; 3878 return -EIO;
3879 } else 3879 } else
3880 return -EINVAL; 3880 return -EINVAL;
3881 } 3881 }
3882 3882
3883 return 0; 3883 return 0;
3884 } 3884 }
3885 3885
3886 static struct tp_acpi_drv_struct ibm_bay_acpidriver = { 3886 static struct tp_acpi_drv_struct ibm_bay_acpidriver = {
3887 .notify = bay_notify, 3887 .notify = bay_notify,
3888 .handle = &bay_handle, 3888 .handle = &bay_handle,
3889 .type = ACPI_SYSTEM_NOTIFY, 3889 .type = ACPI_SYSTEM_NOTIFY,
3890 }; 3890 };
3891 3891
3892 static struct ibm_struct bay_driver_data = { 3892 static struct ibm_struct bay_driver_data = {
3893 .name = "bay", 3893 .name = "bay",
3894 .read = bay_read, 3894 .read = bay_read,
3895 .write = bay_write, 3895 .write = bay_write,
3896 .acpi = &ibm_bay_acpidriver, 3896 .acpi = &ibm_bay_acpidriver,
3897 }; 3897 };
3898 3898
3899 #endif /* CONFIG_THINKPAD_ACPI_BAY */ 3899 #endif /* CONFIG_THINKPAD_ACPI_BAY */
3900 3900
3901 /************************************************************************* 3901 /*************************************************************************
3902 * CMOS subdriver 3902 * CMOS subdriver
3903 */ 3903 */
3904 3904
3905 /* sysfs cmos_command -------------------------------------------------- */ 3905 /* sysfs cmos_command -------------------------------------------------- */
3906 static ssize_t cmos_command_store(struct device *dev, 3906 static ssize_t cmos_command_store(struct device *dev,
3907 struct device_attribute *attr, 3907 struct device_attribute *attr,
3908 const char *buf, size_t count) 3908 const char *buf, size_t count)
3909 { 3909 {
3910 unsigned long cmos_cmd; 3910 unsigned long cmos_cmd;
3911 int res; 3911 int res;
3912 3912
3913 if (parse_strtoul(buf, 21, &cmos_cmd)) 3913 if (parse_strtoul(buf, 21, &cmos_cmd))
3914 return -EINVAL; 3914 return -EINVAL;
3915 3915
3916 res = issue_thinkpad_cmos_command(cmos_cmd); 3916 res = issue_thinkpad_cmos_command(cmos_cmd);
3917 return (res)? res : count; 3917 return (res)? res : count;
3918 } 3918 }
3919 3919
3920 static struct device_attribute dev_attr_cmos_command = 3920 static struct device_attribute dev_attr_cmos_command =
3921 __ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store); 3921 __ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store);
3922 3922
3923 /* --------------------------------------------------------------------- */ 3923 /* --------------------------------------------------------------------- */
3924 3924
3925 static int __init cmos_init(struct ibm_init_struct *iibm) 3925 static int __init cmos_init(struct ibm_init_struct *iibm)
3926 { 3926 {
3927 int res; 3927 int res;
3928 3928
3929 vdbg_printk(TPACPI_DBG_INIT, 3929 vdbg_printk(TPACPI_DBG_INIT,
3930 "initializing cmos commands subdriver\n"); 3930 "initializing cmos commands subdriver\n");
3931 3931
3932 TPACPI_ACPIHANDLE_INIT(cmos); 3932 TPACPI_ACPIHANDLE_INIT(cmos);
3933 3933
3934 vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n", 3934 vdbg_printk(TPACPI_DBG_INIT, "cmos commands are %s\n",
3935 str_supported(cmos_handle != NULL)); 3935 str_supported(cmos_handle != NULL));
3936 3936
3937 res = device_create_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 3937 res = device_create_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
3938 if (res) 3938 if (res)
3939 return res; 3939 return res;
3940 3940
3941 return (cmos_handle)? 0 : 1; 3941 return (cmos_handle)? 0 : 1;
3942 } 3942 }
3943 3943
3944 static void cmos_exit(void) 3944 static void cmos_exit(void)
3945 { 3945 {
3946 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command); 3946 device_remove_file(&tpacpi_pdev->dev, &dev_attr_cmos_command);
3947 } 3947 }
3948 3948
3949 static int cmos_read(char *p) 3949 static int cmos_read(char *p)
3950 { 3950 {
3951 int len = 0; 3951 int len = 0;
3952 3952
3953 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 3953 /* cmos not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
3954 R30, R31, T20-22, X20-21 */ 3954 R30, R31, T20-22, X20-21 */
3955 if (!cmos_handle) 3955 if (!cmos_handle)
3956 len += sprintf(p + len, "status:\t\tnot supported\n"); 3956 len += sprintf(p + len, "status:\t\tnot supported\n");
3957 else { 3957 else {
3958 len += sprintf(p + len, "status:\t\tsupported\n"); 3958 len += sprintf(p + len, "status:\t\tsupported\n");
3959 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-21)\n"); 3959 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-21)\n");
3960 } 3960 }
3961 3961
3962 return len; 3962 return len;
3963 } 3963 }
3964 3964
3965 static int cmos_write(char *buf) 3965 static int cmos_write(char *buf)
3966 { 3966 {
3967 char *cmd; 3967 char *cmd;
3968 int cmos_cmd, res; 3968 int cmos_cmd, res;
3969 3969
3970 while ((cmd = next_cmd(&buf))) { 3970 while ((cmd = next_cmd(&buf))) {
3971 if (sscanf(cmd, "%u", &cmos_cmd) == 1 && 3971 if (sscanf(cmd, "%u", &cmos_cmd) == 1 &&
3972 cmos_cmd >= 0 && cmos_cmd <= 21) { 3972 cmos_cmd >= 0 && cmos_cmd <= 21) {
3973 /* cmos_cmd set */ 3973 /* cmos_cmd set */
3974 } else 3974 } else
3975 return -EINVAL; 3975 return -EINVAL;
3976 3976
3977 res = issue_thinkpad_cmos_command(cmos_cmd); 3977 res = issue_thinkpad_cmos_command(cmos_cmd);
3978 if (res) 3978 if (res)
3979 return res; 3979 return res;
3980 } 3980 }
3981 3981
3982 return 0; 3982 return 0;
3983 } 3983 }
3984 3984
3985 static struct ibm_struct cmos_driver_data = { 3985 static struct ibm_struct cmos_driver_data = {
3986 .name = "cmos", 3986 .name = "cmos",
3987 .read = cmos_read, 3987 .read = cmos_read,
3988 .write = cmos_write, 3988 .write = cmos_write,
3989 .exit = cmos_exit, 3989 .exit = cmos_exit,
3990 }; 3990 };
3991 3991
3992 /************************************************************************* 3992 /*************************************************************************
3993 * LED subdriver 3993 * LED subdriver
3994 */ 3994 */
3995 3995
3996 enum led_access_mode { 3996 enum led_access_mode {
3997 TPACPI_LED_NONE = 0, 3997 TPACPI_LED_NONE = 0,
3998 TPACPI_LED_570, /* 570 */ 3998 TPACPI_LED_570, /* 570 */
3999 TPACPI_LED_OLD, /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ 3999 TPACPI_LED_OLD, /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
4000 TPACPI_LED_NEW, /* all others */ 4000 TPACPI_LED_NEW, /* all others */
4001 }; 4001 };
4002 4002
4003 enum { /* For TPACPI_LED_OLD */ 4003 enum { /* For TPACPI_LED_OLD */
4004 TPACPI_LED_EC_HLCL = 0x0c, /* EC reg to get led to power on */ 4004 TPACPI_LED_EC_HLCL = 0x0c, /* EC reg to get led to power on */
4005 TPACPI_LED_EC_HLBL = 0x0d, /* EC reg to blink a lit led */ 4005 TPACPI_LED_EC_HLBL = 0x0d, /* EC reg to blink a lit led */
4006 TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ 4006 TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */
4007 }; 4007 };
4008 4008
4009 enum led_status_t { 4009 enum led_status_t {
4010 TPACPI_LED_OFF = 0, 4010 TPACPI_LED_OFF = 0,
4011 TPACPI_LED_ON, 4011 TPACPI_LED_ON,
4012 TPACPI_LED_BLINK, 4012 TPACPI_LED_BLINK,
4013 }; 4013 };
4014 4014
4015 static enum led_access_mode led_supported; 4015 static enum led_access_mode led_supported;
4016 4016
4017 TPACPI_HANDLE(led, ec, "SLED", /* 570 */ 4017 TPACPI_HANDLE(led, ec, "SLED", /* 570 */
4018 "SYSL", /* 600e/x, 770e, 770x, A21e, A2xm/p, */ 4018 "SYSL", /* 600e/x, 770e, 770x, A21e, A2xm/p, */
4019 /* T20-22, X20-21 */ 4019 /* T20-22, X20-21 */
4020 "LED", /* all others */ 4020 "LED", /* all others */
4021 ); /* R30, R31 */ 4021 ); /* R30, R31 */
4022 4022
4023 #define TPACPI_LED_NUMLEDS 8 4023 #define TPACPI_LED_NUMLEDS 8
4024 static struct tpacpi_led_classdev *tpacpi_leds; 4024 static struct tpacpi_led_classdev *tpacpi_leds;
4025 static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS]; 4025 static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS];
4026 static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { 4026 static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
4027 /* there's a limit of 19 chars + NULL before 2.6.26 */ 4027 /* there's a limit of 19 chars + NULL before 2.6.26 */
4028 "tpacpi::power", 4028 "tpacpi::power",
4029 "tpacpi:orange:batt", 4029 "tpacpi:orange:batt",
4030 "tpacpi:green:batt", 4030 "tpacpi:green:batt",
4031 "tpacpi::dock_active", 4031 "tpacpi::dock_active",
4032 "tpacpi::bay_active", 4032 "tpacpi::bay_active",
4033 "tpacpi::dock_batt", 4033 "tpacpi::dock_batt",
4034 "tpacpi::unknown_led", 4034 "tpacpi::unknown_led",
4035 "tpacpi::standby", 4035 "tpacpi::standby",
4036 }; 4036 };
4037 4037
4038 static int led_get_status(const unsigned int led) 4038 static int led_get_status(const unsigned int led)
4039 { 4039 {
4040 int status; 4040 int status;
4041 enum led_status_t led_s; 4041 enum led_status_t led_s;
4042 4042
4043 switch (led_supported) { 4043 switch (led_supported) {
4044 case TPACPI_LED_570: 4044 case TPACPI_LED_570:
4045 if (!acpi_evalf(ec_handle, 4045 if (!acpi_evalf(ec_handle,
4046 &status, "GLED", "dd", 1 << led)) 4046 &status, "GLED", "dd", 1 << led))
4047 return -EIO; 4047 return -EIO;
4048 led_s = (status == 0)? 4048 led_s = (status == 0)?
4049 TPACPI_LED_OFF : 4049 TPACPI_LED_OFF :
4050 ((status == 1)? 4050 ((status == 1)?
4051 TPACPI_LED_ON : 4051 TPACPI_LED_ON :
4052 TPACPI_LED_BLINK); 4052 TPACPI_LED_BLINK);
4053 tpacpi_led_state_cache[led] = led_s; 4053 tpacpi_led_state_cache[led] = led_s;
4054 return led_s; 4054 return led_s;
4055 default: 4055 default:
4056 return -ENXIO; 4056 return -ENXIO;
4057 } 4057 }
4058 4058
4059 /* not reached */ 4059 /* not reached */
4060 } 4060 }
4061 4061
4062 static int led_set_status(const unsigned int led, 4062 static int led_set_status(const unsigned int led,
4063 const enum led_status_t ledstatus) 4063 const enum led_status_t ledstatus)
4064 { 4064 {
4065 /* off, on, blink. Index is led_status_t */ 4065 /* off, on, blink. Index is led_status_t */
4066 static const unsigned int led_sled_arg1[] = { 0, 1, 3 }; 4066 static const unsigned int led_sled_arg1[] = { 0, 1, 3 };
4067 static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 }; 4067 static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 };
4068 4068
4069 int rc = 0; 4069 int rc = 0;
4070 4070
4071 switch (led_supported) { 4071 switch (led_supported) {
4072 case TPACPI_LED_570: 4072 case TPACPI_LED_570:
4073 /* 570 */ 4073 /* 570 */
4074 if (led > 7) 4074 if (led > 7)
4075 return -EINVAL; 4075 return -EINVAL;
4076 if (!acpi_evalf(led_handle, NULL, NULL, "vdd", 4076 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
4077 (1 << led), led_sled_arg1[ledstatus])) 4077 (1 << led), led_sled_arg1[ledstatus]))
4078 rc = -EIO; 4078 rc = -EIO;
4079 break; 4079 break;
4080 case TPACPI_LED_OLD: 4080 case TPACPI_LED_OLD:
4081 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ 4081 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
4082 if (led > 7) 4082 if (led > 7)
4083 return -EINVAL; 4083 return -EINVAL;
4084 rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led)); 4084 rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
4085 if (rc >= 0) 4085 if (rc >= 0)
4086 rc = ec_write(TPACPI_LED_EC_HLBL, 4086 rc = ec_write(TPACPI_LED_EC_HLBL,
4087 (ledstatus == TPACPI_LED_BLINK) << led); 4087 (ledstatus == TPACPI_LED_BLINK) << led);
4088 if (rc >= 0) 4088 if (rc >= 0)
4089 rc = ec_write(TPACPI_LED_EC_HLCL, 4089 rc = ec_write(TPACPI_LED_EC_HLCL,
4090 (ledstatus != TPACPI_LED_OFF) << led); 4090 (ledstatus != TPACPI_LED_OFF) << led);
4091 break; 4091 break;
4092 case TPACPI_LED_NEW: 4092 case TPACPI_LED_NEW:
4093 /* all others */ 4093 /* all others */
4094 if (!acpi_evalf(led_handle, NULL, NULL, "vdd", 4094 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
4095 led, led_led_arg1[ledstatus])) 4095 led, led_led_arg1[ledstatus]))
4096 rc = -EIO; 4096 rc = -EIO;
4097 break; 4097 break;
4098 default: 4098 default:
4099 rc = -ENXIO; 4099 rc = -ENXIO;
4100 } 4100 }
4101 4101
4102 if (!rc) 4102 if (!rc)
4103 tpacpi_led_state_cache[led] = ledstatus; 4103 tpacpi_led_state_cache[led] = ledstatus;
4104 4104
4105 return rc; 4105 return rc;
4106 } 4106 }
4107 4107
4108 static void led_sysfs_set_status(unsigned int led, 4108 static void led_sysfs_set_status(unsigned int led,
4109 enum led_brightness brightness) 4109 enum led_brightness brightness)
4110 { 4110 {
4111 led_set_status(led, 4111 led_set_status(led,
4112 (brightness == LED_OFF) ? 4112 (brightness == LED_OFF) ?
4113 TPACPI_LED_OFF : 4113 TPACPI_LED_OFF :
4114 (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ? 4114 (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ?
4115 TPACPI_LED_BLINK : TPACPI_LED_ON); 4115 TPACPI_LED_BLINK : TPACPI_LED_ON);
4116 } 4116 }
4117 4117
4118 static void led_set_status_worker(struct work_struct *work) 4118 static void led_set_status_worker(struct work_struct *work)
4119 { 4119 {
4120 struct tpacpi_led_classdev *data = 4120 struct tpacpi_led_classdev *data =
4121 container_of(work, struct tpacpi_led_classdev, work); 4121 container_of(work, struct tpacpi_led_classdev, work);
4122 4122
4123 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) 4123 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
4124 led_sysfs_set_status(data->led, data->new_brightness); 4124 led_sysfs_set_status(data->led, data->new_brightness);
4125 } 4125 }
4126 4126
4127 static void led_sysfs_set(struct led_classdev *led_cdev, 4127 static void led_sysfs_set(struct led_classdev *led_cdev,
4128 enum led_brightness brightness) 4128 enum led_brightness brightness)
4129 { 4129 {
4130 struct tpacpi_led_classdev *data = container_of(led_cdev, 4130 struct tpacpi_led_classdev *data = container_of(led_cdev,
4131 struct tpacpi_led_classdev, led_classdev); 4131 struct tpacpi_led_classdev, led_classdev);
4132 4132
4133 data->new_brightness = brightness; 4133 data->new_brightness = brightness;
4134 queue_work(tpacpi_wq, &data->work); 4134 queue_work(tpacpi_wq, &data->work);
4135 } 4135 }
4136 4136
4137 static int led_sysfs_blink_set(struct led_classdev *led_cdev, 4137 static int led_sysfs_blink_set(struct led_classdev *led_cdev,
4138 unsigned long *delay_on, unsigned long *delay_off) 4138 unsigned long *delay_on, unsigned long *delay_off)
4139 { 4139 {
4140 struct tpacpi_led_classdev *data = container_of(led_cdev, 4140 struct tpacpi_led_classdev *data = container_of(led_cdev,
4141 struct tpacpi_led_classdev, led_classdev); 4141 struct tpacpi_led_classdev, led_classdev);
4142 4142
4143 /* Can we choose the flash rate? */ 4143 /* Can we choose the flash rate? */
4144 if (*delay_on == 0 && *delay_off == 0) { 4144 if (*delay_on == 0 && *delay_off == 0) {
4145 /* yes. set them to the hardware blink rate (1 Hz) */ 4145 /* yes. set them to the hardware blink rate (1 Hz) */
4146 *delay_on = 500; /* ms */ 4146 *delay_on = 500; /* ms */
4147 *delay_off = 500; /* ms */ 4147 *delay_off = 500; /* ms */
4148 } else if ((*delay_on != 500) || (*delay_off != 500)) 4148 } else if ((*delay_on != 500) || (*delay_off != 500))
4149 return -EINVAL; 4149 return -EINVAL;
4150 4150
4151 data->new_brightness = TPACPI_LED_BLINK; 4151 data->new_brightness = TPACPI_LED_BLINK;
4152 queue_work(tpacpi_wq, &data->work); 4152 queue_work(tpacpi_wq, &data->work);
4153 4153
4154 return 0; 4154 return 0;
4155 } 4155 }
4156 4156
4157 static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev) 4157 static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev)
4158 { 4158 {
4159 int rc; 4159 int rc;
4160 4160
4161 struct tpacpi_led_classdev *data = container_of(led_cdev, 4161 struct tpacpi_led_classdev *data = container_of(led_cdev,
4162 struct tpacpi_led_classdev, led_classdev); 4162 struct tpacpi_led_classdev, led_classdev);
4163 4163
4164 rc = led_get_status(data->led); 4164 rc = led_get_status(data->led);
4165 4165
4166 if (rc == TPACPI_LED_OFF || rc < 0) 4166 if (rc == TPACPI_LED_OFF || rc < 0)
4167 rc = LED_OFF; /* no error handling in led class :( */ 4167 rc = LED_OFF; /* no error handling in led class :( */
4168 else 4168 else
4169 rc = LED_FULL; 4169 rc = LED_FULL;
4170 4170
4171 return rc; 4171 return rc;
4172 } 4172 }
4173 4173
4174 static void led_exit(void) 4174 static void led_exit(void)
4175 { 4175 {
4176 unsigned int i; 4176 unsigned int i;
4177 4177
4178 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { 4178 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
4179 if (tpacpi_leds[i].led_classdev.name) 4179 if (tpacpi_leds[i].led_classdev.name)
4180 led_classdev_unregister(&tpacpi_leds[i].led_classdev); 4180 led_classdev_unregister(&tpacpi_leds[i].led_classdev);
4181 } 4181 }
4182 4182
4183 kfree(tpacpi_leds); 4183 kfree(tpacpi_leds);
4184 } 4184 }
4185 4185
4186 static int __init led_init(struct ibm_init_struct *iibm) 4186 static int __init led_init(struct ibm_init_struct *iibm)
4187 { 4187 {
4188 unsigned int i; 4188 unsigned int i;
4189 int rc; 4189 int rc;
4190 4190
4191 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); 4191 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
4192 4192
4193 TPACPI_ACPIHANDLE_INIT(led); 4193 TPACPI_ACPIHANDLE_INIT(led);
4194 4194
4195 if (!led_handle) 4195 if (!led_handle)
4196 /* led not supported on R30, R31 */ 4196 /* led not supported on R30, R31 */
4197 led_supported = TPACPI_LED_NONE; 4197 led_supported = TPACPI_LED_NONE;
4198 else if (strlencmp(led_path, "SLED") == 0) 4198 else if (strlencmp(led_path, "SLED") == 0)
4199 /* 570 */ 4199 /* 570 */
4200 led_supported = TPACPI_LED_570; 4200 led_supported = TPACPI_LED_570;
4201 else if (strlencmp(led_path, "SYSL") == 0) 4201 else if (strlencmp(led_path, "SYSL") == 0)
4202 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ 4202 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
4203 led_supported = TPACPI_LED_OLD; 4203 led_supported = TPACPI_LED_OLD;
4204 else 4204 else
4205 /* all others */ 4205 /* all others */
4206 led_supported = TPACPI_LED_NEW; 4206 led_supported = TPACPI_LED_NEW;
4207 4207
4208 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", 4208 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
4209 str_supported(led_supported), led_supported); 4209 str_supported(led_supported), led_supported);
4210 4210
4211 tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, 4211 tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS,
4212 GFP_KERNEL); 4212 GFP_KERNEL);
4213 if (!tpacpi_leds) { 4213 if (!tpacpi_leds) {
4214 printk(TPACPI_ERR "Out of memory for LED data\n"); 4214 printk(TPACPI_ERR "Out of memory for LED data\n");
4215 return -ENOMEM; 4215 return -ENOMEM;
4216 } 4216 }
4217 4217
4218 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { 4218 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
4219 tpacpi_leds[i].led = i; 4219 tpacpi_leds[i].led = i;
4220 4220
4221 tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set; 4221 tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
4222 tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set; 4222 tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
4223 if (led_supported == TPACPI_LED_570) 4223 if (led_supported == TPACPI_LED_570)
4224 tpacpi_leds[i].led_classdev.brightness_get = 4224 tpacpi_leds[i].led_classdev.brightness_get =
4225 &led_sysfs_get; 4225 &led_sysfs_get;
4226 4226
4227 tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i]; 4227 tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
4228 4228
4229 INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker); 4229 INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
4230 4230
4231 rc = led_classdev_register(&tpacpi_pdev->dev, 4231 rc = led_classdev_register(&tpacpi_pdev->dev,
4232 &tpacpi_leds[i].led_classdev); 4232 &tpacpi_leds[i].led_classdev);
4233 if (rc < 0) { 4233 if (rc < 0) {
4234 tpacpi_leds[i].led_classdev.name = NULL; 4234 tpacpi_leds[i].led_classdev.name = NULL;
4235 led_exit(); 4235 led_exit();
4236 return rc; 4236 return rc;
4237 } 4237 }
4238 } 4238 }
4239 4239
4240 return (led_supported != TPACPI_LED_NONE)? 0 : 1; 4240 return (led_supported != TPACPI_LED_NONE)? 0 : 1;
4241 } 4241 }
4242 4242
4243 #define str_led_status(s) \ 4243 #define str_led_status(s) \
4244 ((s) == TPACPI_LED_OFF ? "off" : \ 4244 ((s) == TPACPI_LED_OFF ? "off" : \
4245 ((s) == TPACPI_LED_ON ? "on" : "blinking")) 4245 ((s) == TPACPI_LED_ON ? "on" : "blinking"))
4246 4246
4247 static int led_read(char *p) 4247 static int led_read(char *p)
4248 { 4248 {
4249 int len = 0; 4249 int len = 0;
4250 4250
4251 if (!led_supported) { 4251 if (!led_supported) {
4252 len += sprintf(p + len, "status:\t\tnot supported\n"); 4252 len += sprintf(p + len, "status:\t\tnot supported\n");
4253 return len; 4253 return len;
4254 } 4254 }
4255 len += sprintf(p + len, "status:\t\tsupported\n"); 4255 len += sprintf(p + len, "status:\t\tsupported\n");
4256 4256
4257 if (led_supported == TPACPI_LED_570) { 4257 if (led_supported == TPACPI_LED_570) {
4258 /* 570 */ 4258 /* 570 */
4259 int i, status; 4259 int i, status;
4260 for (i = 0; i < 8; i++) { 4260 for (i = 0; i < 8; i++) {
4261 status = led_get_status(i); 4261 status = led_get_status(i);
4262 if (status < 0) 4262 if (status < 0)
4263 return -EIO; 4263 return -EIO;
4264 len += sprintf(p + len, "%d:\t\t%s\n", 4264 len += sprintf(p + len, "%d:\t\t%s\n",
4265 i, str_led_status(status)); 4265 i, str_led_status(status));
4266 } 4266 }
4267 } 4267 }
4268 4268
4269 len += sprintf(p + len, "commands:\t" 4269 len += sprintf(p + len, "commands:\t"
4270 "<led> on, <led> off, <led> blink (<led> is 0-7)\n"); 4270 "<led> on, <led> off, <led> blink (<led> is 0-7)\n");
4271 4271
4272 return len; 4272 return len;
4273 } 4273 }
4274 4274
4275 static int led_write(char *buf) 4275 static int led_write(char *buf)
4276 { 4276 {
4277 char *cmd; 4277 char *cmd;
4278 int led, rc; 4278 int led, rc;
4279 enum led_status_t s; 4279 enum led_status_t s;
4280 4280
4281 if (!led_supported) 4281 if (!led_supported)
4282 return -ENODEV; 4282 return -ENODEV;
4283 4283
4284 while ((cmd = next_cmd(&buf))) { 4284 while ((cmd = next_cmd(&buf))) {
4285 if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 7) 4285 if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 7)
4286 return -EINVAL; 4286 return -EINVAL;
4287 4287
4288 if (strstr(cmd, "off")) { 4288 if (strstr(cmd, "off")) {
4289 s = TPACPI_LED_OFF; 4289 s = TPACPI_LED_OFF;
4290 } else if (strstr(cmd, "on")) { 4290 } else if (strstr(cmd, "on")) {
4291 s = TPACPI_LED_ON; 4291 s = TPACPI_LED_ON;
4292 } else if (strstr(cmd, "blink")) { 4292 } else if (strstr(cmd, "blink")) {
4293 s = TPACPI_LED_BLINK; 4293 s = TPACPI_LED_BLINK;
4294 } else { 4294 } else {
4295 return -EINVAL; 4295 return -EINVAL;
4296 } 4296 }
4297 4297
4298 rc = led_set_status(led, s); 4298 rc = led_set_status(led, s);
4299 if (rc < 0) 4299 if (rc < 0)
4300 return rc; 4300 return rc;
4301 } 4301 }
4302 4302
4303 return 0; 4303 return 0;
4304 } 4304 }
4305 4305
4306 static struct ibm_struct led_driver_data = { 4306 static struct ibm_struct led_driver_data = {
4307 .name = "led", 4307 .name = "led",
4308 .read = led_read, 4308 .read = led_read,
4309 .write = led_write, 4309 .write = led_write,
4310 .exit = led_exit, 4310 .exit = led_exit,
4311 }; 4311 };
4312 4312
4313 /************************************************************************* 4313 /*************************************************************************
4314 * Beep subdriver 4314 * Beep subdriver
4315 */ 4315 */
4316 4316
4317 TPACPI_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ 4317 TPACPI_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */
4318 4318
4319 static int __init beep_init(struct ibm_init_struct *iibm) 4319 static int __init beep_init(struct ibm_init_struct *iibm)
4320 { 4320 {
4321 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n"); 4321 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
4322 4322
4323 TPACPI_ACPIHANDLE_INIT(beep); 4323 TPACPI_ACPIHANDLE_INIT(beep);
4324 4324
4325 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n", 4325 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",
4326 str_supported(beep_handle != NULL)); 4326 str_supported(beep_handle != NULL));
4327 4327
4328 return (beep_handle)? 0 : 1; 4328 return (beep_handle)? 0 : 1;
4329 } 4329 }
4330 4330
4331 static int beep_read(char *p) 4331 static int beep_read(char *p)
4332 { 4332 {
4333 int len = 0; 4333 int len = 0;
4334 4334
4335 if (!beep_handle) 4335 if (!beep_handle)
4336 len += sprintf(p + len, "status:\t\tnot supported\n"); 4336 len += sprintf(p + len, "status:\t\tnot supported\n");
4337 else { 4337 else {
4338 len += sprintf(p + len, "status:\t\tsupported\n"); 4338 len += sprintf(p + len, "status:\t\tsupported\n");
4339 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n"); 4339 len += sprintf(p + len, "commands:\t<cmd> (<cmd> is 0-17)\n");
4340 } 4340 }
4341 4341
4342 return len; 4342 return len;
4343 } 4343 }
4344 4344
4345 static int beep_write(char *buf) 4345 static int beep_write(char *buf)
4346 { 4346 {
4347 char *cmd; 4347 char *cmd;
4348 int beep_cmd; 4348 int beep_cmd;
4349 4349
4350 if (!beep_handle) 4350 if (!beep_handle)
4351 return -ENODEV; 4351 return -ENODEV;
4352 4352
4353 while ((cmd = next_cmd(&buf))) { 4353 while ((cmd = next_cmd(&buf))) {
4354 if (sscanf(cmd, "%u", &beep_cmd) == 1 && 4354 if (sscanf(cmd, "%u", &beep_cmd) == 1 &&
4355 beep_cmd >= 0 && beep_cmd <= 17) { 4355 beep_cmd >= 0 && beep_cmd <= 17) {
4356 /* beep_cmd set */ 4356 /* beep_cmd set */
4357 } else 4357 } else
4358 return -EINVAL; 4358 return -EINVAL;
4359 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0)) 4359 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0))
4360 return -EIO; 4360 return -EIO;
4361 } 4361 }
4362 4362
4363 return 0; 4363 return 0;
4364 } 4364 }
4365 4365
4366 static struct ibm_struct beep_driver_data = { 4366 static struct ibm_struct beep_driver_data = {
4367 .name = "beep", 4367 .name = "beep",
4368 .read = beep_read, 4368 .read = beep_read,
4369 .write = beep_write, 4369 .write = beep_write,
4370 }; 4370 };
4371 4371
4372 /************************************************************************* 4372 /*************************************************************************
4373 * Thermal subdriver 4373 * Thermal subdriver
4374 */ 4374 */
4375 4375
4376 enum thermal_access_mode { 4376 enum thermal_access_mode {
4377 TPACPI_THERMAL_NONE = 0, /* No thermal support */ 4377 TPACPI_THERMAL_NONE = 0, /* No thermal support */
4378 TPACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */ 4378 TPACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */
4379 TPACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */ 4379 TPACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */
4380 TPACPI_THERMAL_TPEC_8, /* Use ACPI EC regs, 8 sensors */ 4380 TPACPI_THERMAL_TPEC_8, /* Use ACPI EC regs, 8 sensors */
4381 TPACPI_THERMAL_TPEC_16, /* Use ACPI EC regs, 16 sensors */ 4381 TPACPI_THERMAL_TPEC_16, /* Use ACPI EC regs, 16 sensors */
4382 }; 4382 };
4383 4383
4384 enum { /* TPACPI_THERMAL_TPEC_* */ 4384 enum { /* TPACPI_THERMAL_TPEC_* */
4385 TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */ 4385 TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */
4386 TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */ 4386 TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */
4387 TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */ 4387 TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */
4388 }; 4388 };
4389 4389
4390 #define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */ 4390 #define TPACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */
4391 struct ibm_thermal_sensors_struct { 4391 struct ibm_thermal_sensors_struct {
4392 s32 temp[TPACPI_MAX_THERMAL_SENSORS]; 4392 s32 temp[TPACPI_MAX_THERMAL_SENSORS];
4393 }; 4393 };
4394 4394
4395 static enum thermal_access_mode thermal_read_mode; 4395 static enum thermal_access_mode thermal_read_mode;
4396 4396
4397 /* idx is zero-based */ 4397 /* idx is zero-based */
4398 static int thermal_get_sensor(int idx, s32 *value) 4398 static int thermal_get_sensor(int idx, s32 *value)
4399 { 4399 {
4400 int t; 4400 int t;
4401 s8 tmp; 4401 s8 tmp;
4402 char tmpi[5]; 4402 char tmpi[5];
4403 4403
4404 t = TP_EC_THERMAL_TMP0; 4404 t = TP_EC_THERMAL_TMP0;
4405 4405
4406 switch (thermal_read_mode) { 4406 switch (thermal_read_mode) {
4407 #if TPACPI_MAX_THERMAL_SENSORS >= 16 4407 #if TPACPI_MAX_THERMAL_SENSORS >= 16
4408 case TPACPI_THERMAL_TPEC_16: 4408 case TPACPI_THERMAL_TPEC_16:
4409 if (idx >= 8 && idx <= 15) { 4409 if (idx >= 8 && idx <= 15) {
4410 t = TP_EC_THERMAL_TMP8; 4410 t = TP_EC_THERMAL_TMP8;
4411 idx -= 8; 4411 idx -= 8;
4412 } 4412 }
4413 /* fallthrough */ 4413 /* fallthrough */
4414 #endif 4414 #endif
4415 case TPACPI_THERMAL_TPEC_8: 4415 case TPACPI_THERMAL_TPEC_8:
4416 if (idx <= 7) { 4416 if (idx <= 7) {
4417 if (!acpi_ec_read(t + idx, &tmp)) 4417 if (!acpi_ec_read(t + idx, &tmp))
4418 return -EIO; 4418 return -EIO;
4419 *value = tmp * 1000; 4419 *value = tmp * 1000;
4420 return 0; 4420 return 0;
4421 } 4421 }
4422 break; 4422 break;
4423 4423
4424 case TPACPI_THERMAL_ACPI_UPDT: 4424 case TPACPI_THERMAL_ACPI_UPDT:
4425 if (idx <= 7) { 4425 if (idx <= 7) {
4426 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); 4426 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
4427 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) 4427 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
4428 return -EIO; 4428 return -EIO;
4429 if (!acpi_evalf(ec_handle, &t, tmpi, "d")) 4429 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
4430 return -EIO; 4430 return -EIO;
4431 *value = (t - 2732) * 100; 4431 *value = (t - 2732) * 100;
4432 return 0; 4432 return 0;
4433 } 4433 }
4434 break; 4434 break;
4435 4435
4436 case TPACPI_THERMAL_ACPI_TMP07: 4436 case TPACPI_THERMAL_ACPI_TMP07:
4437 if (idx <= 7) { 4437 if (idx <= 7) {
4438 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); 4438 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
4439 if (!acpi_evalf(ec_handle, &t, tmpi, "d")) 4439 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
4440 return -EIO; 4440 return -EIO;
4441 if (t > 127 || t < -127) 4441 if (t > 127 || t < -127)
4442 t = TP_EC_THERMAL_TMP_NA; 4442 t = TP_EC_THERMAL_TMP_NA;
4443 *value = t * 1000; 4443 *value = t * 1000;
4444 return 0; 4444 return 0;
4445 } 4445 }
4446 break; 4446 break;
4447 4447
4448 case TPACPI_THERMAL_NONE: 4448 case TPACPI_THERMAL_NONE:
4449 default: 4449 default:
4450 return -ENOSYS; 4450 return -ENOSYS;
4451 } 4451 }
4452 4452
4453 return -EINVAL; 4453 return -EINVAL;
4454 } 4454 }
4455 4455
4456 static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s) 4456 static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
4457 { 4457 {
4458 int res, i; 4458 int res, i;
4459 int n; 4459 int n;
4460 4460
4461 n = 8; 4461 n = 8;
4462 i = 0; 4462 i = 0;
4463 4463
4464 if (!s) 4464 if (!s)
4465 return -EINVAL; 4465 return -EINVAL;
4466 4466
4467 if (thermal_read_mode == TPACPI_THERMAL_TPEC_16) 4467 if (thermal_read_mode == TPACPI_THERMAL_TPEC_16)
4468 n = 16; 4468 n = 16;
4469 4469
4470 for (i = 0 ; i < n; i++) { 4470 for (i = 0 ; i < n; i++) {
4471 res = thermal_get_sensor(i, &s->temp[i]); 4471 res = thermal_get_sensor(i, &s->temp[i]);
4472 if (res) 4472 if (res)
4473 return res; 4473 return res;
4474 } 4474 }
4475 4475
4476 return n; 4476 return n;
4477 } 4477 }
4478 4478
4479 /* sysfs temp##_input -------------------------------------------------- */ 4479 /* sysfs temp##_input -------------------------------------------------- */
4480 4480
4481 static ssize_t thermal_temp_input_show(struct device *dev, 4481 static ssize_t thermal_temp_input_show(struct device *dev,
4482 struct device_attribute *attr, 4482 struct device_attribute *attr,
4483 char *buf) 4483 char *buf)
4484 { 4484 {
4485 struct sensor_device_attribute *sensor_attr = 4485 struct sensor_device_attribute *sensor_attr =
4486 to_sensor_dev_attr(attr); 4486 to_sensor_dev_attr(attr);
4487 int idx = sensor_attr->index; 4487 int idx = sensor_attr->index;
4488 s32 value; 4488 s32 value;
4489 int res; 4489 int res;
4490 4490
4491 res = thermal_get_sensor(idx, &value); 4491 res = thermal_get_sensor(idx, &value);
4492 if (res) 4492 if (res)
4493 return res; 4493 return res;
4494 if (value == TP_EC_THERMAL_TMP_NA * 1000) 4494 if (value == TP_EC_THERMAL_TMP_NA * 1000)
4495 return -ENXIO; 4495 return -ENXIO;
4496 4496
4497 return snprintf(buf, PAGE_SIZE, "%d\n", value); 4497 return snprintf(buf, PAGE_SIZE, "%d\n", value);
4498 } 4498 }
4499 4499
4500 #define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \ 4500 #define THERMAL_SENSOR_ATTR_TEMP(_idxA, _idxB) \
4501 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, \ 4501 SENSOR_ATTR(temp##_idxA##_input, S_IRUGO, \
4502 thermal_temp_input_show, NULL, _idxB) 4502 thermal_temp_input_show, NULL, _idxB)
4503 4503
4504 static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = { 4504 static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] = {
4505 THERMAL_SENSOR_ATTR_TEMP(1, 0), 4505 THERMAL_SENSOR_ATTR_TEMP(1, 0),
4506 THERMAL_SENSOR_ATTR_TEMP(2, 1), 4506 THERMAL_SENSOR_ATTR_TEMP(2, 1),
4507 THERMAL_SENSOR_ATTR_TEMP(3, 2), 4507 THERMAL_SENSOR_ATTR_TEMP(3, 2),
4508 THERMAL_SENSOR_ATTR_TEMP(4, 3), 4508 THERMAL_SENSOR_ATTR_TEMP(4, 3),
4509 THERMAL_SENSOR_ATTR_TEMP(5, 4), 4509 THERMAL_SENSOR_ATTR_TEMP(5, 4),
4510 THERMAL_SENSOR_ATTR_TEMP(6, 5), 4510 THERMAL_SENSOR_ATTR_TEMP(6, 5),
4511 THERMAL_SENSOR_ATTR_TEMP(7, 6), 4511 THERMAL_SENSOR_ATTR_TEMP(7, 6),
4512 THERMAL_SENSOR_ATTR_TEMP(8, 7), 4512 THERMAL_SENSOR_ATTR_TEMP(8, 7),
4513 THERMAL_SENSOR_ATTR_TEMP(9, 8), 4513 THERMAL_SENSOR_ATTR_TEMP(9, 8),
4514 THERMAL_SENSOR_ATTR_TEMP(10, 9), 4514 THERMAL_SENSOR_ATTR_TEMP(10, 9),
4515 THERMAL_SENSOR_ATTR_TEMP(11, 10), 4515 THERMAL_SENSOR_ATTR_TEMP(11, 10),
4516 THERMAL_SENSOR_ATTR_TEMP(12, 11), 4516 THERMAL_SENSOR_ATTR_TEMP(12, 11),
4517 THERMAL_SENSOR_ATTR_TEMP(13, 12), 4517 THERMAL_SENSOR_ATTR_TEMP(13, 12),
4518 THERMAL_SENSOR_ATTR_TEMP(14, 13), 4518 THERMAL_SENSOR_ATTR_TEMP(14, 13),
4519 THERMAL_SENSOR_ATTR_TEMP(15, 14), 4519 THERMAL_SENSOR_ATTR_TEMP(15, 14),
4520 THERMAL_SENSOR_ATTR_TEMP(16, 15), 4520 THERMAL_SENSOR_ATTR_TEMP(16, 15),
4521 }; 4521 };
4522 4522
4523 #define THERMAL_ATTRS(X) \ 4523 #define THERMAL_ATTRS(X) \
4524 &sensor_dev_attr_thermal_temp_input[X].dev_attr.attr 4524 &sensor_dev_attr_thermal_temp_input[X].dev_attr.attr
4525 4525
4526 static struct attribute *thermal_temp_input_attr[] = { 4526 static struct attribute *thermal_temp_input_attr[] = {
4527 THERMAL_ATTRS(8), 4527 THERMAL_ATTRS(8),
4528 THERMAL_ATTRS(9), 4528 THERMAL_ATTRS(9),
4529 THERMAL_ATTRS(10), 4529 THERMAL_ATTRS(10),
4530 THERMAL_ATTRS(11), 4530 THERMAL_ATTRS(11),
4531 THERMAL_ATTRS(12), 4531 THERMAL_ATTRS(12),
4532 THERMAL_ATTRS(13), 4532 THERMAL_ATTRS(13),
4533 THERMAL_ATTRS(14), 4533 THERMAL_ATTRS(14),
4534 THERMAL_ATTRS(15), 4534 THERMAL_ATTRS(15),
4535 THERMAL_ATTRS(0), 4535 THERMAL_ATTRS(0),
4536 THERMAL_ATTRS(1), 4536 THERMAL_ATTRS(1),
4537 THERMAL_ATTRS(2), 4537 THERMAL_ATTRS(2),
4538 THERMAL_ATTRS(3), 4538 THERMAL_ATTRS(3),
4539 THERMAL_ATTRS(4), 4539 THERMAL_ATTRS(4),
4540 THERMAL_ATTRS(5), 4540 THERMAL_ATTRS(5),
4541 THERMAL_ATTRS(6), 4541 THERMAL_ATTRS(6),
4542 THERMAL_ATTRS(7), 4542 THERMAL_ATTRS(7),
4543 NULL 4543 NULL
4544 }; 4544 };
4545 4545
4546 static const struct attribute_group thermal_temp_input16_group = { 4546 static const struct attribute_group thermal_temp_input16_group = {
4547 .attrs = thermal_temp_input_attr 4547 .attrs = thermal_temp_input_attr
4548 }; 4548 };
4549 4549
4550 static const struct attribute_group thermal_temp_input8_group = { 4550 static const struct attribute_group thermal_temp_input8_group = {
4551 .attrs = &thermal_temp_input_attr[8] 4551 .attrs = &thermal_temp_input_attr[8]
4552 }; 4552 };
4553 4553
4554 #undef THERMAL_SENSOR_ATTR_TEMP 4554 #undef THERMAL_SENSOR_ATTR_TEMP
4555 #undef THERMAL_ATTRS 4555 #undef THERMAL_ATTRS
4556 4556
4557 /* --------------------------------------------------------------------- */ 4557 /* --------------------------------------------------------------------- */
4558 4558
4559 static int __init thermal_init(struct ibm_init_struct *iibm) 4559 static int __init thermal_init(struct ibm_init_struct *iibm)
4560 { 4560 {
4561 u8 t, ta1, ta2; 4561 u8 t, ta1, ta2;
4562 int i; 4562 int i;
4563 int acpi_tmp7; 4563 int acpi_tmp7;
4564 int res; 4564 int res;
4565 4565
4566 vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n"); 4566 vdbg_printk(TPACPI_DBG_INIT, "initializing thermal subdriver\n");
4567 4567
4568 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); 4568 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
4569 4569
4570 if (thinkpad_id.ec_model) { 4570 if (thinkpad_id.ec_model) {
4571 /* 4571 /*
4572 * Direct EC access mode: sensors at registers 4572 * Direct EC access mode: sensors at registers
4573 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for 4573 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
4574 * non-implemented, thermal sensors return 0x80 when 4574 * non-implemented, thermal sensors return 0x80 when
4575 * not available 4575 * not available
4576 */ 4576 */
4577 4577
4578 ta1 = ta2 = 0; 4578 ta1 = ta2 = 0;
4579 for (i = 0; i < 8; i++) { 4579 for (i = 0; i < 8; i++) {
4580 if (acpi_ec_read(TP_EC_THERMAL_TMP0 + i, &t)) { 4580 if (acpi_ec_read(TP_EC_THERMAL_TMP0 + i, &t)) {
4581 ta1 |= t; 4581 ta1 |= t;
4582 } else { 4582 } else {
4583 ta1 = 0; 4583 ta1 = 0;
4584 break; 4584 break;
4585 } 4585 }
4586 if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) { 4586 if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) {
4587 ta2 |= t; 4587 ta2 |= t;
4588 } else { 4588 } else {
4589 ta1 = 0; 4589 ta1 = 0;
4590 break; 4590 break;
4591 } 4591 }
4592 } 4592 }
4593 if (ta1 == 0) { 4593 if (ta1 == 0) {
4594 /* This is sheer paranoia, but we handle it anyway */ 4594 /* This is sheer paranoia, but we handle it anyway */
4595 if (acpi_tmp7) { 4595 if (acpi_tmp7) {
4596 printk(TPACPI_ERR 4596 printk(TPACPI_ERR
4597 "ThinkPad ACPI EC access misbehaving, " 4597 "ThinkPad ACPI EC access misbehaving, "
4598 "falling back to ACPI TMPx access " 4598 "falling back to ACPI TMPx access "
4599 "mode\n"); 4599 "mode\n");
4600 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; 4600 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
4601 } else { 4601 } else {
4602 printk(TPACPI_ERR 4602 printk(TPACPI_ERR
4603 "ThinkPad ACPI EC access misbehaving, " 4603 "ThinkPad ACPI EC access misbehaving, "
4604 "disabling thermal sensors access\n"); 4604 "disabling thermal sensors access\n");
4605 thermal_read_mode = TPACPI_THERMAL_NONE; 4605 thermal_read_mode = TPACPI_THERMAL_NONE;
4606 } 4606 }
4607 } else { 4607 } else {
4608 thermal_read_mode = 4608 thermal_read_mode =
4609 (ta2 != 0) ? 4609 (ta2 != 0) ?
4610 TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8; 4610 TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8;
4611 } 4611 }
4612 } else if (acpi_tmp7) { 4612 } else if (acpi_tmp7) {
4613 if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) { 4613 if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
4614 /* 600e/x, 770e, 770x */ 4614 /* 600e/x, 770e, 770x */
4615 thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT; 4615 thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT;
4616 } else { 4616 } else {
4617 /* Standard ACPI TMPx access, max 8 sensors */ 4617 /* Standard ACPI TMPx access, max 8 sensors */
4618 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; 4618 thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
4619 } 4619 }
4620 } else { 4620 } else {
4621 /* temperatures not supported on 570, G4x, R30, R31, R32 */ 4621 /* temperatures not supported on 570, G4x, R30, R31, R32 */
4622 thermal_read_mode = TPACPI_THERMAL_NONE; 4622 thermal_read_mode = TPACPI_THERMAL_NONE;
4623 } 4623 }
4624 4624
4625 vdbg_printk(TPACPI_DBG_INIT, "thermal is %s, mode %d\n", 4625 vdbg_printk(TPACPI_DBG_INIT, "thermal is %s, mode %d\n",
4626 str_supported(thermal_read_mode != TPACPI_THERMAL_NONE), 4626 str_supported(thermal_read_mode != TPACPI_THERMAL_NONE),
4627 thermal_read_mode); 4627 thermal_read_mode);
4628 4628
4629 switch (thermal_read_mode) { 4629 switch (thermal_read_mode) {
4630 case TPACPI_THERMAL_TPEC_16: 4630 case TPACPI_THERMAL_TPEC_16:
4631 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 4631 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
4632 &thermal_temp_input16_group); 4632 &thermal_temp_input16_group);
4633 if (res) 4633 if (res)
4634 return res; 4634 return res;
4635 break; 4635 break;
4636 case TPACPI_THERMAL_TPEC_8: 4636 case TPACPI_THERMAL_TPEC_8:
4637 case TPACPI_THERMAL_ACPI_TMP07: 4637 case TPACPI_THERMAL_ACPI_TMP07:
4638 case TPACPI_THERMAL_ACPI_UPDT: 4638 case TPACPI_THERMAL_ACPI_UPDT:
4639 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 4639 res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
4640 &thermal_temp_input8_group); 4640 &thermal_temp_input8_group);
4641 if (res) 4641 if (res)
4642 return res; 4642 return res;
4643 break; 4643 break;
4644 case TPACPI_THERMAL_NONE: 4644 case TPACPI_THERMAL_NONE:
4645 default: 4645 default:
4646 return 1; 4646 return 1;
4647 } 4647 }
4648 4648
4649 return 0; 4649 return 0;
4650 } 4650 }
4651 4651
4652 static void thermal_exit(void) 4652 static void thermal_exit(void)
4653 { 4653 {
4654 switch (thermal_read_mode) { 4654 switch (thermal_read_mode) {
4655 case TPACPI_THERMAL_TPEC_16: 4655 case TPACPI_THERMAL_TPEC_16:
4656 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 4656 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
4657 &thermal_temp_input16_group); 4657 &thermal_temp_input16_group);
4658 break; 4658 break;
4659 case TPACPI_THERMAL_TPEC_8: 4659 case TPACPI_THERMAL_TPEC_8:
4660 case TPACPI_THERMAL_ACPI_TMP07: 4660 case TPACPI_THERMAL_ACPI_TMP07:
4661 case TPACPI_THERMAL_ACPI_UPDT: 4661 case TPACPI_THERMAL_ACPI_UPDT:
4662 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 4662 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
4663 &thermal_temp_input16_group); 4663 &thermal_temp_input16_group);
4664 break; 4664 break;
4665 case TPACPI_THERMAL_NONE: 4665 case TPACPI_THERMAL_NONE:
4666 default: 4666 default:
4667 break; 4667 break;
4668 } 4668 }
4669 } 4669 }
4670 4670
4671 static int thermal_read(char *p) 4671 static int thermal_read(char *p)
4672 { 4672 {
4673 int len = 0; 4673 int len = 0;
4674 int n, i; 4674 int n, i;
4675 struct ibm_thermal_sensors_struct t; 4675 struct ibm_thermal_sensors_struct t;
4676 4676
4677 n = thermal_get_sensors(&t); 4677 n = thermal_get_sensors(&t);
4678 if (unlikely(n < 0)) 4678 if (unlikely(n < 0))
4679 return n; 4679 return n;
4680 4680
4681 len += sprintf(p + len, "temperatures:\t"); 4681 len += sprintf(p + len, "temperatures:\t");
4682 4682
4683 if (n > 0) { 4683 if (n > 0) {
4684 for (i = 0; i < (n - 1); i++) 4684 for (i = 0; i < (n - 1); i++)
4685 len += sprintf(p + len, "%d ", t.temp[i] / 1000); 4685 len += sprintf(p + len, "%d ", t.temp[i] / 1000);
4686 len += sprintf(p + len, "%d\n", t.temp[i] / 1000); 4686 len += sprintf(p + len, "%d\n", t.temp[i] / 1000);
4687 } else 4687 } else
4688 len += sprintf(p + len, "not supported\n"); 4688 len += sprintf(p + len, "not supported\n");
4689 4689
4690 return len; 4690 return len;
4691 } 4691 }
4692 4692
4693 static struct ibm_struct thermal_driver_data = { 4693 static struct ibm_struct thermal_driver_data = {
4694 .name = "thermal", 4694 .name = "thermal",
4695 .read = thermal_read, 4695 .read = thermal_read,
4696 .exit = thermal_exit, 4696 .exit = thermal_exit,
4697 }; 4697 };
4698 4698
4699 /************************************************************************* 4699 /*************************************************************************
4700 * EC Dump subdriver 4700 * EC Dump subdriver
4701 */ 4701 */
4702 4702
4703 static u8 ecdump_regs[256]; 4703 static u8 ecdump_regs[256];
4704 4704
4705 static int ecdump_read(char *p) 4705 static int ecdump_read(char *p)
4706 { 4706 {
4707 int len = 0; 4707 int len = 0;
4708 int i, j; 4708 int i, j;
4709 u8 v; 4709 u8 v;
4710 4710
4711 len += sprintf(p + len, "EC " 4711 len += sprintf(p + len, "EC "
4712 " +00 +01 +02 +03 +04 +05 +06 +07" 4712 " +00 +01 +02 +03 +04 +05 +06 +07"
4713 " +08 +09 +0a +0b +0c +0d +0e +0f\n"); 4713 " +08 +09 +0a +0b +0c +0d +0e +0f\n");
4714 for (i = 0; i < 256; i += 16) { 4714 for (i = 0; i < 256; i += 16) {
4715 len += sprintf(p + len, "EC 0x%02x:", i); 4715 len += sprintf(p + len, "EC 0x%02x:", i);
4716 for (j = 0; j < 16; j++) { 4716 for (j = 0; j < 16; j++) {
4717 if (!acpi_ec_read(i + j, &v)) 4717 if (!acpi_ec_read(i + j, &v))
4718 break; 4718 break;
4719 if (v != ecdump_regs[i + j]) 4719 if (v != ecdump_regs[i + j])
4720 len += sprintf(p + len, " *%02x", v); 4720 len += sprintf(p + len, " *%02x", v);
4721 else 4721 else
4722 len += sprintf(p + len, " %02x", v); 4722 len += sprintf(p + len, " %02x", v);
4723 ecdump_regs[i + j] = v; 4723 ecdump_regs[i + j] = v;
4724 } 4724 }
4725 len += sprintf(p + len, "\n"); 4725 len += sprintf(p + len, "\n");
4726 if (j != 16) 4726 if (j != 16)
4727 break; 4727 break;
4728 } 4728 }
4729 4729
4730 /* These are way too dangerous to advertise openly... */ 4730 /* These are way too dangerous to advertise openly... */
4731 #if 0 4731 #if 0
4732 len += sprintf(p + len, "commands:\t0x<offset> 0x<value>" 4732 len += sprintf(p + len, "commands:\t0x<offset> 0x<value>"
4733 " (<offset> is 00-ff, <value> is 00-ff)\n"); 4733 " (<offset> is 00-ff, <value> is 00-ff)\n");
4734 len += sprintf(p + len, "commands:\t0x<offset> <value> " 4734 len += sprintf(p + len, "commands:\t0x<offset> <value> "
4735 " (<offset> is 00-ff, <value> is 0-255)\n"); 4735 " (<offset> is 00-ff, <value> is 0-255)\n");
4736 #endif 4736 #endif
4737 return len; 4737 return len;
4738 } 4738 }
4739 4739
4740 static int ecdump_write(char *buf) 4740 static int ecdump_write(char *buf)
4741 { 4741 {
4742 char *cmd; 4742 char *cmd;
4743 int i, v; 4743 int i, v;
4744 4744
4745 while ((cmd = next_cmd(&buf))) { 4745 while ((cmd = next_cmd(&buf))) {
4746 if (sscanf(cmd, "0x%x 0x%x", &i, &v) == 2) { 4746 if (sscanf(cmd, "0x%x 0x%x", &i, &v) == 2) {
4747 /* i and v set */ 4747 /* i and v set */
4748 } else if (sscanf(cmd, "0x%x %u", &i, &v) == 2) { 4748 } else if (sscanf(cmd, "0x%x %u", &i, &v) == 2) {
4749 /* i and v set */ 4749 /* i and v set */
4750 } else 4750 } else
4751 return -EINVAL; 4751 return -EINVAL;
4752 if (i >= 0 && i < 256 && v >= 0 && v < 256) { 4752 if (i >= 0 && i < 256 && v >= 0 && v < 256) {
4753 if (!acpi_ec_write(i, v)) 4753 if (!acpi_ec_write(i, v))
4754 return -EIO; 4754 return -EIO;
4755 } else 4755 } else
4756 return -EINVAL; 4756 return -EINVAL;
4757 } 4757 }
4758 4758
4759 return 0; 4759 return 0;
4760 } 4760 }
4761 4761
4762 static struct ibm_struct ecdump_driver_data = { 4762 static struct ibm_struct ecdump_driver_data = {
4763 .name = "ecdump", 4763 .name = "ecdump",
4764 .read = ecdump_read, 4764 .read = ecdump_read,
4765 .write = ecdump_write, 4765 .write = ecdump_write,
4766 .flags.experimental = 1, 4766 .flags.experimental = 1,
4767 }; 4767 };
4768 4768
4769 /************************************************************************* 4769 /*************************************************************************
4770 * Backlight/brightness subdriver 4770 * Backlight/brightness subdriver
4771 */ 4771 */
4772 4772
4773 #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen" 4773 #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
4774 4774
4775 enum { 4775 enum {
4776 TP_EC_BACKLIGHT = 0x31, 4776 TP_EC_BACKLIGHT = 0x31,
4777 4777
4778 /* TP_EC_BACKLIGHT bitmasks */ 4778 /* TP_EC_BACKLIGHT bitmasks */
4779 TP_EC_BACKLIGHT_LVLMSK = 0x1F, 4779 TP_EC_BACKLIGHT_LVLMSK = 0x1F,
4780 TP_EC_BACKLIGHT_CMDMSK = 0xE0, 4780 TP_EC_BACKLIGHT_CMDMSK = 0xE0,
4781 TP_EC_BACKLIGHT_MAPSW = 0x20, 4781 TP_EC_BACKLIGHT_MAPSW = 0x20,
4782 }; 4782 };
4783 4783
4784 static struct backlight_device *ibm_backlight_device; 4784 static struct backlight_device *ibm_backlight_device;
4785 static int brightness_mode; 4785 static int brightness_mode;
4786 static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ 4786 static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
4787 4787
4788 static struct mutex brightness_mutex; 4788 static struct mutex brightness_mutex;
4789 4789
4790 /* 4790 /*
4791 * ThinkPads can read brightness from two places: EC 0x31, or 4791 * ThinkPads can read brightness from two places: EC 0x31, or
4792 * CMOS NVRAM byte 0x5E, bits 0-3. 4792 * CMOS NVRAM byte 0x5E, bits 0-3.
4793 * 4793 *
4794 * EC 0x31 has the following layout 4794 * EC 0x31 has the following layout
4795 * Bit 7: unknown function 4795 * Bit 7: unknown function
4796 * Bit 6: unknown function 4796 * Bit 6: unknown function
4797 * Bit 5: Z: honour scale changes, NZ: ignore scale changes 4797 * Bit 5: Z: honour scale changes, NZ: ignore scale changes
4798 * Bit 4: must be set to zero to avoid problems 4798 * Bit 4: must be set to zero to avoid problems
4799 * Bit 3-0: backlight brightness level 4799 * Bit 3-0: backlight brightness level
4800 * 4800 *
4801 * brightness_get_raw returns status data in the EC 0x31 layout 4801 * brightness_get_raw returns status data in the EC 0x31 layout
4802 */ 4802 */
4803 static int brightness_get_raw(int *status) 4803 static int brightness_get_raw(int *status)
4804 { 4804 {
4805 u8 lec = 0, lcmos = 0, level = 0; 4805 u8 lec = 0, lcmos = 0, level = 0;
4806 4806
4807 if (brightness_mode & 1) { 4807 if (brightness_mode & 1) {
4808 if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec)) 4808 if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
4809 return -EIO; 4809 return -EIO;
4810 level = lec & TP_EC_BACKLIGHT_LVLMSK; 4810 level = lec & TP_EC_BACKLIGHT_LVLMSK;
4811 }; 4811 };
4812 if (brightness_mode & 2) { 4812 if (brightness_mode & 2) {
4813 lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) 4813 lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
4814 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) 4814 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
4815 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; 4815 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
4816 lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07; 4816 lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
4817 level = lcmos; 4817 level = lcmos;
4818 } 4818 }
4819 4819
4820 if (brightness_mode == 3) { 4820 if (brightness_mode == 3) {
4821 *status = lec; /* Prefer EC, CMOS is just a backing store */ 4821 *status = lec; /* Prefer EC, CMOS is just a backing store */
4822 lec &= TP_EC_BACKLIGHT_LVLMSK; 4822 lec &= TP_EC_BACKLIGHT_LVLMSK;
4823 if (lec == lcmos) 4823 if (lec == lcmos)
4824 tp_warned.bright_cmos_ec_unsync = 0; 4824 tp_warned.bright_cmos_ec_unsync = 0;
4825 else { 4825 else {
4826 if (!tp_warned.bright_cmos_ec_unsync) { 4826 if (!tp_warned.bright_cmos_ec_unsync) {
4827 printk(TPACPI_ERR 4827 printk(TPACPI_ERR
4828 "CMOS NVRAM (%u) and EC (%u) do not " 4828 "CMOS NVRAM (%u) and EC (%u) do not "
4829 "agree on display brightness level\n", 4829 "agree on display brightness level\n",
4830 (unsigned int) lcmos, 4830 (unsigned int) lcmos,
4831 (unsigned int) lec); 4831 (unsigned int) lec);
4832 tp_warned.bright_cmos_ec_unsync = 1; 4832 tp_warned.bright_cmos_ec_unsync = 1;
4833 } 4833 }
4834 return -EIO; 4834 return -EIO;
4835 } 4835 }
4836 } else { 4836 } else {
4837 *status = level; 4837 *status = level;
4838 } 4838 }
4839 4839
4840 return 0; 4840 return 0;
4841 } 4841 }
4842 4842
4843 /* May return EINTR which can always be mapped to ERESTARTSYS */ 4843 /* May return EINTR which can always be mapped to ERESTARTSYS */
4844 static int brightness_set(int value) 4844 static int brightness_set(int value)
4845 { 4845 {
4846 int cmos_cmd, inc, i, res; 4846 int cmos_cmd, inc, i, res;
4847 int current_value; 4847 int current_value;
4848 int command_bits; 4848 int command_bits;
4849 4849
4850 if (value > ((tp_features.bright_16levels)? 15 : 7) || 4850 if (value > ((tp_features.bright_16levels)? 15 : 7) ||
4851 value < 0) 4851 value < 0)
4852 return -EINVAL; 4852 return -EINVAL;
4853 4853
4854 res = mutex_lock_interruptible(&brightness_mutex); 4854 res = mutex_lock_interruptible(&brightness_mutex);
4855 if (res < 0) 4855 if (res < 0)
4856 return res; 4856 return res;
4857 4857
4858 res = brightness_get_raw(&current_value); 4858 res = brightness_get_raw(&current_value);
4859 if (res < 0) 4859 if (res < 0)
4860 goto errout; 4860 goto errout;
4861 4861
4862 command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK; 4862 command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
4863 current_value &= TP_EC_BACKLIGHT_LVLMSK; 4863 current_value &= TP_EC_BACKLIGHT_LVLMSK;
4864 4864
4865 cmos_cmd = value > current_value ? 4865 cmos_cmd = value > current_value ?
4866 TP_CMOS_BRIGHTNESS_UP : 4866 TP_CMOS_BRIGHTNESS_UP :
4867 TP_CMOS_BRIGHTNESS_DOWN; 4867 TP_CMOS_BRIGHTNESS_DOWN;
4868 inc = (value > current_value)? 1 : -1; 4868 inc = (value > current_value)? 1 : -1;
4869 4869
4870 res = 0; 4870 res = 0;
4871 for (i = current_value; i != value; i += inc) { 4871 for (i = current_value; i != value; i += inc) {
4872 if ((brightness_mode & 2) && 4872 if ((brightness_mode & 2) &&
4873 issue_thinkpad_cmos_command(cmos_cmd)) { 4873 issue_thinkpad_cmos_command(cmos_cmd)) {
4874 res = -EIO; 4874 res = -EIO;
4875 goto errout; 4875 goto errout;
4876 } 4876 }
4877 if ((brightness_mode & 1) && 4877 if ((brightness_mode & 1) &&
4878 !acpi_ec_write(TP_EC_BACKLIGHT, 4878 !acpi_ec_write(TP_EC_BACKLIGHT,
4879 (i + inc) | command_bits)) { 4879 (i + inc) | command_bits)) {
4880 res = -EIO; 4880 res = -EIO;
4881 goto errout;; 4881 goto errout;;
4882 } 4882 }
4883 } 4883 }
4884 4884
4885 errout: 4885 errout:
4886 mutex_unlock(&brightness_mutex); 4886 mutex_unlock(&brightness_mutex);
4887 return res; 4887 return res;
4888 } 4888 }
4889 4889
4890 /* sysfs backlight class ----------------------------------------------- */ 4890 /* sysfs backlight class ----------------------------------------------- */
4891 4891
4892 static int brightness_update_status(struct backlight_device *bd) 4892 static int brightness_update_status(struct backlight_device *bd)
4893 { 4893 {
4894 /* it is the backlight class's job (caller) to handle 4894 /* it is the backlight class's job (caller) to handle
4895 * EINTR and other errors properly */ 4895 * EINTR and other errors properly */
4896 return brightness_set( 4896 return brightness_set(
4897 (bd->props.fb_blank == FB_BLANK_UNBLANK && 4897 (bd->props.fb_blank == FB_BLANK_UNBLANK &&
4898 bd->props.power == FB_BLANK_UNBLANK) ? 4898 bd->props.power == FB_BLANK_UNBLANK) ?
4899 bd->props.brightness : 0); 4899 bd->props.brightness : 0);
4900 } 4900 }
4901 4901
4902 static int brightness_get(struct backlight_device *bd) 4902 static int brightness_get(struct backlight_device *bd)
4903 { 4903 {
4904 int status, res; 4904 int status, res;
4905 4905
4906 res = brightness_get_raw(&status); 4906 res = brightness_get_raw(&status);
4907 if (res < 0) 4907 if (res < 0)
4908 return 0; /* FIXME: teach backlight about error handling */ 4908 return 0; /* FIXME: teach backlight about error handling */
4909 4909
4910 return status & TP_EC_BACKLIGHT_LVLMSK; 4910 return status & TP_EC_BACKLIGHT_LVLMSK;
4911 } 4911 }
4912 4912
4913 static struct backlight_ops ibm_backlight_data = { 4913 static struct backlight_ops ibm_backlight_data = {
4914 .get_brightness = brightness_get, 4914 .get_brightness = brightness_get,
4915 .update_status = brightness_update_status, 4915 .update_status = brightness_update_status,
4916 }; 4916 };
4917 4917
4918 /* --------------------------------------------------------------------- */ 4918 /* --------------------------------------------------------------------- */
4919 4919
4920 static int __init brightness_init(struct ibm_init_struct *iibm) 4920 static int __init brightness_init(struct ibm_init_struct *iibm)
4921 { 4921 {
4922 int b; 4922 int b;
4923 4923
4924 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); 4924 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
4925 4925
4926 mutex_init(&brightness_mutex); 4926 mutex_init(&brightness_mutex);
4927 4927
4928 /* 4928 /*
4929 * We always attempt to detect acpi support, so as to switch 4929 * We always attempt to detect acpi support, so as to switch
4930 * Lenovo Vista BIOS to ACPI brightness mode even if we are not 4930 * Lenovo Vista BIOS to ACPI brightness mode even if we are not
4931 * going to publish a backlight interface 4931 * going to publish a backlight interface
4932 */ 4932 */
4933 b = tpacpi_check_std_acpi_brightness_support(); 4933 b = tpacpi_check_std_acpi_brightness_support();
4934 if (b > 0) { 4934 if (b > 0) {
4935 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { 4935
4936 printk(TPACPI_NOTICE 4936 if (acpi_video_backlight_support()) {
4937 "Lenovo BIOS switched to ACPI backlight " 4937 if (brightness_enable > 1) {
4938 "control mode\n"); 4938 printk(TPACPI_NOTICE
4939 } 4939 "Standard ACPI backlight interface "
4940 if (brightness_enable > 1) { 4940 "available, not loading native one.\n");
4941 printk(TPACPI_NOTICE 4941 return 1;
4942 "standard ACPI backlight interface " 4942 } else if (brightness_enable == 1) {
4943 "available, not loading native one...\n"); 4943 printk(TPACPI_NOTICE
4944 return 1; 4944 "Backlight control force enabled, even if standard "
4945 "ACPI backlight interface is available\n");
4946 }
4947 } else {
4948 if (brightness_enable > 1) {
4949 printk(TPACPI_NOTICE
4950 "Standard ACPI backlight interface not "
4951 "available, thinkpad_acpi native "
4952 "brightness control enabled\n");
4953 }
4945 } 4954 }
4946 } 4955 }
4947 4956
4948 if (!brightness_enable) { 4957 if (!brightness_enable) {
4949 dbg_printk(TPACPI_DBG_INIT, 4958 dbg_printk(TPACPI_DBG_INIT,
4950 "brightness support disabled by " 4959 "brightness support disabled by "
4951 "module parameter\n"); 4960 "module parameter\n");
4952 return 1; 4961 return 1;
4953 } 4962 }
4954 4963
4955 if (b > 16) { 4964 if (b > 16) {
4956 printk(TPACPI_ERR 4965 printk(TPACPI_ERR
4957 "Unsupported brightness interface, " 4966 "Unsupported brightness interface, "
4958 "please contact %s\n", TPACPI_MAIL); 4967 "please contact %s\n", TPACPI_MAIL);
4959 return 1; 4968 return 1;
4960 } 4969 }
4961 if (b == 16) 4970 if (b == 16)
4962 tp_features.bright_16levels = 1; 4971 tp_features.bright_16levels = 1;
4963 4972
4964 if (!brightness_mode) { 4973 if (!brightness_mode) {
4965 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) 4974 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
4966 brightness_mode = 2; 4975 brightness_mode = 2;
4967 else 4976 else
4968 brightness_mode = 3; 4977 brightness_mode = 3;
4969 4978
4970 dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n", 4979 dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
4971 brightness_mode); 4980 brightness_mode);
4972 } 4981 }
4973 4982
4974 if (brightness_mode > 3) 4983 if (brightness_mode > 3)
4975 return -EINVAL; 4984 return -EINVAL;
4976 4985
4977 if (brightness_get_raw(&b) < 0) 4986 if (brightness_get_raw(&b) < 0)
4978 return 1; 4987 return 1;
4979 4988
4980 if (tp_features.bright_16levels) 4989 if (tp_features.bright_16levels)
4981 printk(TPACPI_INFO 4990 printk(TPACPI_INFO
4982 "detected a 16-level brightness capable ThinkPad\n"); 4991 "detected a 16-level brightness capable ThinkPad\n");
4983 4992
4984 ibm_backlight_device = backlight_device_register( 4993 ibm_backlight_device = backlight_device_register(
4985 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, 4994 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
4986 &ibm_backlight_data); 4995 &ibm_backlight_data);
4987 if (IS_ERR(ibm_backlight_device)) { 4996 if (IS_ERR(ibm_backlight_device)) {
4988 printk(TPACPI_ERR "Could not register backlight device\n"); 4997 printk(TPACPI_ERR "Could not register backlight device\n");
4989 return PTR_ERR(ibm_backlight_device); 4998 return PTR_ERR(ibm_backlight_device);
4990 } 4999 }
4991 vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n"); 5000 vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
4992 5001
4993 ibm_backlight_device->props.max_brightness = 5002 ibm_backlight_device->props.max_brightness =
4994 (tp_features.bright_16levels)? 15 : 7; 5003 (tp_features.bright_16levels)? 15 : 7;
4995 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; 5004 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
4996 backlight_update_status(ibm_backlight_device); 5005 backlight_update_status(ibm_backlight_device);
4997 5006
4998 return 0; 5007 return 0;
4999 } 5008 }
5000 5009
5001 static void brightness_exit(void) 5010 static void brightness_exit(void)
5002 { 5011 {
5003 if (ibm_backlight_device) { 5012 if (ibm_backlight_device) {
5004 vdbg_printk(TPACPI_DBG_EXIT, 5013 vdbg_printk(TPACPI_DBG_EXIT,
5005 "calling backlight_device_unregister()\n"); 5014 "calling backlight_device_unregister()\n");
5006 backlight_device_unregister(ibm_backlight_device); 5015 backlight_device_unregister(ibm_backlight_device);
5007 } 5016 }
5008 } 5017 }
5009 5018
5010 static int brightness_read(char *p) 5019 static int brightness_read(char *p)
5011 { 5020 {
5012 int len = 0; 5021 int len = 0;
5013 int level; 5022 int level;
5014 5023
5015 level = brightness_get(NULL); 5024 level = brightness_get(NULL);
5016 if (level < 0) { 5025 if (level < 0) {
5017 len += sprintf(p + len, "level:\t\tunreadable\n"); 5026 len += sprintf(p + len, "level:\t\tunreadable\n");
5018 } else { 5027 } else {
5019 len += sprintf(p + len, "level:\t\t%d\n", level); 5028 len += sprintf(p + len, "level:\t\t%d\n", level);
5020 len += sprintf(p + len, "commands:\tup, down\n"); 5029 len += sprintf(p + len, "commands:\tup, down\n");
5021 len += sprintf(p + len, "commands:\tlevel <level>" 5030 len += sprintf(p + len, "commands:\tlevel <level>"
5022 " (<level> is 0-%d)\n", 5031 " (<level> is 0-%d)\n",
5023 (tp_features.bright_16levels) ? 15 : 7); 5032 (tp_features.bright_16levels) ? 15 : 7);
5024 } 5033 }
5025 5034
5026 return len; 5035 return len;
5027 } 5036 }
5028 5037
5029 static int brightness_write(char *buf) 5038 static int brightness_write(char *buf)
5030 { 5039 {
5031 int level; 5040 int level;
5032 int rc; 5041 int rc;
5033 char *cmd; 5042 char *cmd;
5034 int max_level = (tp_features.bright_16levels) ? 15 : 7; 5043 int max_level = (tp_features.bright_16levels) ? 15 : 7;
5035 5044
5036 level = brightness_get(NULL); 5045 level = brightness_get(NULL);
5037 if (level < 0) 5046 if (level < 0)
5038 return level; 5047 return level;
5039 5048
5040 while ((cmd = next_cmd(&buf))) { 5049 while ((cmd = next_cmd(&buf))) {
5041 if (strlencmp(cmd, "up") == 0) { 5050 if (strlencmp(cmd, "up") == 0) {
5042 if (level < max_level) 5051 if (level < max_level)
5043 level++; 5052 level++;
5044 } else if (strlencmp(cmd, "down") == 0) { 5053 } else if (strlencmp(cmd, "down") == 0) {
5045 if (level > 0) 5054 if (level > 0)
5046 level--; 5055 level--;
5047 } else if (sscanf(cmd, "level %d", &level) == 1 && 5056 } else if (sscanf(cmd, "level %d", &level) == 1 &&
5048 level >= 0 && level <= max_level) { 5057 level >= 0 && level <= max_level) {
5049 /* new level set */ 5058 /* new level set */
5050 } else 5059 } else
5051 return -EINVAL; 5060 return -EINVAL;
5052 } 5061 }
5053 5062
5054 /* 5063 /*
5055 * Now we know what the final level should be, so we try to set it. 5064 * Now we know what the final level should be, so we try to set it.
5056 * Doing it this way makes the syscall restartable in case of EINTR 5065 * Doing it this way makes the syscall restartable in case of EINTR
5057 */ 5066 */
5058 rc = brightness_set(level); 5067 rc = brightness_set(level);
5059 return (rc == -EINTR)? ERESTARTSYS : rc; 5068 return (rc == -EINTR)? ERESTARTSYS : rc;
5060 } 5069 }
5061 5070
5062 static struct ibm_struct brightness_driver_data = { 5071 static struct ibm_struct brightness_driver_data = {
5063 .name = "brightness", 5072 .name = "brightness",
5064 .read = brightness_read, 5073 .read = brightness_read,
5065 .write = brightness_write, 5074 .write = brightness_write,
5066 .exit = brightness_exit, 5075 .exit = brightness_exit,
5067 }; 5076 };
5068 5077
5069 /************************************************************************* 5078 /*************************************************************************
5070 * Volume subdriver 5079 * Volume subdriver
5071 */ 5080 */
5072 5081
5073 static int volume_offset = 0x30; 5082 static int volume_offset = 0x30;
5074 5083
5075 static int volume_read(char *p) 5084 static int volume_read(char *p)
5076 { 5085 {
5077 int len = 0; 5086 int len = 0;
5078 u8 level; 5087 u8 level;
5079 5088
5080 if (!acpi_ec_read(volume_offset, &level)) { 5089 if (!acpi_ec_read(volume_offset, &level)) {
5081 len += sprintf(p + len, "level:\t\tunreadable\n"); 5090 len += sprintf(p + len, "level:\t\tunreadable\n");
5082 } else { 5091 } else {
5083 len += sprintf(p + len, "level:\t\t%d\n", level & 0xf); 5092 len += sprintf(p + len, "level:\t\t%d\n", level & 0xf);
5084 len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6)); 5093 len += sprintf(p + len, "mute:\t\t%s\n", onoff(level, 6));
5085 len += sprintf(p + len, "commands:\tup, down, mute\n"); 5094 len += sprintf(p + len, "commands:\tup, down, mute\n");
5086 len += sprintf(p + len, "commands:\tlevel <level>" 5095 len += sprintf(p + len, "commands:\tlevel <level>"
5087 " (<level> is 0-15)\n"); 5096 " (<level> is 0-15)\n");
5088 } 5097 }
5089 5098
5090 return len; 5099 return len;
5091 } 5100 }
5092 5101
5093 static int volume_write(char *buf) 5102 static int volume_write(char *buf)
5094 { 5103 {
5095 int cmos_cmd, inc, i; 5104 int cmos_cmd, inc, i;
5096 u8 level, mute; 5105 u8 level, mute;
5097 int new_level, new_mute; 5106 int new_level, new_mute;
5098 char *cmd; 5107 char *cmd;
5099 5108
5100 while ((cmd = next_cmd(&buf))) { 5109 while ((cmd = next_cmd(&buf))) {
5101 if (!acpi_ec_read(volume_offset, &level)) 5110 if (!acpi_ec_read(volume_offset, &level))
5102 return -EIO; 5111 return -EIO;
5103 new_mute = mute = level & 0x40; 5112 new_mute = mute = level & 0x40;
5104 new_level = level = level & 0xf; 5113 new_level = level = level & 0xf;
5105 5114
5106 if (strlencmp(cmd, "up") == 0) { 5115 if (strlencmp(cmd, "up") == 0) {
5107 if (mute) 5116 if (mute)
5108 new_mute = 0; 5117 new_mute = 0;
5109 else 5118 else
5110 new_level = level == 15 ? 15 : level + 1; 5119 new_level = level == 15 ? 15 : level + 1;
5111 } else if (strlencmp(cmd, "down") == 0) { 5120 } else if (strlencmp(cmd, "down") == 0) {
5112 if (mute) 5121 if (mute)
5113 new_mute = 0; 5122 new_mute = 0;
5114 else 5123 else
5115 new_level = level == 0 ? 0 : level - 1; 5124 new_level = level == 0 ? 0 : level - 1;
5116 } else if (sscanf(cmd, "level %d", &new_level) == 1 && 5125 } else if (sscanf(cmd, "level %d", &new_level) == 1 &&
5117 new_level >= 0 && new_level <= 15) { 5126 new_level >= 0 && new_level <= 15) {
5118 /* new_level set */ 5127 /* new_level set */
5119 } else if (strlencmp(cmd, "mute") == 0) { 5128 } else if (strlencmp(cmd, "mute") == 0) {
5120 new_mute = 0x40; 5129 new_mute = 0x40;
5121 } else 5130 } else
5122 return -EINVAL; 5131 return -EINVAL;
5123 5132
5124 if (new_level != level) { 5133 if (new_level != level) {
5125 /* mute doesn't change */ 5134 /* mute doesn't change */
5126 5135
5127 cmos_cmd = (new_level > level) ? 5136 cmos_cmd = (new_level > level) ?
5128 TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN; 5137 TP_CMOS_VOLUME_UP : TP_CMOS_VOLUME_DOWN;
5129 inc = new_level > level ? 1 : -1; 5138 inc = new_level > level ? 1 : -1;
5130 5139
5131 if (mute && (issue_thinkpad_cmos_command(cmos_cmd) || 5140 if (mute && (issue_thinkpad_cmos_command(cmos_cmd) ||
5132 !acpi_ec_write(volume_offset, level))) 5141 !acpi_ec_write(volume_offset, level)))
5133 return -EIO; 5142 return -EIO;
5134 5143
5135 for (i = level; i != new_level; i += inc) 5144 for (i = level; i != new_level; i += inc)
5136 if (issue_thinkpad_cmos_command(cmos_cmd) || 5145 if (issue_thinkpad_cmos_command(cmos_cmd) ||
5137 !acpi_ec_write(volume_offset, i + inc)) 5146 !acpi_ec_write(volume_offset, i + inc))
5138 return -EIO; 5147 return -EIO;
5139 5148
5140 if (mute && 5149 if (mute &&
5141 (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) || 5150 (issue_thinkpad_cmos_command(TP_CMOS_VOLUME_MUTE) ||
5142 !acpi_ec_write(volume_offset, new_level + mute))) { 5151 !acpi_ec_write(volume_offset, new_level + mute))) {
5143 return -EIO; 5152 return -EIO;
5144 } 5153 }
5145 } 5154 }
5146 5155
5147 if (new_mute != mute) { 5156 if (new_mute != mute) {
5148 /* level doesn't change */ 5157 /* level doesn't change */
5149 5158
5150 cmos_cmd = (new_mute) ? 5159 cmos_cmd = (new_mute) ?
5151 TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP; 5160 TP_CMOS_VOLUME_MUTE : TP_CMOS_VOLUME_UP;
5152 5161
5153 if (issue_thinkpad_cmos_command(cmos_cmd) || 5162 if (issue_thinkpad_cmos_command(cmos_cmd) ||
5154 !acpi_ec_write(volume_offset, level + new_mute)) 5163 !acpi_ec_write(volume_offset, level + new_mute))
5155 return -EIO; 5164 return -EIO;
5156 } 5165 }
5157 } 5166 }
5158 5167
5159 return 0; 5168 return 0;
5160 } 5169 }
5161 5170
5162 static struct ibm_struct volume_driver_data = { 5171 static struct ibm_struct volume_driver_data = {
5163 .name = "volume", 5172 .name = "volume",
5164 .read = volume_read, 5173 .read = volume_read,
5165 .write = volume_write, 5174 .write = volume_write,
5166 }; 5175 };
5167 5176
5168 /************************************************************************* 5177 /*************************************************************************
5169 * Fan subdriver 5178 * Fan subdriver
5170 */ 5179 */
5171 5180
5172 /* 5181 /*
5173 * FAN ACCESS MODES 5182 * FAN ACCESS MODES
5174 * 5183 *
5175 * TPACPI_FAN_RD_ACPI_GFAN: 5184 * TPACPI_FAN_RD_ACPI_GFAN:
5176 * ACPI GFAN method: returns fan level 5185 * ACPI GFAN method: returns fan level
5177 * 5186 *
5178 * see TPACPI_FAN_WR_ACPI_SFAN 5187 * see TPACPI_FAN_WR_ACPI_SFAN
5179 * EC 0x2f (HFSP) not available if GFAN exists 5188 * EC 0x2f (HFSP) not available if GFAN exists
5180 * 5189 *
5181 * TPACPI_FAN_WR_ACPI_SFAN: 5190 * TPACPI_FAN_WR_ACPI_SFAN:
5182 * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max) 5191 * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
5183 * 5192 *
5184 * EC 0x2f (HFSP) might be available *for reading*, but do not use 5193 * EC 0x2f (HFSP) might be available *for reading*, but do not use
5185 * it for writing. 5194 * it for writing.
5186 * 5195 *
5187 * TPACPI_FAN_WR_TPEC: 5196 * TPACPI_FAN_WR_TPEC:
5188 * ThinkPad EC register 0x2f (HFSP): fan control loop mode 5197 * ThinkPad EC register 0x2f (HFSP): fan control loop mode
5189 * Supported on almost all ThinkPads 5198 * Supported on almost all ThinkPads
5190 * 5199 *
5191 * Fan speed changes of any sort (including those caused by the 5200 * Fan speed changes of any sort (including those caused by the
5192 * disengaged mode) are usually done slowly by the firmware as the 5201 * disengaged mode) are usually done slowly by the firmware as the
5193 * maximum ammount of fan duty cycle change per second seems to be 5202 * maximum ammount of fan duty cycle change per second seems to be
5194 * limited. 5203 * limited.
5195 * 5204 *
5196 * Reading is not available if GFAN exists. 5205 * Reading is not available if GFAN exists.
5197 * Writing is not available if SFAN exists. 5206 * Writing is not available if SFAN exists.
5198 * 5207 *
5199 * Bits 5208 * Bits
5200 * 7 automatic mode engaged; 5209 * 7 automatic mode engaged;
5201 * (default operation mode of the ThinkPad) 5210 * (default operation mode of the ThinkPad)
5202 * fan level is ignored in this mode. 5211 * fan level is ignored in this mode.
5203 * 6 full speed mode (takes precedence over bit 7); 5212 * 6 full speed mode (takes precedence over bit 7);
5204 * not available on all thinkpads. May disable 5213 * not available on all thinkpads. May disable
5205 * the tachometer while the fan controller ramps up 5214 * the tachometer while the fan controller ramps up
5206 * the speed (which can take up to a few *minutes*). 5215 * the speed (which can take up to a few *minutes*).
5207 * Speeds up fan to 100% duty-cycle, which is far above 5216 * Speeds up fan to 100% duty-cycle, which is far above
5208 * the standard RPM levels. It is not impossible that 5217 * the standard RPM levels. It is not impossible that
5209 * it could cause hardware damage. 5218 * it could cause hardware damage.
5210 * 5-3 unused in some models. Extra bits for fan level 5219 * 5-3 unused in some models. Extra bits for fan level
5211 * in others, but still useless as all values above 5220 * in others, but still useless as all values above
5212 * 7 map to the same speed as level 7 in these models. 5221 * 7 map to the same speed as level 7 in these models.
5213 * 2-0 fan level (0..7 usually) 5222 * 2-0 fan level (0..7 usually)
5214 * 0x00 = stop 5223 * 0x00 = stop
5215 * 0x07 = max (set when temperatures critical) 5224 * 0x07 = max (set when temperatures critical)
5216 * Some ThinkPads may have other levels, see 5225 * Some ThinkPads may have other levels, see
5217 * TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41) 5226 * TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
5218 * 5227 *
5219 * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at 5228 * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at
5220 * boot. Apparently the EC does not intialize it, so unless ACPI DSDT 5229 * boot. Apparently the EC does not intialize it, so unless ACPI DSDT
5221 * does so, its initial value is meaningless (0x07). 5230 * does so, its initial value is meaningless (0x07).
5222 * 5231 *
5223 * For firmware bugs, refer to: 5232 * For firmware bugs, refer to:
5224 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues 5233 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
5225 * 5234 *
5226 * ---- 5235 * ----
5227 * 5236 *
5228 * ThinkPad EC register 0x84 (LSB), 0x85 (MSB): 5237 * ThinkPad EC register 0x84 (LSB), 0x85 (MSB):
5229 * Main fan tachometer reading (in RPM) 5238 * Main fan tachometer reading (in RPM)
5230 * 5239 *
5231 * This register is present on all ThinkPads with a new-style EC, and 5240 * This register is present on all ThinkPads with a new-style EC, and
5232 * it is known not to be present on the A21m/e, and T22, as there is 5241 * it is known not to be present on the A21m/e, and T22, as there is
5233 * something else in offset 0x84 according to the ACPI DSDT. Other 5242 * something else in offset 0x84 according to the ACPI DSDT. Other
5234 * ThinkPads from this same time period (and earlier) probably lack the 5243 * ThinkPads from this same time period (and earlier) probably lack the
5235 * tachometer as well. 5244 * tachometer as well.
5236 * 5245 *
5237 * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare 5246 * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
5238 * was never fixed by IBM to report the EC firmware version string 5247 * was never fixed by IBM to report the EC firmware version string
5239 * probably support the tachometer (like the early X models), so 5248 * probably support the tachometer (like the early X models), so
5240 * detecting it is quite hard. We need more data to know for sure. 5249 * detecting it is quite hard. We need more data to know for sure.
5241 * 5250 *
5242 * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings 5251 * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings
5243 * might result. 5252 * might result.
5244 * 5253 *
5245 * FIRMWARE BUG: may go stale while the EC is switching to full speed 5254 * FIRMWARE BUG: may go stale while the EC is switching to full speed
5246 * mode. 5255 * mode.
5247 * 5256 *
5248 * For firmware bugs, refer to: 5257 * For firmware bugs, refer to:
5249 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues 5258 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
5250 * 5259 *
5251 * TPACPI_FAN_WR_ACPI_FANS: 5260 * TPACPI_FAN_WR_ACPI_FANS:
5252 * ThinkPad X31, X40, X41. Not available in the X60. 5261 * ThinkPad X31, X40, X41. Not available in the X60.
5253 * 5262 *
5254 * FANS ACPI handle: takes three arguments: low speed, medium speed, 5263 * FANS ACPI handle: takes three arguments: low speed, medium speed,
5255 * high speed. ACPI DSDT seems to map these three speeds to levels 5264 * high speed. ACPI DSDT seems to map these three speeds to levels
5256 * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH 5265 * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH
5257 * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3") 5266 * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3")
5258 * 5267 *
5259 * The speeds are stored on handles 5268 * The speeds are stored on handles
5260 * (FANA:FAN9), (FANC:FANB), (FANE:FAND). 5269 * (FANA:FAN9), (FANC:FANB), (FANE:FAND).
5261 * 5270 *
5262 * There are three default speed sets, acessible as handles: 5271 * There are three default speed sets, acessible as handles:
5263 * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H 5272 * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
5264 * 5273 *
5265 * ACPI DSDT switches which set is in use depending on various 5274 * ACPI DSDT switches which set is in use depending on various
5266 * factors. 5275 * factors.
5267 * 5276 *
5268 * TPACPI_FAN_WR_TPEC is also available and should be used to 5277 * TPACPI_FAN_WR_TPEC is also available and should be used to
5269 * command the fan. The X31/X40/X41 seems to have 8 fan levels, 5278 * command the fan. The X31/X40/X41 seems to have 8 fan levels,
5270 * but the ACPI tables just mention level 7. 5279 * but the ACPI tables just mention level 7.
5271 */ 5280 */
5272 5281
5273 enum { /* Fan control constants */ 5282 enum { /* Fan control constants */
5274 fan_status_offset = 0x2f, /* EC register 0x2f */ 5283 fan_status_offset = 0x2f, /* EC register 0x2f */
5275 fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) 5284 fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM)
5276 * 0x84 must be read before 0x85 */ 5285 * 0x84 must be read before 0x85 */
5277 5286
5278 TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */ 5287 TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */
5279 TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */ 5288 TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */
5280 5289
5281 TPACPI_FAN_LAST_LEVEL = 0x100, /* Use cached last-seen fan level */ 5290 TPACPI_FAN_LAST_LEVEL = 0x100, /* Use cached last-seen fan level */
5282 }; 5291 };
5283 5292
5284 enum fan_status_access_mode { 5293 enum fan_status_access_mode {
5285 TPACPI_FAN_NONE = 0, /* No fan status or control */ 5294 TPACPI_FAN_NONE = 0, /* No fan status or control */
5286 TPACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */ 5295 TPACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */
5287 TPACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */ 5296 TPACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */
5288 }; 5297 };
5289 5298
5290 enum fan_control_access_mode { 5299 enum fan_control_access_mode {
5291 TPACPI_FAN_WR_NONE = 0, /* No fan control */ 5300 TPACPI_FAN_WR_NONE = 0, /* No fan control */
5292 TPACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */ 5301 TPACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */
5293 TPACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */ 5302 TPACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */
5294 TPACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */ 5303 TPACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */
5295 }; 5304 };
5296 5305
5297 enum fan_control_commands { 5306 enum fan_control_commands {
5298 TPACPI_FAN_CMD_SPEED = 0x0001, /* speed command */ 5307 TPACPI_FAN_CMD_SPEED = 0x0001, /* speed command */
5299 TPACPI_FAN_CMD_LEVEL = 0x0002, /* level command */ 5308 TPACPI_FAN_CMD_LEVEL = 0x0002, /* level command */
5300 TPACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd, 5309 TPACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd,
5301 * and also watchdog cmd */ 5310 * and also watchdog cmd */
5302 }; 5311 };
5303 5312
5304 static int fan_control_allowed; 5313 static int fan_control_allowed;
5305 5314
5306 static enum fan_status_access_mode fan_status_access_mode; 5315 static enum fan_status_access_mode fan_status_access_mode;
5307 static enum fan_control_access_mode fan_control_access_mode; 5316 static enum fan_control_access_mode fan_control_access_mode;
5308 static enum fan_control_commands fan_control_commands; 5317 static enum fan_control_commands fan_control_commands;
5309 5318
5310 static u8 fan_control_initial_status; 5319 static u8 fan_control_initial_status;
5311 static u8 fan_control_desired_level; 5320 static u8 fan_control_desired_level;
5312 static int fan_watchdog_maxinterval; 5321 static int fan_watchdog_maxinterval;
5313 5322
5314 static struct mutex fan_mutex; 5323 static struct mutex fan_mutex;
5315 5324
5316 static void fan_watchdog_fire(struct work_struct *ignored); 5325 static void fan_watchdog_fire(struct work_struct *ignored);
5317 static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire); 5326 static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
5318 5327
5319 TPACPI_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */ 5328 TPACPI_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */
5320 TPACPI_HANDLE(gfan, ec, "GFAN", /* 570 */ 5329 TPACPI_HANDLE(gfan, ec, "GFAN", /* 570 */
5321 "\\FSPD", /* 600e/x, 770e, 770x */ 5330 "\\FSPD", /* 600e/x, 770e, 770x */
5322 ); /* all others */ 5331 ); /* all others */
5323 TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */ 5332 TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */
5324 "JFNS", /* 770x-JL */ 5333 "JFNS", /* 770x-JL */
5325 ); /* all others */ 5334 ); /* all others */
5326 5335
5327 /* 5336 /*
5328 * Call with fan_mutex held 5337 * Call with fan_mutex held
5329 */ 5338 */
5330 static void fan_update_desired_level(u8 status) 5339 static void fan_update_desired_level(u8 status)
5331 { 5340 {
5332 if ((status & 5341 if ((status &
5333 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) { 5342 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
5334 if (status > 7) 5343 if (status > 7)
5335 fan_control_desired_level = 7; 5344 fan_control_desired_level = 7;
5336 else 5345 else
5337 fan_control_desired_level = status; 5346 fan_control_desired_level = status;
5338 } 5347 }
5339 } 5348 }
5340 5349
5341 static int fan_get_status(u8 *status) 5350 static int fan_get_status(u8 *status)
5342 { 5351 {
5343 u8 s; 5352 u8 s;
5344 5353
5345 /* TODO: 5354 /* TODO:
5346 * Add TPACPI_FAN_RD_ACPI_FANS ? */ 5355 * Add TPACPI_FAN_RD_ACPI_FANS ? */
5347 5356
5348 switch (fan_status_access_mode) { 5357 switch (fan_status_access_mode) {
5349 case TPACPI_FAN_RD_ACPI_GFAN: 5358 case TPACPI_FAN_RD_ACPI_GFAN:
5350 /* 570, 600e/x, 770e, 770x */ 5359 /* 570, 600e/x, 770e, 770x */
5351 5360
5352 if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) 5361 if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
5353 return -EIO; 5362 return -EIO;
5354 5363
5355 if (likely(status)) 5364 if (likely(status))
5356 *status = s & 0x07; 5365 *status = s & 0x07;
5357 5366
5358 break; 5367 break;
5359 5368
5360 case TPACPI_FAN_RD_TPEC: 5369 case TPACPI_FAN_RD_TPEC:
5361 /* all except 570, 600e/x, 770e, 770x */ 5370 /* all except 570, 600e/x, 770e, 770x */
5362 if (unlikely(!acpi_ec_read(fan_status_offset, &s))) 5371 if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
5363 return -EIO; 5372 return -EIO;
5364 5373
5365 if (likely(status)) 5374 if (likely(status))
5366 *status = s; 5375 *status = s;
5367 5376
5368 break; 5377 break;
5369 5378
5370 default: 5379 default:
5371 return -ENXIO; 5380 return -ENXIO;
5372 } 5381 }
5373 5382
5374 return 0; 5383 return 0;
5375 } 5384 }
5376 5385
5377 static int fan_get_status_safe(u8 *status) 5386 static int fan_get_status_safe(u8 *status)
5378 { 5387 {
5379 int rc; 5388 int rc;
5380 u8 s; 5389 u8 s;
5381 5390
5382 if (mutex_lock_interruptible(&fan_mutex)) 5391 if (mutex_lock_interruptible(&fan_mutex))
5383 return -ERESTARTSYS; 5392 return -ERESTARTSYS;
5384 rc = fan_get_status(&s); 5393 rc = fan_get_status(&s);
5385 if (!rc) 5394 if (!rc)
5386 fan_update_desired_level(s); 5395 fan_update_desired_level(s);
5387 mutex_unlock(&fan_mutex); 5396 mutex_unlock(&fan_mutex);
5388 5397
5389 if (status) 5398 if (status)
5390 *status = s; 5399 *status = s;
5391 5400
5392 return rc; 5401 return rc;
5393 } 5402 }
5394 5403
5395 static int fan_get_speed(unsigned int *speed) 5404 static int fan_get_speed(unsigned int *speed)
5396 { 5405 {
5397 u8 hi, lo; 5406 u8 hi, lo;
5398 5407
5399 switch (fan_status_access_mode) { 5408 switch (fan_status_access_mode) {
5400 case TPACPI_FAN_RD_TPEC: 5409 case TPACPI_FAN_RD_TPEC:
5401 /* all except 570, 600e/x, 770e, 770x */ 5410 /* all except 570, 600e/x, 770e, 770x */
5402 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || 5411 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
5403 !acpi_ec_read(fan_rpm_offset + 1, &hi))) 5412 !acpi_ec_read(fan_rpm_offset + 1, &hi)))
5404 return -EIO; 5413 return -EIO;
5405 5414
5406 if (likely(speed)) 5415 if (likely(speed))
5407 *speed = (hi << 8) | lo; 5416 *speed = (hi << 8) | lo;
5408 5417
5409 break; 5418 break;
5410 5419
5411 default: 5420 default:
5412 return -ENXIO; 5421 return -ENXIO;
5413 } 5422 }
5414 5423
5415 return 0; 5424 return 0;
5416 } 5425 }
5417 5426
5418 static int fan_set_level(int level) 5427 static int fan_set_level(int level)
5419 { 5428 {
5420 if (!fan_control_allowed) 5429 if (!fan_control_allowed)
5421 return -EPERM; 5430 return -EPERM;
5422 5431
5423 switch (fan_control_access_mode) { 5432 switch (fan_control_access_mode) {
5424 case TPACPI_FAN_WR_ACPI_SFAN: 5433 case TPACPI_FAN_WR_ACPI_SFAN:
5425 if (level >= 0 && level <= 7) { 5434 if (level >= 0 && level <= 7) {
5426 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) 5435 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
5427 return -EIO; 5436 return -EIO;
5428 } else 5437 } else
5429 return -EINVAL; 5438 return -EINVAL;
5430 break; 5439 break;
5431 5440
5432 case TPACPI_FAN_WR_ACPI_FANS: 5441 case TPACPI_FAN_WR_ACPI_FANS:
5433 case TPACPI_FAN_WR_TPEC: 5442 case TPACPI_FAN_WR_TPEC:
5434 if ((level != TP_EC_FAN_AUTO) && 5443 if ((level != TP_EC_FAN_AUTO) &&
5435 (level != TP_EC_FAN_FULLSPEED) && 5444 (level != TP_EC_FAN_FULLSPEED) &&
5436 ((level < 0) || (level > 7))) 5445 ((level < 0) || (level > 7)))
5437 return -EINVAL; 5446 return -EINVAL;
5438 5447
5439 /* safety net should the EC not support AUTO 5448 /* safety net should the EC not support AUTO
5440 * or FULLSPEED mode bits and just ignore them */ 5449 * or FULLSPEED mode bits and just ignore them */
5441 if (level & TP_EC_FAN_FULLSPEED) 5450 if (level & TP_EC_FAN_FULLSPEED)
5442 level |= 7; /* safety min speed 7 */ 5451 level |= 7; /* safety min speed 7 */
5443 else if (level & TP_EC_FAN_AUTO) 5452 else if (level & TP_EC_FAN_AUTO)
5444 level |= 4; /* safety min speed 4 */ 5453 level |= 4; /* safety min speed 4 */
5445 5454
5446 if (!acpi_ec_write(fan_status_offset, level)) 5455 if (!acpi_ec_write(fan_status_offset, level))
5447 return -EIO; 5456 return -EIO;
5448 else 5457 else
5449 tp_features.fan_ctrl_status_undef = 0; 5458 tp_features.fan_ctrl_status_undef = 0;
5450 break; 5459 break;
5451 5460
5452 default: 5461 default:
5453 return -ENXIO; 5462 return -ENXIO;
5454 } 5463 }
5455 return 0; 5464 return 0;
5456 } 5465 }
5457 5466
5458 static int fan_set_level_safe(int level) 5467 static int fan_set_level_safe(int level)
5459 { 5468 {
5460 int rc; 5469 int rc;
5461 5470
5462 if (!fan_control_allowed) 5471 if (!fan_control_allowed)
5463 return -EPERM; 5472 return -EPERM;
5464 5473
5465 if (mutex_lock_interruptible(&fan_mutex)) 5474 if (mutex_lock_interruptible(&fan_mutex))
5466 return -ERESTARTSYS; 5475 return -ERESTARTSYS;
5467 5476
5468 if (level == TPACPI_FAN_LAST_LEVEL) 5477 if (level == TPACPI_FAN_LAST_LEVEL)
5469 level = fan_control_desired_level; 5478 level = fan_control_desired_level;
5470 5479
5471 rc = fan_set_level(level); 5480 rc = fan_set_level(level);
5472 if (!rc) 5481 if (!rc)
5473 fan_update_desired_level(level); 5482 fan_update_desired_level(level);
5474 5483
5475 mutex_unlock(&fan_mutex); 5484 mutex_unlock(&fan_mutex);
5476 return rc; 5485 return rc;
5477 } 5486 }
5478 5487
5479 static int fan_set_enable(void) 5488 static int fan_set_enable(void)
5480 { 5489 {
5481 u8 s; 5490 u8 s;
5482 int rc; 5491 int rc;
5483 5492
5484 if (!fan_control_allowed) 5493 if (!fan_control_allowed)
5485 return -EPERM; 5494 return -EPERM;
5486 5495
5487 if (mutex_lock_interruptible(&fan_mutex)) 5496 if (mutex_lock_interruptible(&fan_mutex))
5488 return -ERESTARTSYS; 5497 return -ERESTARTSYS;
5489 5498
5490 switch (fan_control_access_mode) { 5499 switch (fan_control_access_mode) {
5491 case TPACPI_FAN_WR_ACPI_FANS: 5500 case TPACPI_FAN_WR_ACPI_FANS:
5492 case TPACPI_FAN_WR_TPEC: 5501 case TPACPI_FAN_WR_TPEC:
5493 rc = fan_get_status(&s); 5502 rc = fan_get_status(&s);
5494 if (rc < 0) 5503 if (rc < 0)
5495 break; 5504 break;
5496 5505
5497 /* Don't go out of emergency fan mode */ 5506 /* Don't go out of emergency fan mode */
5498 if (s != 7) { 5507 if (s != 7) {
5499 s &= 0x07; 5508 s &= 0x07;
5500 s |= TP_EC_FAN_AUTO | 4; /* min fan speed 4 */ 5509 s |= TP_EC_FAN_AUTO | 4; /* min fan speed 4 */
5501 } 5510 }
5502 5511
5503 if (!acpi_ec_write(fan_status_offset, s)) 5512 if (!acpi_ec_write(fan_status_offset, s))
5504 rc = -EIO; 5513 rc = -EIO;
5505 else { 5514 else {
5506 tp_features.fan_ctrl_status_undef = 0; 5515 tp_features.fan_ctrl_status_undef = 0;
5507 rc = 0; 5516 rc = 0;
5508 } 5517 }
5509 break; 5518 break;
5510 5519
5511 case TPACPI_FAN_WR_ACPI_SFAN: 5520 case TPACPI_FAN_WR_ACPI_SFAN:
5512 rc = fan_get_status(&s); 5521 rc = fan_get_status(&s);
5513 if (rc < 0) 5522 if (rc < 0)
5514 break; 5523 break;
5515 5524
5516 s &= 0x07; 5525 s &= 0x07;
5517 5526
5518 /* Set fan to at least level 4 */ 5527 /* Set fan to at least level 4 */
5519 s |= 4; 5528 s |= 4;
5520 5529
5521 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s)) 5530 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
5522 rc = -EIO; 5531 rc = -EIO;
5523 else 5532 else
5524 rc = 0; 5533 rc = 0;
5525 break; 5534 break;
5526 5535
5527 default: 5536 default:
5528 rc = -ENXIO; 5537 rc = -ENXIO;
5529 } 5538 }
5530 5539
5531 mutex_unlock(&fan_mutex); 5540 mutex_unlock(&fan_mutex);
5532 return rc; 5541 return rc;
5533 } 5542 }
5534 5543
5535 static int fan_set_disable(void) 5544 static int fan_set_disable(void)
5536 { 5545 {
5537 int rc; 5546 int rc;
5538 5547
5539 if (!fan_control_allowed) 5548 if (!fan_control_allowed)
5540 return -EPERM; 5549 return -EPERM;
5541 5550
5542 if (mutex_lock_interruptible(&fan_mutex)) 5551 if (mutex_lock_interruptible(&fan_mutex))
5543 return -ERESTARTSYS; 5552 return -ERESTARTSYS;
5544 5553
5545 rc = 0; 5554 rc = 0;
5546 switch (fan_control_access_mode) { 5555 switch (fan_control_access_mode) {
5547 case TPACPI_FAN_WR_ACPI_FANS: 5556 case TPACPI_FAN_WR_ACPI_FANS:
5548 case TPACPI_FAN_WR_TPEC: 5557 case TPACPI_FAN_WR_TPEC:
5549 if (!acpi_ec_write(fan_status_offset, 0x00)) 5558 if (!acpi_ec_write(fan_status_offset, 0x00))
5550 rc = -EIO; 5559 rc = -EIO;
5551 else { 5560 else {
5552 fan_control_desired_level = 0; 5561 fan_control_desired_level = 0;
5553 tp_features.fan_ctrl_status_undef = 0; 5562 tp_features.fan_ctrl_status_undef = 0;
5554 } 5563 }
5555 break; 5564 break;
5556 5565
5557 case TPACPI_FAN_WR_ACPI_SFAN: 5566 case TPACPI_FAN_WR_ACPI_SFAN:
5558 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00)) 5567 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
5559 rc = -EIO; 5568 rc = -EIO;
5560 else 5569 else
5561 fan_control_desired_level = 0; 5570 fan_control_desired_level = 0;
5562 break; 5571 break;
5563 5572
5564 default: 5573 default:
5565 rc = -ENXIO; 5574 rc = -ENXIO;
5566 } 5575 }
5567 5576
5568 5577
5569 mutex_unlock(&fan_mutex); 5578 mutex_unlock(&fan_mutex);
5570 return rc; 5579 return rc;
5571 } 5580 }
5572 5581
5573 static int fan_set_speed(int speed) 5582 static int fan_set_speed(int speed)
5574 { 5583 {
5575 int rc; 5584 int rc;
5576 5585
5577 if (!fan_control_allowed) 5586 if (!fan_control_allowed)
5578 return -EPERM; 5587 return -EPERM;
5579 5588
5580 if (mutex_lock_interruptible(&fan_mutex)) 5589 if (mutex_lock_interruptible(&fan_mutex))
5581 return -ERESTARTSYS; 5590 return -ERESTARTSYS;
5582 5591
5583 rc = 0; 5592 rc = 0;
5584 switch (fan_control_access_mode) { 5593 switch (fan_control_access_mode) {
5585 case TPACPI_FAN_WR_ACPI_FANS: 5594 case TPACPI_FAN_WR_ACPI_FANS:
5586 if (speed >= 0 && speed <= 65535) { 5595 if (speed >= 0 && speed <= 65535) {
5587 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd", 5596 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
5588 speed, speed, speed)) 5597 speed, speed, speed))
5589 rc = -EIO; 5598 rc = -EIO;
5590 } else 5599 } else
5591 rc = -EINVAL; 5600 rc = -EINVAL;
5592 break; 5601 break;
5593 5602
5594 default: 5603 default:
5595 rc = -ENXIO; 5604 rc = -ENXIO;
5596 } 5605 }
5597 5606
5598 mutex_unlock(&fan_mutex); 5607 mutex_unlock(&fan_mutex);
5599 return rc; 5608 return rc;
5600 } 5609 }
5601 5610
5602 static void fan_watchdog_reset(void) 5611 static void fan_watchdog_reset(void)
5603 { 5612 {
5604 static int fan_watchdog_active; 5613 static int fan_watchdog_active;
5605 5614
5606 if (fan_control_access_mode == TPACPI_FAN_WR_NONE) 5615 if (fan_control_access_mode == TPACPI_FAN_WR_NONE)
5607 return; 5616 return;
5608 5617
5609 if (fan_watchdog_active) 5618 if (fan_watchdog_active)
5610 cancel_delayed_work(&fan_watchdog_task); 5619 cancel_delayed_work(&fan_watchdog_task);
5611 5620
5612 if (fan_watchdog_maxinterval > 0 && 5621 if (fan_watchdog_maxinterval > 0 &&
5613 tpacpi_lifecycle != TPACPI_LIFE_EXITING) { 5622 tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
5614 fan_watchdog_active = 1; 5623 fan_watchdog_active = 1;
5615 if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task, 5624 if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task,
5616 msecs_to_jiffies(fan_watchdog_maxinterval 5625 msecs_to_jiffies(fan_watchdog_maxinterval
5617 * 1000))) { 5626 * 1000))) {
5618 printk(TPACPI_ERR 5627 printk(TPACPI_ERR
5619 "failed to queue the fan watchdog, " 5628 "failed to queue the fan watchdog, "
5620 "watchdog will not trigger\n"); 5629 "watchdog will not trigger\n");
5621 } 5630 }
5622 } else 5631 } else
5623 fan_watchdog_active = 0; 5632 fan_watchdog_active = 0;
5624 } 5633 }
5625 5634
5626 static void fan_watchdog_fire(struct work_struct *ignored) 5635 static void fan_watchdog_fire(struct work_struct *ignored)
5627 { 5636 {
5628 int rc; 5637 int rc;
5629 5638
5630 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) 5639 if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
5631 return; 5640 return;
5632 5641
5633 printk(TPACPI_NOTICE "fan watchdog: enabling fan\n"); 5642 printk(TPACPI_NOTICE "fan watchdog: enabling fan\n");
5634 rc = fan_set_enable(); 5643 rc = fan_set_enable();
5635 if (rc < 0) { 5644 if (rc < 0) {
5636 printk(TPACPI_ERR "fan watchdog: error %d while enabling fan, " 5645 printk(TPACPI_ERR "fan watchdog: error %d while enabling fan, "
5637 "will try again later...\n", -rc); 5646 "will try again later...\n", -rc);
5638 /* reschedule for later */ 5647 /* reschedule for later */
5639 fan_watchdog_reset(); 5648 fan_watchdog_reset();
5640 } 5649 }
5641 } 5650 }
5642 5651
5643 /* 5652 /*
5644 * SYSFS fan layout: hwmon compatible (device) 5653 * SYSFS fan layout: hwmon compatible (device)
5645 * 5654 *
5646 * pwm*_enable: 5655 * pwm*_enable:
5647 * 0: "disengaged" mode 5656 * 0: "disengaged" mode
5648 * 1: manual mode 5657 * 1: manual mode
5649 * 2: native EC "auto" mode (recommended, hardware default) 5658 * 2: native EC "auto" mode (recommended, hardware default)
5650 * 5659 *
5651 * pwm*: set speed in manual mode, ignored otherwise. 5660 * pwm*: set speed in manual mode, ignored otherwise.
5652 * 0 is level 0; 255 is level 7. Intermediate points done with linear 5661 * 0 is level 0; 255 is level 7. Intermediate points done with linear
5653 * interpolation. 5662 * interpolation.
5654 * 5663 *
5655 * fan*_input: tachometer reading, RPM 5664 * fan*_input: tachometer reading, RPM
5656 * 5665 *
5657 * 5666 *
5658 * SYSFS fan layout: extensions 5667 * SYSFS fan layout: extensions
5659 * 5668 *
5660 * fan_watchdog (driver): 5669 * fan_watchdog (driver):
5661 * fan watchdog interval in seconds, 0 disables (default), max 120 5670 * fan watchdog interval in seconds, 0 disables (default), max 120
5662 */ 5671 */
5663 5672
5664 /* sysfs fan pwm1_enable ----------------------------------------------- */ 5673 /* sysfs fan pwm1_enable ----------------------------------------------- */
5665 static ssize_t fan_pwm1_enable_show(struct device *dev, 5674 static ssize_t fan_pwm1_enable_show(struct device *dev,
5666 struct device_attribute *attr, 5675 struct device_attribute *attr,
5667 char *buf) 5676 char *buf)
5668 { 5677 {
5669 int res, mode; 5678 int res, mode;
5670 u8 status; 5679 u8 status;
5671 5680
5672 res = fan_get_status_safe(&status); 5681 res = fan_get_status_safe(&status);
5673 if (res) 5682 if (res)
5674 return res; 5683 return res;
5675 5684
5676 if (unlikely(tp_features.fan_ctrl_status_undef)) { 5685 if (unlikely(tp_features.fan_ctrl_status_undef)) {
5677 if (status != fan_control_initial_status) { 5686 if (status != fan_control_initial_status) {
5678 tp_features.fan_ctrl_status_undef = 0; 5687 tp_features.fan_ctrl_status_undef = 0;
5679 } else { 5688 } else {
5680 /* Return most likely status. In fact, it 5689 /* Return most likely status. In fact, it
5681 * might be the only possible status */ 5690 * might be the only possible status */
5682 status = TP_EC_FAN_AUTO; 5691 status = TP_EC_FAN_AUTO;
5683 } 5692 }
5684 } 5693 }
5685 5694
5686 if (status & TP_EC_FAN_FULLSPEED) { 5695 if (status & TP_EC_FAN_FULLSPEED) {
5687 mode = 0; 5696 mode = 0;
5688 } else if (status & TP_EC_FAN_AUTO) { 5697 } else if (status & TP_EC_FAN_AUTO) {
5689 mode = 2; 5698 mode = 2;
5690 } else 5699 } else
5691 mode = 1; 5700 mode = 1;
5692 5701
5693 return snprintf(buf, PAGE_SIZE, "%d\n", mode); 5702 return snprintf(buf, PAGE_SIZE, "%d\n", mode);
5694 } 5703 }
5695 5704
5696 static ssize_t fan_pwm1_enable_store(struct device *dev, 5705 static ssize_t fan_pwm1_enable_store(struct device *dev,
5697 struct device_attribute *attr, 5706 struct device_attribute *attr,
5698 const char *buf, size_t count) 5707 const char *buf, size_t count)
5699 { 5708 {
5700 unsigned long t; 5709 unsigned long t;
5701 int res, level; 5710 int res, level;
5702 5711
5703 if (parse_strtoul(buf, 2, &t)) 5712 if (parse_strtoul(buf, 2, &t))
5704 return -EINVAL; 5713 return -EINVAL;
5705 5714
5706 switch (t) { 5715 switch (t) {
5707 case 0: 5716 case 0:
5708 level = TP_EC_FAN_FULLSPEED; 5717 level = TP_EC_FAN_FULLSPEED;
5709 break; 5718 break;
5710 case 1: 5719 case 1:
5711 level = TPACPI_FAN_LAST_LEVEL; 5720 level = TPACPI_FAN_LAST_LEVEL;
5712 break; 5721 break;
5713 case 2: 5722 case 2:
5714 level = TP_EC_FAN_AUTO; 5723 level = TP_EC_FAN_AUTO;
5715 break; 5724 break;
5716 case 3: 5725 case 3:
5717 /* reserved for software-controlled auto mode */ 5726 /* reserved for software-controlled auto mode */
5718 return -ENOSYS; 5727 return -ENOSYS;
5719 default: 5728 default:
5720 return -EINVAL; 5729 return -EINVAL;
5721 } 5730 }
5722 5731
5723 res = fan_set_level_safe(level); 5732 res = fan_set_level_safe(level);
5724 if (res == -ENXIO) 5733 if (res == -ENXIO)
5725 return -EINVAL; 5734 return -EINVAL;
5726 else if (res < 0) 5735 else if (res < 0)
5727 return res; 5736 return res;
5728 5737
5729 fan_watchdog_reset(); 5738 fan_watchdog_reset();
5730 5739
5731 return count; 5740 return count;
5732 } 5741 }
5733 5742
5734 static struct device_attribute dev_attr_fan_pwm1_enable = 5743 static struct device_attribute dev_attr_fan_pwm1_enable =
5735 __ATTR(pwm1_enable, S_IWUSR | S_IRUGO, 5744 __ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
5736 fan_pwm1_enable_show, fan_pwm1_enable_store); 5745 fan_pwm1_enable_show, fan_pwm1_enable_store);
5737 5746
5738 /* sysfs fan pwm1 ------------------------------------------------------ */ 5747 /* sysfs fan pwm1 ------------------------------------------------------ */
5739 static ssize_t fan_pwm1_show(struct device *dev, 5748 static ssize_t fan_pwm1_show(struct device *dev,
5740 struct device_attribute *attr, 5749 struct device_attribute *attr,
5741 char *buf) 5750 char *buf)
5742 { 5751 {
5743 int res; 5752 int res;
5744 u8 status; 5753 u8 status;
5745 5754
5746 res = fan_get_status_safe(&status); 5755 res = fan_get_status_safe(&status);
5747 if (res) 5756 if (res)
5748 return res; 5757 return res;
5749 5758
5750 if (unlikely(tp_features.fan_ctrl_status_undef)) { 5759 if (unlikely(tp_features.fan_ctrl_status_undef)) {
5751 if (status != fan_control_initial_status) { 5760 if (status != fan_control_initial_status) {
5752 tp_features.fan_ctrl_status_undef = 0; 5761 tp_features.fan_ctrl_status_undef = 0;
5753 } else { 5762 } else {
5754 status = TP_EC_FAN_AUTO; 5763 status = TP_EC_FAN_AUTO;
5755 } 5764 }
5756 } 5765 }
5757 5766
5758 if ((status & 5767 if ((status &
5759 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0) 5768 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)
5760 status = fan_control_desired_level; 5769 status = fan_control_desired_level;
5761 5770
5762 if (status > 7) 5771 if (status > 7)
5763 status = 7; 5772 status = 7;
5764 5773
5765 return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7); 5774 return snprintf(buf, PAGE_SIZE, "%u\n", (status * 255) / 7);
5766 } 5775 }
5767 5776
5768 static ssize_t fan_pwm1_store(struct device *dev, 5777 static ssize_t fan_pwm1_store(struct device *dev,
5769 struct device_attribute *attr, 5778 struct device_attribute *attr,
5770 const char *buf, size_t count) 5779 const char *buf, size_t count)
5771 { 5780 {
5772 unsigned long s; 5781 unsigned long s;
5773 int rc; 5782 int rc;
5774 u8 status, newlevel; 5783 u8 status, newlevel;
5775 5784
5776 if (parse_strtoul(buf, 255, &s)) 5785 if (parse_strtoul(buf, 255, &s))
5777 return -EINVAL; 5786 return -EINVAL;
5778 5787
5779 /* scale down from 0-255 to 0-7 */ 5788 /* scale down from 0-255 to 0-7 */
5780 newlevel = (s >> 5) & 0x07; 5789 newlevel = (s >> 5) & 0x07;
5781 5790
5782 if (mutex_lock_interruptible(&fan_mutex)) 5791 if (mutex_lock_interruptible(&fan_mutex))
5783 return -ERESTARTSYS; 5792 return -ERESTARTSYS;
5784 5793
5785 rc = fan_get_status(&status); 5794 rc = fan_get_status(&status);
5786 if (!rc && (status & 5795 if (!rc && (status &
5787 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) { 5796 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) == 0) {
5788 rc = fan_set_level(newlevel); 5797 rc = fan_set_level(newlevel);
5789 if (rc == -ENXIO) 5798 if (rc == -ENXIO)
5790 rc = -EINVAL; 5799 rc = -EINVAL;
5791 else if (!rc) { 5800 else if (!rc) {
5792 fan_update_desired_level(newlevel); 5801 fan_update_desired_level(newlevel);
5793 fan_watchdog_reset(); 5802 fan_watchdog_reset();
5794 } 5803 }
5795 } 5804 }
5796 5805
5797 mutex_unlock(&fan_mutex); 5806 mutex_unlock(&fan_mutex);
5798 return (rc)? rc : count; 5807 return (rc)? rc : count;
5799 } 5808 }
5800 5809
5801 static struct device_attribute dev_attr_fan_pwm1 = 5810 static struct device_attribute dev_attr_fan_pwm1 =
5802 __ATTR(pwm1, S_IWUSR | S_IRUGO, 5811 __ATTR(pwm1, S_IWUSR | S_IRUGO,
5803 fan_pwm1_show, fan_pwm1_store); 5812 fan_pwm1_show, fan_pwm1_store);
5804 5813
5805 /* sysfs fan fan1_input ------------------------------------------------ */ 5814 /* sysfs fan fan1_input ------------------------------------------------ */
5806 static ssize_t fan_fan1_input_show(struct device *dev, 5815 static ssize_t fan_fan1_input_show(struct device *dev,
5807 struct device_attribute *attr, 5816 struct device_attribute *attr,
5808 char *buf) 5817 char *buf)
5809 { 5818 {
5810 int res; 5819 int res;
5811 unsigned int speed; 5820 unsigned int speed;
5812 5821
5813 res = fan_get_speed(&speed); 5822 res = fan_get_speed(&speed);
5814 if (res < 0) 5823 if (res < 0)
5815 return res; 5824 return res;
5816 5825
5817 return snprintf(buf, PAGE_SIZE, "%u\n", speed); 5826 return snprintf(buf, PAGE_SIZE, "%u\n", speed);
5818 } 5827 }
5819 5828
5820 static struct device_attribute dev_attr_fan_fan1_input = 5829 static struct device_attribute dev_attr_fan_fan1_input =
5821 __ATTR(fan1_input, S_IRUGO, 5830 __ATTR(fan1_input, S_IRUGO,
5822 fan_fan1_input_show, NULL); 5831 fan_fan1_input_show, NULL);
5823 5832
5824 /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ 5833 /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
5825 static ssize_t fan_fan_watchdog_show(struct device_driver *drv, 5834 static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
5826 char *buf) 5835 char *buf)
5827 { 5836 {
5828 return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval); 5837 return snprintf(buf, PAGE_SIZE, "%u\n", fan_watchdog_maxinterval);
5829 } 5838 }
5830 5839
5831 static ssize_t fan_fan_watchdog_store(struct device_driver *drv, 5840 static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
5832 const char *buf, size_t count) 5841 const char *buf, size_t count)
5833 { 5842 {
5834 unsigned long t; 5843 unsigned long t;
5835 5844
5836 if (parse_strtoul(buf, 120, &t)) 5845 if (parse_strtoul(buf, 120, &t))
5837 return -EINVAL; 5846 return -EINVAL;
5838 5847
5839 if (!fan_control_allowed) 5848 if (!fan_control_allowed)
5840 return -EPERM; 5849 return -EPERM;
5841 5850
5842 fan_watchdog_maxinterval = t; 5851 fan_watchdog_maxinterval = t;
5843 fan_watchdog_reset(); 5852 fan_watchdog_reset();
5844 5853
5845 return count; 5854 return count;
5846 } 5855 }
5847 5856
5848 static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO, 5857 static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
5849 fan_fan_watchdog_show, fan_fan_watchdog_store); 5858 fan_fan_watchdog_show, fan_fan_watchdog_store);
5850 5859
5851 /* --------------------------------------------------------------------- */ 5860 /* --------------------------------------------------------------------- */
5852 static struct attribute *fan_attributes[] = { 5861 static struct attribute *fan_attributes[] = {
5853 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr, 5862 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
5854 &dev_attr_fan_fan1_input.attr, 5863 &dev_attr_fan_fan1_input.attr,
5855 NULL 5864 NULL
5856 }; 5865 };
5857 5866
5858 static const struct attribute_group fan_attr_group = { 5867 static const struct attribute_group fan_attr_group = {
5859 .attrs = fan_attributes, 5868 .attrs = fan_attributes,
5860 }; 5869 };
5861 5870
5862 static int __init fan_init(struct ibm_init_struct *iibm) 5871 static int __init fan_init(struct ibm_init_struct *iibm)
5863 { 5872 {
5864 int rc; 5873 int rc;
5865 5874
5866 vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n"); 5875 vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
5867 5876
5868 mutex_init(&fan_mutex); 5877 mutex_init(&fan_mutex);
5869 fan_status_access_mode = TPACPI_FAN_NONE; 5878 fan_status_access_mode = TPACPI_FAN_NONE;
5870 fan_control_access_mode = TPACPI_FAN_WR_NONE; 5879 fan_control_access_mode = TPACPI_FAN_WR_NONE;
5871 fan_control_commands = 0; 5880 fan_control_commands = 0;
5872 fan_watchdog_maxinterval = 0; 5881 fan_watchdog_maxinterval = 0;
5873 tp_features.fan_ctrl_status_undef = 0; 5882 tp_features.fan_ctrl_status_undef = 0;
5874 fan_control_desired_level = 7; 5883 fan_control_desired_level = 7;
5875 5884
5876 TPACPI_ACPIHANDLE_INIT(fans); 5885 TPACPI_ACPIHANDLE_INIT(fans);
5877 TPACPI_ACPIHANDLE_INIT(gfan); 5886 TPACPI_ACPIHANDLE_INIT(gfan);
5878 TPACPI_ACPIHANDLE_INIT(sfan); 5887 TPACPI_ACPIHANDLE_INIT(sfan);
5879 5888
5880 if (gfan_handle) { 5889 if (gfan_handle) {
5881 /* 570, 600e/x, 770e, 770x */ 5890 /* 570, 600e/x, 770e, 770x */
5882 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN; 5891 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
5883 } else { 5892 } else {
5884 /* all other ThinkPads: note that even old-style 5893 /* all other ThinkPads: note that even old-style
5885 * ThinkPad ECs supports the fan control register */ 5894 * ThinkPad ECs supports the fan control register */
5886 if (likely(acpi_ec_read(fan_status_offset, 5895 if (likely(acpi_ec_read(fan_status_offset,
5887 &fan_control_initial_status))) { 5896 &fan_control_initial_status))) {
5888 fan_status_access_mode = TPACPI_FAN_RD_TPEC; 5897 fan_status_access_mode = TPACPI_FAN_RD_TPEC;
5889 5898
5890 /* In some ThinkPads, neither the EC nor the ACPI 5899 /* In some ThinkPads, neither the EC nor the ACPI
5891 * DSDT initialize the fan status, and it ends up 5900 * DSDT initialize the fan status, and it ends up
5892 * being set to 0x07 when it *could* be either 5901 * being set to 0x07 when it *could* be either
5893 * 0x07 or 0x80. 5902 * 0x07 or 0x80.
5894 * 5903 *
5895 * Enable for TP-1Y (T43), TP-78 (R51e), 5904 * Enable for TP-1Y (T43), TP-78 (R51e),
5896 * TP-76 (R52), TP-70 (T43, R52), which are known 5905 * TP-76 (R52), TP-70 (T43, R52), which are known
5897 * to be buggy. */ 5906 * to be buggy. */
5898 if (fan_control_initial_status == 0x07) { 5907 if (fan_control_initial_status == 0x07) {
5899 switch (thinkpad_id.ec_model) { 5908 switch (thinkpad_id.ec_model) {
5900 case 0x5931: /* TP-1Y */ 5909 case 0x5931: /* TP-1Y */
5901 case 0x3837: /* TP-78 */ 5910 case 0x3837: /* TP-78 */
5902 case 0x3637: /* TP-76 */ 5911 case 0x3637: /* TP-76 */
5903 case 0x3037: /* TP-70 */ 5912 case 0x3037: /* TP-70 */
5904 printk(TPACPI_NOTICE 5913 printk(TPACPI_NOTICE
5905 "fan_init: initial fan status " 5914 "fan_init: initial fan status "
5906 "is unknown, assuming it is " 5915 "is unknown, assuming it is "
5907 "in auto mode\n"); 5916 "in auto mode\n");
5908 tp_features.fan_ctrl_status_undef = 1; 5917 tp_features.fan_ctrl_status_undef = 1;
5909 ;; 5918 ;;
5910 } 5919 }
5911 } 5920 }
5912 } else { 5921 } else {
5913 printk(TPACPI_ERR 5922 printk(TPACPI_ERR
5914 "ThinkPad ACPI EC access misbehaving, " 5923 "ThinkPad ACPI EC access misbehaving, "
5915 "fan status and control unavailable\n"); 5924 "fan status and control unavailable\n");
5916 return 1; 5925 return 1;
5917 } 5926 }
5918 } 5927 }
5919 5928
5920 if (sfan_handle) { 5929 if (sfan_handle) {
5921 /* 570, 770x-JL */ 5930 /* 570, 770x-JL */
5922 fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN; 5931 fan_control_access_mode = TPACPI_FAN_WR_ACPI_SFAN;
5923 fan_control_commands |= 5932 fan_control_commands |=
5924 TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE; 5933 TPACPI_FAN_CMD_LEVEL | TPACPI_FAN_CMD_ENABLE;
5925 } else { 5934 } else {
5926 if (!gfan_handle) { 5935 if (!gfan_handle) {
5927 /* gfan without sfan means no fan control */ 5936 /* gfan without sfan means no fan control */
5928 /* all other models implement TP EC 0x2f control */ 5937 /* all other models implement TP EC 0x2f control */
5929 5938
5930 if (fans_handle) { 5939 if (fans_handle) {
5931 /* X31, X40, X41 */ 5940 /* X31, X40, X41 */
5932 fan_control_access_mode = 5941 fan_control_access_mode =
5933 TPACPI_FAN_WR_ACPI_FANS; 5942 TPACPI_FAN_WR_ACPI_FANS;
5934 fan_control_commands |= 5943 fan_control_commands |=
5935 TPACPI_FAN_CMD_SPEED | 5944 TPACPI_FAN_CMD_SPEED |
5936 TPACPI_FAN_CMD_LEVEL | 5945 TPACPI_FAN_CMD_LEVEL |
5937 TPACPI_FAN_CMD_ENABLE; 5946 TPACPI_FAN_CMD_ENABLE;
5938 } else { 5947 } else {
5939 fan_control_access_mode = TPACPI_FAN_WR_TPEC; 5948 fan_control_access_mode = TPACPI_FAN_WR_TPEC;
5940 fan_control_commands |= 5949 fan_control_commands |=
5941 TPACPI_FAN_CMD_LEVEL | 5950 TPACPI_FAN_CMD_LEVEL |
5942 TPACPI_FAN_CMD_ENABLE; 5951 TPACPI_FAN_CMD_ENABLE;
5943 } 5952 }
5944 } 5953 }
5945 } 5954 }
5946 5955
5947 vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n", 5956 vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
5948 str_supported(fan_status_access_mode != TPACPI_FAN_NONE || 5957 str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
5949 fan_control_access_mode != TPACPI_FAN_WR_NONE), 5958 fan_control_access_mode != TPACPI_FAN_WR_NONE),
5950 fan_status_access_mode, fan_control_access_mode); 5959 fan_status_access_mode, fan_control_access_mode);
5951 5960
5952 /* fan control master switch */ 5961 /* fan control master switch */
5953 if (!fan_control_allowed) { 5962 if (!fan_control_allowed) {
5954 fan_control_access_mode = TPACPI_FAN_WR_NONE; 5963 fan_control_access_mode = TPACPI_FAN_WR_NONE;
5955 fan_control_commands = 0; 5964 fan_control_commands = 0;
5956 dbg_printk(TPACPI_DBG_INIT, 5965 dbg_printk(TPACPI_DBG_INIT,
5957 "fan control features disabled by parameter\n"); 5966 "fan control features disabled by parameter\n");
5958 } 5967 }
5959 5968
5960 /* update fan_control_desired_level */ 5969 /* update fan_control_desired_level */
5961 if (fan_status_access_mode != TPACPI_FAN_NONE) 5970 if (fan_status_access_mode != TPACPI_FAN_NONE)
5962 fan_get_status_safe(NULL); 5971 fan_get_status_safe(NULL);
5963 5972
5964 if (fan_status_access_mode != TPACPI_FAN_NONE || 5973 if (fan_status_access_mode != TPACPI_FAN_NONE ||
5965 fan_control_access_mode != TPACPI_FAN_WR_NONE) { 5974 fan_control_access_mode != TPACPI_FAN_WR_NONE) {
5966 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 5975 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
5967 &fan_attr_group); 5976 &fan_attr_group);
5968 if (rc < 0) 5977 if (rc < 0)
5969 return rc; 5978 return rc;
5970 5979
5971 rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, 5980 rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
5972 &driver_attr_fan_watchdog); 5981 &driver_attr_fan_watchdog);
5973 if (rc < 0) { 5982 if (rc < 0) {
5974 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 5983 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
5975 &fan_attr_group); 5984 &fan_attr_group);
5976 return rc; 5985 return rc;
5977 } 5986 }
5978 return 0; 5987 return 0;
5979 } else 5988 } else
5980 return 1; 5989 return 1;
5981 } 5990 }
5982 5991
5983 static void fan_exit(void) 5992 static void fan_exit(void)
5984 { 5993 {
5985 vdbg_printk(TPACPI_DBG_EXIT, 5994 vdbg_printk(TPACPI_DBG_EXIT,
5986 "cancelling any pending fan watchdog tasks\n"); 5995 "cancelling any pending fan watchdog tasks\n");
5987 5996
5988 /* FIXME: can we really do this unconditionally? */ 5997 /* FIXME: can we really do this unconditionally? */
5989 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); 5998 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
5990 driver_remove_file(&tpacpi_hwmon_pdriver.driver, 5999 driver_remove_file(&tpacpi_hwmon_pdriver.driver,
5991 &driver_attr_fan_watchdog); 6000 &driver_attr_fan_watchdog);
5992 6001
5993 cancel_delayed_work(&fan_watchdog_task); 6002 cancel_delayed_work(&fan_watchdog_task);
5994 flush_workqueue(tpacpi_wq); 6003 flush_workqueue(tpacpi_wq);
5995 } 6004 }
5996 6005
5997 static void fan_suspend(pm_message_t state) 6006 static void fan_suspend(pm_message_t state)
5998 { 6007 {
5999 if (!fan_control_allowed) 6008 if (!fan_control_allowed)
6000 return; 6009 return;
6001 6010
6002 /* Store fan status in cache */ 6011 /* Store fan status in cache */
6003 fan_get_status_safe(NULL); 6012 fan_get_status_safe(NULL);
6004 if (tp_features.fan_ctrl_status_undef) 6013 if (tp_features.fan_ctrl_status_undef)
6005 fan_control_desired_level = TP_EC_FAN_AUTO; 6014 fan_control_desired_level = TP_EC_FAN_AUTO;
6006 } 6015 }
6007 6016
6008 static void fan_resume(void) 6017 static void fan_resume(void)
6009 { 6018 {
6010 u8 saved_fan_level; 6019 u8 saved_fan_level;
6011 u8 current_level = 7; 6020 u8 current_level = 7;
6012 bool do_set = false; 6021 bool do_set = false;
6013 6022
6014 /* DSDT *always* updates status on resume */ 6023 /* DSDT *always* updates status on resume */
6015 tp_features.fan_ctrl_status_undef = 0; 6024 tp_features.fan_ctrl_status_undef = 0;
6016 6025
6017 saved_fan_level = fan_control_desired_level; 6026 saved_fan_level = fan_control_desired_level;
6018 if (!fan_control_allowed || 6027 if (!fan_control_allowed ||
6019 (fan_get_status_safe(&current_level) < 0)) 6028 (fan_get_status_safe(&current_level) < 0))
6020 return; 6029 return;
6021 6030
6022 switch (fan_control_access_mode) { 6031 switch (fan_control_access_mode) {
6023 case TPACPI_FAN_WR_ACPI_SFAN: 6032 case TPACPI_FAN_WR_ACPI_SFAN:
6024 do_set = (saved_fan_level > current_level); 6033 do_set = (saved_fan_level > current_level);
6025 break; 6034 break;
6026 case TPACPI_FAN_WR_ACPI_FANS: 6035 case TPACPI_FAN_WR_ACPI_FANS:
6027 case TPACPI_FAN_WR_TPEC: 6036 case TPACPI_FAN_WR_TPEC:
6028 do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) || 6037 do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) ||
6029 (saved_fan_level == 7 && 6038 (saved_fan_level == 7 &&
6030 !(current_level & TP_EC_FAN_FULLSPEED))); 6039 !(current_level & TP_EC_FAN_FULLSPEED)));
6031 break; 6040 break;
6032 default: 6041 default:
6033 return; 6042 return;
6034 } 6043 }
6035 if (do_set) { 6044 if (do_set) {
6036 printk(TPACPI_NOTICE 6045 printk(TPACPI_NOTICE
6037 "restoring fan level to 0x%02x\n", 6046 "restoring fan level to 0x%02x\n",
6038 saved_fan_level); 6047 saved_fan_level);
6039 fan_set_level_safe(saved_fan_level); 6048 fan_set_level_safe(saved_fan_level);
6040 } 6049 }
6041 } 6050 }
6042 6051
6043 static int fan_read(char *p) 6052 static int fan_read(char *p)
6044 { 6053 {
6045 int len = 0; 6054 int len = 0;
6046 int rc; 6055 int rc;
6047 u8 status; 6056 u8 status;
6048 unsigned int speed = 0; 6057 unsigned int speed = 0;
6049 6058
6050 switch (fan_status_access_mode) { 6059 switch (fan_status_access_mode) {
6051 case TPACPI_FAN_RD_ACPI_GFAN: 6060 case TPACPI_FAN_RD_ACPI_GFAN:
6052 /* 570, 600e/x, 770e, 770x */ 6061 /* 570, 600e/x, 770e, 770x */
6053 rc = fan_get_status_safe(&status); 6062 rc = fan_get_status_safe(&status);
6054 if (rc < 0) 6063 if (rc < 0)
6055 return rc; 6064 return rc;
6056 6065
6057 len += sprintf(p + len, "status:\t\t%s\n" 6066 len += sprintf(p + len, "status:\t\t%s\n"
6058 "level:\t\t%d\n", 6067 "level:\t\t%d\n",
6059 (status != 0) ? "enabled" : "disabled", status); 6068 (status != 0) ? "enabled" : "disabled", status);
6060 break; 6069 break;
6061 6070
6062 case TPACPI_FAN_RD_TPEC: 6071 case TPACPI_FAN_RD_TPEC:
6063 /* all except 570, 600e/x, 770e, 770x */ 6072 /* all except 570, 600e/x, 770e, 770x */
6064 rc = fan_get_status_safe(&status); 6073 rc = fan_get_status_safe(&status);
6065 if (rc < 0) 6074 if (rc < 0)
6066 return rc; 6075 return rc;
6067 6076
6068 if (unlikely(tp_features.fan_ctrl_status_undef)) { 6077 if (unlikely(tp_features.fan_ctrl_status_undef)) {
6069 if (status != fan_control_initial_status) 6078 if (status != fan_control_initial_status)
6070 tp_features.fan_ctrl_status_undef = 0; 6079 tp_features.fan_ctrl_status_undef = 0;
6071 else 6080 else
6072 /* Return most likely status. In fact, it 6081 /* Return most likely status. In fact, it
6073 * might be the only possible status */ 6082 * might be the only possible status */
6074 status = TP_EC_FAN_AUTO; 6083 status = TP_EC_FAN_AUTO;
6075 } 6084 }
6076 6085
6077 len += sprintf(p + len, "status:\t\t%s\n", 6086 len += sprintf(p + len, "status:\t\t%s\n",
6078 (status != 0) ? "enabled" : "disabled"); 6087 (status != 0) ? "enabled" : "disabled");
6079 6088
6080 rc = fan_get_speed(&speed); 6089 rc = fan_get_speed(&speed);
6081 if (rc < 0) 6090 if (rc < 0)
6082 return rc; 6091 return rc;
6083 6092
6084 len += sprintf(p + len, "speed:\t\t%d\n", speed); 6093 len += sprintf(p + len, "speed:\t\t%d\n", speed);
6085 6094
6086 if (status & TP_EC_FAN_FULLSPEED) 6095 if (status & TP_EC_FAN_FULLSPEED)
6087 /* Disengaged mode takes precedence */ 6096 /* Disengaged mode takes precedence */
6088 len += sprintf(p + len, "level:\t\tdisengaged\n"); 6097 len += sprintf(p + len, "level:\t\tdisengaged\n");
6089 else if (status & TP_EC_FAN_AUTO) 6098 else if (status & TP_EC_FAN_AUTO)
6090 len += sprintf(p + len, "level:\t\tauto\n"); 6099 len += sprintf(p + len, "level:\t\tauto\n");
6091 else 6100 else
6092 len += sprintf(p + len, "level:\t\t%d\n", status); 6101 len += sprintf(p + len, "level:\t\t%d\n", status);
6093 break; 6102 break;
6094 6103
6095 case TPACPI_FAN_NONE: 6104 case TPACPI_FAN_NONE:
6096 default: 6105 default:
6097 len += sprintf(p + len, "status:\t\tnot supported\n"); 6106 len += sprintf(p + len, "status:\t\tnot supported\n");
6098 } 6107 }
6099 6108
6100 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) { 6109 if (fan_control_commands & TPACPI_FAN_CMD_LEVEL) {
6101 len += sprintf(p + len, "commands:\tlevel <level>"); 6110 len += sprintf(p + len, "commands:\tlevel <level>");
6102 6111
6103 switch (fan_control_access_mode) { 6112 switch (fan_control_access_mode) {
6104 case TPACPI_FAN_WR_ACPI_SFAN: 6113 case TPACPI_FAN_WR_ACPI_SFAN:
6105 len += sprintf(p + len, " (<level> is 0-7)\n"); 6114 len += sprintf(p + len, " (<level> is 0-7)\n");
6106 break; 6115 break;
6107 6116
6108 default: 6117 default:
6109 len += sprintf(p + len, " (<level> is 0-7, " 6118 len += sprintf(p + len, " (<level> is 0-7, "
6110 "auto, disengaged, full-speed)\n"); 6119 "auto, disengaged, full-speed)\n");
6111 break; 6120 break;
6112 } 6121 }
6113 } 6122 }
6114 6123
6115 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE) 6124 if (fan_control_commands & TPACPI_FAN_CMD_ENABLE)
6116 len += sprintf(p + len, "commands:\tenable, disable\n" 6125 len += sprintf(p + len, "commands:\tenable, disable\n"
6117 "commands:\twatchdog <timeout> (<timeout> " 6126 "commands:\twatchdog <timeout> (<timeout> "
6118 "is 0 (off), 1-120 (seconds))\n"); 6127 "is 0 (off), 1-120 (seconds))\n");
6119 6128
6120 if (fan_control_commands & TPACPI_FAN_CMD_SPEED) 6129 if (fan_control_commands & TPACPI_FAN_CMD_SPEED)
6121 len += sprintf(p + len, "commands:\tspeed <speed>" 6130 len += sprintf(p + len, "commands:\tspeed <speed>"
6122 " (<speed> is 0-65535)\n"); 6131 " (<speed> is 0-65535)\n");
6123 6132
6124 return len; 6133 return len;
6125 } 6134 }
6126 6135
6127 static int fan_write_cmd_level(const char *cmd, int *rc) 6136 static int fan_write_cmd_level(const char *cmd, int *rc)
6128 { 6137 {
6129 int level; 6138 int level;
6130 6139
6131 if (strlencmp(cmd, "level auto") == 0) 6140 if (strlencmp(cmd, "level auto") == 0)
6132 level = TP_EC_FAN_AUTO; 6141 level = TP_EC_FAN_AUTO;
6133 else if ((strlencmp(cmd, "level disengaged") == 0) | 6142 else if ((strlencmp(cmd, "level disengaged") == 0) |
6134 (strlencmp(cmd, "level full-speed") == 0)) 6143 (strlencmp(cmd, "level full-speed") == 0))
6135 level = TP_EC_FAN_FULLSPEED; 6144 level = TP_EC_FAN_FULLSPEED;
6136 else if (sscanf(cmd, "level %d", &level) != 1) 6145 else if (sscanf(cmd, "level %d", &level) != 1)
6137 return 0; 6146 return 0;
6138 6147
6139 *rc = fan_set_level_safe(level); 6148 *rc = fan_set_level_safe(level);
6140 if (*rc == -ENXIO) 6149 if (*rc == -ENXIO)
6141 printk(TPACPI_ERR "level command accepted for unsupported " 6150 printk(TPACPI_ERR "level command accepted for unsupported "
6142 "access mode %d", fan_control_access_mode); 6151 "access mode %d", fan_control_access_mode);
6143 6152
6144 return 1; 6153 return 1;
6145 } 6154 }
6146 6155
6147 static int fan_write_cmd_enable(const char *cmd, int *rc) 6156 static int fan_write_cmd_enable(const char *cmd, int *rc)
6148 { 6157 {
6149 if (strlencmp(cmd, "enable") != 0) 6158 if (strlencmp(cmd, "enable") != 0)
6150 return 0; 6159 return 0;
6151 6160
6152 *rc = fan_set_enable(); 6161 *rc = fan_set_enable();
6153 if (*rc == -ENXIO) 6162 if (*rc == -ENXIO)
6154 printk(TPACPI_ERR "enable command accepted for unsupported " 6163 printk(TPACPI_ERR "enable command accepted for unsupported "
6155 "access mode %d", fan_control_access_mode); 6164 "access mode %d", fan_control_access_mode);
6156 6165
6157 return 1; 6166 return 1;
6158 } 6167 }
6159 6168
6160 static int fan_write_cmd_disable(const char *cmd, int *rc) 6169 static int fan_write_cmd_disable(const char *cmd, int *rc)
6161 { 6170 {
6162 if (strlencmp(cmd, "disable") != 0) 6171 if (strlencmp(cmd, "disable") != 0)
6163 return 0; 6172 return 0;
6164 6173
6165 *rc = fan_set_disable(); 6174 *rc = fan_set_disable();
6166 if (*rc == -ENXIO) 6175 if (*rc == -ENXIO)
6167 printk(TPACPI_ERR "disable command accepted for unsupported " 6176 printk(TPACPI_ERR "disable command accepted for unsupported "
6168 "access mode %d", fan_control_access_mode); 6177 "access mode %d", fan_control_access_mode);
6169 6178
6170 return 1; 6179 return 1;
6171 } 6180 }
6172 6181
6173 static int fan_write_cmd_speed(const char *cmd, int *rc) 6182 static int fan_write_cmd_speed(const char *cmd, int *rc)
6174 { 6183 {
6175 int speed; 6184 int speed;
6176 6185
6177 /* TODO: 6186 /* TODO:
6178 * Support speed <low> <medium> <high> ? */ 6187 * Support speed <low> <medium> <high> ? */
6179 6188
6180 if (sscanf(cmd, "speed %d", &speed) != 1) 6189 if (sscanf(cmd, "speed %d", &speed) != 1)
6181 return 0; 6190 return 0;
6182 6191
6183 *rc = fan_set_speed(speed); 6192 *rc = fan_set_speed(speed);
6184 if (*rc == -ENXIO) 6193 if (*rc == -ENXIO)
6185 printk(TPACPI_ERR "speed command accepted for unsupported " 6194 printk(TPACPI_ERR "speed command accepted for unsupported "
6186 "access mode %d", fan_control_access_mode); 6195 "access mode %d", fan_control_access_mode);
6187 6196
6188 return 1; 6197 return 1;
6189 } 6198 }
6190 6199
6191 static int fan_write_cmd_watchdog(const char *cmd, int *rc) 6200 static int fan_write_cmd_watchdog(const char *cmd, int *rc)
6192 { 6201 {
6193 int interval; 6202 int interval;
6194 6203
6195 if (sscanf(cmd, "watchdog %d", &interval) != 1) 6204 if (sscanf(cmd, "watchdog %d", &interval) != 1)
6196 return 0; 6205 return 0;
6197 6206
6198 if (interval < 0 || interval > 120) 6207 if (interval < 0 || interval > 120)
6199 *rc = -EINVAL; 6208 *rc = -EINVAL;
6200 else 6209 else
6201 fan_watchdog_maxinterval = interval; 6210 fan_watchdog_maxinterval = interval;
6202 6211
6203 return 1; 6212 return 1;
6204 } 6213 }
6205 6214
6206 static int fan_write(char *buf) 6215 static int fan_write(char *buf)
6207 { 6216 {
6208 char *cmd; 6217 char *cmd;
6209 int rc = 0; 6218 int rc = 0;
6210 6219
6211 while (!rc && (cmd = next_cmd(&buf))) { 6220 while (!rc && (cmd = next_cmd(&buf))) {
6212 if (!((fan_control_commands & TPACPI_FAN_CMD_LEVEL) && 6221 if (!((fan_control_commands & TPACPI_FAN_CMD_LEVEL) &&
6213 fan_write_cmd_level(cmd, &rc)) && 6222 fan_write_cmd_level(cmd, &rc)) &&
6214 !((fan_control_commands & TPACPI_FAN_CMD_ENABLE) && 6223 !((fan_control_commands & TPACPI_FAN_CMD_ENABLE) &&
6215 (fan_write_cmd_enable(cmd, &rc) || 6224 (fan_write_cmd_enable(cmd, &rc) ||
6216 fan_write_cmd_disable(cmd, &rc) || 6225 fan_write_cmd_disable(cmd, &rc) ||
6217 fan_write_cmd_watchdog(cmd, &rc))) && 6226 fan_write_cmd_watchdog(cmd, &rc))) &&
6218 !((fan_control_commands & TPACPI_FAN_CMD_SPEED) && 6227 !((fan_control_commands & TPACPI_FAN_CMD_SPEED) &&
6219 fan_write_cmd_speed(cmd, &rc)) 6228 fan_write_cmd_speed(cmd, &rc))
6220 ) 6229 )
6221 rc = -EINVAL; 6230 rc = -EINVAL;
6222 else if (!rc) 6231 else if (!rc)
6223 fan_watchdog_reset(); 6232 fan_watchdog_reset();
6224 } 6233 }
6225 6234
6226 return rc; 6235 return rc;
6227 } 6236 }
6228 6237
6229 static struct ibm_struct fan_driver_data = { 6238 static struct ibm_struct fan_driver_data = {
6230 .name = "fan", 6239 .name = "fan",
6231 .read = fan_read, 6240 .read = fan_read,
6232 .write = fan_write, 6241 .write = fan_write,
6233 .exit = fan_exit, 6242 .exit = fan_exit,
6234 .suspend = fan_suspend, 6243 .suspend = fan_suspend,
6235 .resume = fan_resume, 6244 .resume = fan_resume,
6236 }; 6245 };
6237 6246
6238 /**************************************************************************** 6247 /****************************************************************************
6239 **************************************************************************** 6248 ****************************************************************************
6240 * 6249 *
6241 * Infrastructure 6250 * Infrastructure
6242 * 6251 *
6243 **************************************************************************** 6252 ****************************************************************************
6244 ****************************************************************************/ 6253 ****************************************************************************/
6245 6254
6246 /* sysfs name ---------------------------------------------------------- */ 6255 /* sysfs name ---------------------------------------------------------- */
6247 static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, 6256 static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
6248 struct device_attribute *attr, 6257 struct device_attribute *attr,
6249 char *buf) 6258 char *buf)
6250 { 6259 {
6251 return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME); 6260 return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME);
6252 } 6261 }
6253 6262
6254 static struct device_attribute dev_attr_thinkpad_acpi_pdev_name = 6263 static struct device_attribute dev_attr_thinkpad_acpi_pdev_name =
6255 __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL); 6264 __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
6256 6265
6257 /* --------------------------------------------------------------------- */ 6266 /* --------------------------------------------------------------------- */
6258 6267
6259 /* /proc support */ 6268 /* /proc support */
6260 static struct proc_dir_entry *proc_dir; 6269 static struct proc_dir_entry *proc_dir;
6261 6270
6262 /* 6271 /*
6263 * Module and infrastructure proble, init and exit handling 6272 * Module and infrastructure proble, init and exit handling
6264 */ 6273 */
6265 6274
6266 static int force_load; 6275 static int force_load;
6267 6276
6268 #ifdef CONFIG_THINKPAD_ACPI_DEBUG 6277 #ifdef CONFIG_THINKPAD_ACPI_DEBUG
6269 static const char * __init str_supported(int is_supported) 6278 static const char * __init str_supported(int is_supported)
6270 { 6279 {
6271 static char text_unsupported[] __initdata = "not supported"; 6280 static char text_unsupported[] __initdata = "not supported";
6272 6281
6273 return (is_supported)? &text_unsupported[4] : &text_unsupported[0]; 6282 return (is_supported)? &text_unsupported[4] : &text_unsupported[0];
6274 } 6283 }
6275 #endif /* CONFIG_THINKPAD_ACPI_DEBUG */ 6284 #endif /* CONFIG_THINKPAD_ACPI_DEBUG */
6276 6285
6277 static void ibm_exit(struct ibm_struct *ibm) 6286 static void ibm_exit(struct ibm_struct *ibm)
6278 { 6287 {
6279 dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name); 6288 dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);
6280 6289
6281 list_del_init(&ibm->all_drivers); 6290 list_del_init(&ibm->all_drivers);
6282 6291
6283 if (ibm->flags.acpi_notify_installed) { 6292 if (ibm->flags.acpi_notify_installed) {
6284 dbg_printk(TPACPI_DBG_EXIT, 6293 dbg_printk(TPACPI_DBG_EXIT,
6285 "%s: acpi_remove_notify_handler\n", ibm->name); 6294 "%s: acpi_remove_notify_handler\n", ibm->name);
6286 BUG_ON(!ibm->acpi); 6295 BUG_ON(!ibm->acpi);
6287 acpi_remove_notify_handler(*ibm->acpi->handle, 6296 acpi_remove_notify_handler(*ibm->acpi->handle,
6288 ibm->acpi->type, 6297 ibm->acpi->type,
6289 dispatch_acpi_notify); 6298 dispatch_acpi_notify);
6290 ibm->flags.acpi_notify_installed = 0; 6299 ibm->flags.acpi_notify_installed = 0;
6291 ibm->flags.acpi_notify_installed = 0; 6300 ibm->flags.acpi_notify_installed = 0;
6292 } 6301 }
6293 6302
6294 if (ibm->flags.proc_created) { 6303 if (ibm->flags.proc_created) {
6295 dbg_printk(TPACPI_DBG_EXIT, 6304 dbg_printk(TPACPI_DBG_EXIT,
6296 "%s: remove_proc_entry\n", ibm->name); 6305 "%s: remove_proc_entry\n", ibm->name);
6297 remove_proc_entry(ibm->name, proc_dir); 6306 remove_proc_entry(ibm->name, proc_dir);
6298 ibm->flags.proc_created = 0; 6307 ibm->flags.proc_created = 0;
6299 } 6308 }
6300 6309
6301 if (ibm->flags.acpi_driver_registered) { 6310 if (ibm->flags.acpi_driver_registered) {
6302 dbg_printk(TPACPI_DBG_EXIT, 6311 dbg_printk(TPACPI_DBG_EXIT,
6303 "%s: acpi_bus_unregister_driver\n", ibm->name); 6312 "%s: acpi_bus_unregister_driver\n", ibm->name);
6304 BUG_ON(!ibm->acpi); 6313 BUG_ON(!ibm->acpi);
6305 acpi_bus_unregister_driver(ibm->acpi->driver); 6314 acpi_bus_unregister_driver(ibm->acpi->driver);
6306 kfree(ibm->acpi->driver); 6315 kfree(ibm->acpi->driver);
6307 ibm->acpi->driver = NULL; 6316 ibm->acpi->driver = NULL;
6308 ibm->flags.acpi_driver_registered = 0; 6317 ibm->flags.acpi_driver_registered = 0;
6309 } 6318 }
6310 6319
6311 if (ibm->flags.init_called && ibm->exit) { 6320 if (ibm->flags.init_called && ibm->exit) {
6312 ibm->exit(); 6321 ibm->exit();
6313 ibm->flags.init_called = 0; 6322 ibm->flags.init_called = 0;
6314 } 6323 }
6315 6324
6316 dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name); 6325 dbg_printk(TPACPI_DBG_INIT, "finished removing %s\n", ibm->name);
6317 } 6326 }
6318 6327
6319 static int __init ibm_init(struct ibm_init_struct *iibm) 6328 static int __init ibm_init(struct ibm_init_struct *iibm)
6320 { 6329 {
6321 int ret; 6330 int ret;
6322 struct ibm_struct *ibm = iibm->data; 6331 struct ibm_struct *ibm = iibm->data;
6323 struct proc_dir_entry *entry; 6332 struct proc_dir_entry *entry;
6324 6333
6325 BUG_ON(ibm == NULL); 6334 BUG_ON(ibm == NULL);
6326 6335
6327 INIT_LIST_HEAD(&ibm->all_drivers); 6336 INIT_LIST_HEAD(&ibm->all_drivers);
6328 6337
6329 if (ibm->flags.experimental && !experimental) 6338 if (ibm->flags.experimental && !experimental)
6330 return 0; 6339 return 0;
6331 6340
6332 dbg_printk(TPACPI_DBG_INIT, 6341 dbg_printk(TPACPI_DBG_INIT,
6333 "probing for %s\n", ibm->name); 6342 "probing for %s\n", ibm->name);
6334 6343
6335 if (iibm->init) { 6344 if (iibm->init) {
6336 ret = iibm->init(iibm); 6345 ret = iibm->init(iibm);
6337 if (ret > 0) 6346 if (ret > 0)
6338 return 0; /* probe failed */ 6347 return 0; /* probe failed */
6339 if (ret) 6348 if (ret)
6340 return ret; 6349 return ret;
6341 6350
6342 ibm->flags.init_called = 1; 6351 ibm->flags.init_called = 1;
6343 } 6352 }
6344 6353
6345 if (ibm->acpi) { 6354 if (ibm->acpi) {
6346 if (ibm->acpi->hid) { 6355 if (ibm->acpi->hid) {
6347 ret = register_tpacpi_subdriver(ibm); 6356 ret = register_tpacpi_subdriver(ibm);
6348 if (ret) 6357 if (ret)
6349 goto err_out; 6358 goto err_out;
6350 } 6359 }
6351 6360
6352 if (ibm->acpi->notify) { 6361 if (ibm->acpi->notify) {
6353 ret = setup_acpi_notify(ibm); 6362 ret = setup_acpi_notify(ibm);
6354 if (ret == -ENODEV) { 6363 if (ret == -ENODEV) {
6355 printk(TPACPI_NOTICE "disabling subdriver %s\n", 6364 printk(TPACPI_NOTICE "disabling subdriver %s\n",
6356 ibm->name); 6365 ibm->name);
6357 ret = 0; 6366 ret = 0;
6358 goto err_out; 6367 goto err_out;
6359 } 6368 }
6360 if (ret < 0) 6369 if (ret < 0)
6361 goto err_out; 6370 goto err_out;
6362 } 6371 }
6363 } 6372 }
6364 6373
6365 dbg_printk(TPACPI_DBG_INIT, 6374 dbg_printk(TPACPI_DBG_INIT,
6366 "%s installed\n", ibm->name); 6375 "%s installed\n", ibm->name);
6367 6376
6368 if (ibm->read) { 6377 if (ibm->read) {
6369 entry = create_proc_entry(ibm->name, 6378 entry = create_proc_entry(ibm->name,
6370 S_IFREG | S_IRUGO | S_IWUSR, 6379 S_IFREG | S_IRUGO | S_IWUSR,
6371 proc_dir); 6380 proc_dir);
6372 if (!entry) { 6381 if (!entry) {
6373 printk(TPACPI_ERR "unable to create proc entry %s\n", 6382 printk(TPACPI_ERR "unable to create proc entry %s\n",
6374 ibm->name); 6383 ibm->name);
6375 ret = -ENODEV; 6384 ret = -ENODEV;
6376 goto err_out; 6385 goto err_out;
6377 } 6386 }
6378 entry->owner = THIS_MODULE; 6387 entry->owner = THIS_MODULE;
6379 entry->data = ibm; 6388 entry->data = ibm;
6380 entry->read_proc = &dispatch_procfs_read; 6389 entry->read_proc = &dispatch_procfs_read;
6381 if (ibm->write) 6390 if (ibm->write)
6382 entry->write_proc = &dispatch_procfs_write; 6391 entry->write_proc = &dispatch_procfs_write;
6383 ibm->flags.proc_created = 1; 6392 ibm->flags.proc_created = 1;
6384 } 6393 }
6385 6394
6386 list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers); 6395 list_add_tail(&ibm->all_drivers, &tpacpi_all_drivers);
6387 6396
6388 return 0; 6397 return 0;
6389 6398
6390 err_out: 6399 err_out:
6391 dbg_printk(TPACPI_DBG_INIT, 6400 dbg_printk(TPACPI_DBG_INIT,
6392 "%s: at error exit path with result %d\n", 6401 "%s: at error exit path with result %d\n",
6393 ibm->name, ret); 6402 ibm->name, ret);
6394 6403
6395 ibm_exit(ibm); 6404 ibm_exit(ibm);
6396 return (ret < 0)? ret : 0; 6405 return (ret < 0)? ret : 0;
6397 } 6406 }
6398 6407
6399 /* Probing */ 6408 /* Probing */
6400 6409
6401 /* returns 0 - probe ok, or < 0 - probe error. 6410 /* returns 0 - probe ok, or < 0 - probe error.
6402 * Probe ok doesn't mean thinkpad found. 6411 * Probe ok doesn't mean thinkpad found.
6403 * On error, kfree() cleanup on tp->* is not performed, caller must do it */ 6412 * On error, kfree() cleanup on tp->* is not performed, caller must do it */
6404 static int __must_check __init get_thinkpad_model_data( 6413 static int __must_check __init get_thinkpad_model_data(
6405 struct thinkpad_id_data *tp) 6414 struct thinkpad_id_data *tp)
6406 { 6415 {
6407 const struct dmi_device *dev = NULL; 6416 const struct dmi_device *dev = NULL;
6408 char ec_fw_string[18]; 6417 char ec_fw_string[18];
6409 char const *s; 6418 char const *s;
6410 6419
6411 if (!tp) 6420 if (!tp)
6412 return -EINVAL; 6421 return -EINVAL;
6413 6422
6414 memset(tp, 0, sizeof(*tp)); 6423 memset(tp, 0, sizeof(*tp));
6415 6424
6416 if (dmi_name_in_vendors("IBM")) 6425 if (dmi_name_in_vendors("IBM"))
6417 tp->vendor = PCI_VENDOR_ID_IBM; 6426 tp->vendor = PCI_VENDOR_ID_IBM;
6418 else if (dmi_name_in_vendors("LENOVO")) 6427 else if (dmi_name_in_vendors("LENOVO"))
6419 tp->vendor = PCI_VENDOR_ID_LENOVO; 6428 tp->vendor = PCI_VENDOR_ID_LENOVO;
6420 else 6429 else
6421 return 0; 6430 return 0;
6422 6431
6423 s = dmi_get_system_info(DMI_BIOS_VERSION); 6432 s = dmi_get_system_info(DMI_BIOS_VERSION);
6424 tp->bios_version_str = kstrdup(s, GFP_KERNEL); 6433 tp->bios_version_str = kstrdup(s, GFP_KERNEL);
6425 if (s && !tp->bios_version_str) 6434 if (s && !tp->bios_version_str)
6426 return -ENOMEM; 6435 return -ENOMEM;
6427 if (!tp->bios_version_str) 6436 if (!tp->bios_version_str)
6428 return 0; 6437 return 0;
6429 tp->bios_model = tp->bios_version_str[0] 6438 tp->bios_model = tp->bios_version_str[0]
6430 | (tp->bios_version_str[1] << 8); 6439 | (tp->bios_version_str[1] << 8);
6431 6440
6432 /* 6441 /*
6433 * ThinkPad T23 or newer, A31 or newer, R50e or newer, 6442 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
6434 * X32 or newer, all Z series; Some models must have an 6443 * X32 or newer, all Z series; Some models must have an
6435 * up-to-date BIOS or they will not be detected. 6444 * up-to-date BIOS or they will not be detected.
6436 * 6445 *
6437 * See http://thinkwiki.org/wiki/List_of_DMI_IDs 6446 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
6438 */ 6447 */
6439 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { 6448 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
6440 if (sscanf(dev->name, 6449 if (sscanf(dev->name,
6441 "IBM ThinkPad Embedded Controller -[%17c", 6450 "IBM ThinkPad Embedded Controller -[%17c",
6442 ec_fw_string) == 1) { 6451 ec_fw_string) == 1) {
6443 ec_fw_string[sizeof(ec_fw_string) - 1] = 0; 6452 ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
6444 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; 6453 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
6445 6454
6446 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); 6455 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
6447 if (!tp->ec_version_str) 6456 if (!tp->ec_version_str)
6448 return -ENOMEM; 6457 return -ENOMEM;
6449 tp->ec_model = ec_fw_string[0] 6458 tp->ec_model = ec_fw_string[0]
6450 | (ec_fw_string[1] << 8); 6459 | (ec_fw_string[1] << 8);
6451 break; 6460 break;
6452 } 6461 }
6453 } 6462 }
6454 6463
6455 s = dmi_get_system_info(DMI_PRODUCT_VERSION); 6464 s = dmi_get_system_info(DMI_PRODUCT_VERSION);
6456 if (s && !strnicmp(s, "ThinkPad", 8)) { 6465 if (s && !strnicmp(s, "ThinkPad", 8)) {
6457 tp->model_str = kstrdup(s, GFP_KERNEL); 6466 tp->model_str = kstrdup(s, GFP_KERNEL);
6458 if (!tp->model_str) 6467 if (!tp->model_str)
6459 return -ENOMEM; 6468 return -ENOMEM;
6460 } 6469 }
6461 6470
6462 s = dmi_get_system_info(DMI_PRODUCT_NAME); 6471 s = dmi_get_system_info(DMI_PRODUCT_NAME);
6463 tp->nummodel_str = kstrdup(s, GFP_KERNEL); 6472 tp->nummodel_str = kstrdup(s, GFP_KERNEL);
6464 if (s && !tp->nummodel_str) 6473 if (s && !tp->nummodel_str)
6465 return -ENOMEM; 6474 return -ENOMEM;
6466 6475
6467 return 0; 6476 return 0;
6468 } 6477 }
6469 6478
6470 static int __init probe_for_thinkpad(void) 6479 static int __init probe_for_thinkpad(void)
6471 { 6480 {
6472 int is_thinkpad; 6481 int is_thinkpad;
6473 6482
6474 if (acpi_disabled) 6483 if (acpi_disabled)
6475 return -ENODEV; 6484 return -ENODEV;
6476 6485
6477 /* 6486 /*
6478 * Non-ancient models have better DMI tagging, but very old models 6487 * Non-ancient models have better DMI tagging, but very old models
6479 * don't. 6488 * don't.
6480 */ 6489 */
6481 is_thinkpad = (thinkpad_id.model_str != NULL); 6490 is_thinkpad = (thinkpad_id.model_str != NULL);
6482 6491
6483 /* ec is required because many other handles are relative to it */ 6492 /* ec is required because many other handles are relative to it */
6484 TPACPI_ACPIHANDLE_INIT(ec); 6493 TPACPI_ACPIHANDLE_INIT(ec);
6485 if (!ec_handle) { 6494 if (!ec_handle) {
6486 if (is_thinkpad) 6495 if (is_thinkpad)
6487 printk(TPACPI_ERR 6496 printk(TPACPI_ERR
6488 "Not yet supported ThinkPad detected!\n"); 6497 "Not yet supported ThinkPad detected!\n");
6489 return -ENODEV; 6498 return -ENODEV;
6490 } 6499 }
6491 6500
6492 /* 6501 /*
6493 * Risks a regression on very old machines, but reduces potential 6502 * Risks a regression on very old machines, but reduces potential
6494 * false positives a damn great deal 6503 * false positives a damn great deal
6495 */ 6504 */
6496 if (!is_thinkpad) 6505 if (!is_thinkpad)
6497 is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM); 6506 is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
6498 6507
6499 if (!is_thinkpad && !force_load) 6508 if (!is_thinkpad && !force_load)
6500 return -ENODEV; 6509 return -ENODEV;
6501 6510
6502 return 0; 6511 return 0;
6503 } 6512 }
6504 6513
6505 6514
6506 /* Module init, exit, parameters */ 6515 /* Module init, exit, parameters */
6507 6516
6508 static struct ibm_init_struct ibms_init[] __initdata = { 6517 static struct ibm_init_struct ibms_init[] __initdata = {
6509 { 6518 {
6510 .init = thinkpad_acpi_driver_init, 6519 .init = thinkpad_acpi_driver_init,
6511 .data = &thinkpad_acpi_driver_data, 6520 .data = &thinkpad_acpi_driver_data,
6512 }, 6521 },
6513 { 6522 {
6514 .init = hotkey_init, 6523 .init = hotkey_init,
6515 .data = &hotkey_driver_data, 6524 .data = &hotkey_driver_data,
6516 }, 6525 },
6517 { 6526 {
6518 .init = bluetooth_init, 6527 .init = bluetooth_init,
6519 .data = &bluetooth_driver_data, 6528 .data = &bluetooth_driver_data,
6520 }, 6529 },
6521 { 6530 {
6522 .init = wan_init, 6531 .init = wan_init,
6523 .data = &wan_driver_data, 6532 .data = &wan_driver_data,
6524 }, 6533 },
6525 #ifdef CONFIG_THINKPAD_ACPI_VIDEO 6534 #ifdef CONFIG_THINKPAD_ACPI_VIDEO
6526 { 6535 {
6527 .init = video_init, 6536 .init = video_init,
6528 .data = &video_driver_data, 6537 .data = &video_driver_data,
6529 }, 6538 },
6530 #endif 6539 #endif
6531 { 6540 {
6532 .init = light_init, 6541 .init = light_init,
6533 .data = &light_driver_data, 6542 .data = &light_driver_data,
6534 }, 6543 },
6535 #ifdef CONFIG_THINKPAD_ACPI_DOCK 6544 #ifdef CONFIG_THINKPAD_ACPI_DOCK
6536 { 6545 {
6537 .init = dock_init, 6546 .init = dock_init,
6538 .data = &dock_driver_data[0], 6547 .data = &dock_driver_data[0],
6539 }, 6548 },
6540 { 6549 {
6541 .init = dock_init2, 6550 .init = dock_init2,
6542 .data = &dock_driver_data[1], 6551 .data = &dock_driver_data[1],
6543 }, 6552 },
6544 #endif 6553 #endif
6545 #ifdef CONFIG_THINKPAD_ACPI_BAY 6554 #ifdef CONFIG_THINKPAD_ACPI_BAY
6546 { 6555 {
6547 .init = bay_init, 6556 .init = bay_init,
6548 .data = &bay_driver_data, 6557 .data = &bay_driver_data,
6549 }, 6558 },
6550 #endif 6559 #endif
6551 { 6560 {
6552 .init = cmos_init, 6561 .init = cmos_init,
6553 .data = &cmos_driver_data, 6562 .data = &cmos_driver_data,
6554 }, 6563 },
6555 { 6564 {
6556 .init = led_init, 6565 .init = led_init,
6557 .data = &led_driver_data, 6566 .data = &led_driver_data,
6558 }, 6567 },
6559 { 6568 {
6560 .init = beep_init, 6569 .init = beep_init,
6561 .data = &beep_driver_data, 6570 .data = &beep_driver_data,
6562 }, 6571 },
6563 { 6572 {
6564 .init = thermal_init, 6573 .init = thermal_init,
6565 .data = &thermal_driver_data, 6574 .data = &thermal_driver_data,
6566 }, 6575 },
6567 { 6576 {
6568 .data = &ecdump_driver_data, 6577 .data = &ecdump_driver_data,
6569 }, 6578 },
6570 { 6579 {
6571 .init = brightness_init, 6580 .init = brightness_init,
6572 .data = &brightness_driver_data, 6581 .data = &brightness_driver_data,
6573 }, 6582 },
6574 { 6583 {
6575 .data = &volume_driver_data, 6584 .data = &volume_driver_data,
6576 }, 6585 },
6577 { 6586 {
6578 .init = fan_init, 6587 .init = fan_init,
6579 .data = &fan_driver_data, 6588 .data = &fan_driver_data,
6580 }, 6589 },
6581 }; 6590 };
6582 6591
6583 static int __init set_ibm_param(const char *val, struct kernel_param *kp) 6592 static int __init set_ibm_param(const char *val, struct kernel_param *kp)
6584 { 6593 {
6585 unsigned int i; 6594 unsigned int i;
6586 struct ibm_struct *ibm; 6595 struct ibm_struct *ibm;
6587 6596
6588 if (!kp || !kp->name || !val) 6597 if (!kp || !kp->name || !val)
6589 return -EINVAL; 6598 return -EINVAL;
6590 6599
6591 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 6600 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
6592 ibm = ibms_init[i].data; 6601 ibm = ibms_init[i].data;
6593 WARN_ON(ibm == NULL); 6602 WARN_ON(ibm == NULL);
6594 6603
6595 if (!ibm || !ibm->name) 6604 if (!ibm || !ibm->name)
6596 continue; 6605 continue;
6597 6606
6598 if (strcmp(ibm->name, kp->name) == 0 && ibm->write) { 6607 if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
6599 if (strlen(val) > sizeof(ibms_init[i].param) - 2) 6608 if (strlen(val) > sizeof(ibms_init[i].param) - 2)
6600 return -ENOSPC; 6609 return -ENOSPC;
6601 strcpy(ibms_init[i].param, val); 6610 strcpy(ibms_init[i].param, val);
6602 strcat(ibms_init[i].param, ","); 6611 strcat(ibms_init[i].param, ",");
6603 return 0; 6612 return 0;
6604 } 6613 }
6605 } 6614 }
6606 6615
6607 return -EINVAL; 6616 return -EINVAL;
6608 } 6617 }
6609 6618
6610 module_param(experimental, int, 0); 6619 module_param(experimental, int, 0);
6611 MODULE_PARM_DESC(experimental, 6620 MODULE_PARM_DESC(experimental,
6612 "Enables experimental features when non-zero"); 6621 "Enables experimental features when non-zero");
6613 6622
6614 module_param_named(debug, dbg_level, uint, 0); 6623 module_param_named(debug, dbg_level, uint, 0);
6615 MODULE_PARM_DESC(debug, "Sets debug level bit-mask"); 6624 MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
6616 6625
6617 module_param(force_load, bool, 0); 6626 module_param(force_load, bool, 0);
6618 MODULE_PARM_DESC(force_load, 6627 MODULE_PARM_DESC(force_load,
6619 "Attempts to load the driver even on a " 6628 "Attempts to load the driver even on a "
6620 "mis-identified ThinkPad when true"); 6629 "mis-identified ThinkPad when true");
6621 6630
6622 module_param_named(fan_control, fan_control_allowed, bool, 0); 6631 module_param_named(fan_control, fan_control_allowed, bool, 0);
6623 MODULE_PARM_DESC(fan_control, 6632 MODULE_PARM_DESC(fan_control,
6624 "Enables setting fan parameters features when true"); 6633 "Enables setting fan parameters features when true");
6625 6634
6626 module_param_named(brightness_mode, brightness_mode, int, 0); 6635 module_param_named(brightness_mode, brightness_mode, int, 0);
6627 MODULE_PARM_DESC(brightness_mode, 6636 MODULE_PARM_DESC(brightness_mode,
6628 "Selects brightness control strategy: " 6637 "Selects brightness control strategy: "
6629 "0=auto, 1=EC, 2=CMOS, 3=both"); 6638 "0=auto, 1=EC, 2=CMOS, 3=both");
6630 6639
6631 module_param(brightness_enable, uint, 0); 6640 module_param(brightness_enable, uint, 0);
6632 MODULE_PARM_DESC(brightness_enable, 6641 MODULE_PARM_DESC(brightness_enable,
6633 "Enables backlight control when 1, disables when 0"); 6642 "Enables backlight control when 1, disables when 0");
6634 6643
6635 module_param(hotkey_report_mode, uint, 0); 6644 module_param(hotkey_report_mode, uint, 0);
6636 MODULE_PARM_DESC(hotkey_report_mode, 6645 MODULE_PARM_DESC(hotkey_report_mode,
6637 "used for backwards compatibility with userspace, " 6646 "used for backwards compatibility with userspace, "
6638 "see documentation"); 6647 "see documentation");
6639 6648
6640 #define TPACPI_PARAM(feature) \ 6649 #define TPACPI_PARAM(feature) \
6641 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \ 6650 module_param_call(feature, set_ibm_param, NULL, NULL, 0); \
6642 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \ 6651 MODULE_PARM_DESC(feature, "Simulates thinkpad-acpi procfs command " \
6643 "at module load, see documentation") 6652 "at module load, see documentation")
6644 6653
6645 TPACPI_PARAM(hotkey); 6654 TPACPI_PARAM(hotkey);
6646 TPACPI_PARAM(bluetooth); 6655 TPACPI_PARAM(bluetooth);
6647 TPACPI_PARAM(video); 6656 TPACPI_PARAM(video);
6648 TPACPI_PARAM(light); 6657 TPACPI_PARAM(light);
6649 #ifdef CONFIG_THINKPAD_ACPI_DOCK 6658 #ifdef CONFIG_THINKPAD_ACPI_DOCK
6650 TPACPI_PARAM(dock); 6659 TPACPI_PARAM(dock);
6651 #endif 6660 #endif
6652 #ifdef CONFIG_THINKPAD_ACPI_BAY 6661 #ifdef CONFIG_THINKPAD_ACPI_BAY
6653 TPACPI_PARAM(bay); 6662 TPACPI_PARAM(bay);
6654 #endif /* CONFIG_THINKPAD_ACPI_BAY */ 6663 #endif /* CONFIG_THINKPAD_ACPI_BAY */
6655 TPACPI_PARAM(cmos); 6664 TPACPI_PARAM(cmos);
6656 TPACPI_PARAM(led); 6665 TPACPI_PARAM(led);
6657 TPACPI_PARAM(beep); 6666 TPACPI_PARAM(beep);
6658 TPACPI_PARAM(ecdump); 6667 TPACPI_PARAM(ecdump);
6659 TPACPI_PARAM(brightness); 6668 TPACPI_PARAM(brightness);
6660 TPACPI_PARAM(volume); 6669 TPACPI_PARAM(volume);
6661 TPACPI_PARAM(fan); 6670 TPACPI_PARAM(fan);
6662 6671
6663 static void thinkpad_acpi_module_exit(void) 6672 static void thinkpad_acpi_module_exit(void)
6664 { 6673 {
6665 struct ibm_struct *ibm, *itmp; 6674 struct ibm_struct *ibm, *itmp;
6666 6675
6667 tpacpi_lifecycle = TPACPI_LIFE_EXITING; 6676 tpacpi_lifecycle = TPACPI_LIFE_EXITING;
6668 6677
6669 list_for_each_entry_safe_reverse(ibm, itmp, 6678 list_for_each_entry_safe_reverse(ibm, itmp,
6670 &tpacpi_all_drivers, 6679 &tpacpi_all_drivers,
6671 all_drivers) { 6680 all_drivers) {
6672 ibm_exit(ibm); 6681 ibm_exit(ibm);
6673 } 6682 }
6674 6683
6675 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n"); 6684 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
6676 6685
6677 if (tpacpi_inputdev) { 6686 if (tpacpi_inputdev) {
6678 if (tp_features.input_device_registered) 6687 if (tp_features.input_device_registered)
6679 input_unregister_device(tpacpi_inputdev); 6688 input_unregister_device(tpacpi_inputdev);
6680 else 6689 else
6681 input_free_device(tpacpi_inputdev); 6690 input_free_device(tpacpi_inputdev);
6682 } 6691 }
6683 6692
6684 if (tpacpi_hwmon) 6693 if (tpacpi_hwmon)
6685 hwmon_device_unregister(tpacpi_hwmon); 6694 hwmon_device_unregister(tpacpi_hwmon);
6686 6695
6687 if (tp_features.sensors_pdev_attrs_registered) 6696 if (tp_features.sensors_pdev_attrs_registered)
6688 device_remove_file(&tpacpi_sensors_pdev->dev, 6697 device_remove_file(&tpacpi_sensors_pdev->dev,
6689 &dev_attr_thinkpad_acpi_pdev_name); 6698 &dev_attr_thinkpad_acpi_pdev_name);
6690 if (tpacpi_sensors_pdev) 6699 if (tpacpi_sensors_pdev)
6691 platform_device_unregister(tpacpi_sensors_pdev); 6700 platform_device_unregister(tpacpi_sensors_pdev);
6692 if (tpacpi_pdev) 6701 if (tpacpi_pdev)
6693 platform_device_unregister(tpacpi_pdev); 6702 platform_device_unregister(tpacpi_pdev);
6694 6703
6695 if (tp_features.sensors_pdrv_attrs_registered) 6704 if (tp_features.sensors_pdrv_attrs_registered)
6696 tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver); 6705 tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver);
6697 if (tp_features.platform_drv_attrs_registered) 6706 if (tp_features.platform_drv_attrs_registered)
6698 tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); 6707 tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
6699 6708
6700 if (tp_features.sensors_pdrv_registered) 6709 if (tp_features.sensors_pdrv_registered)
6701 platform_driver_unregister(&tpacpi_hwmon_pdriver); 6710 platform_driver_unregister(&tpacpi_hwmon_pdriver);
6702 6711
6703 if (tp_features.platform_drv_registered) 6712 if (tp_features.platform_drv_registered)
6704 platform_driver_unregister(&tpacpi_pdriver); 6713 platform_driver_unregister(&tpacpi_pdriver);
6705 6714
6706 if (proc_dir) 6715 if (proc_dir)
6707 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir); 6716 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
6708 6717
6709 if (tpacpi_wq) 6718 if (tpacpi_wq)
6710 destroy_workqueue(tpacpi_wq); 6719 destroy_workqueue(tpacpi_wq);
6711 6720
6712 kfree(thinkpad_id.bios_version_str); 6721 kfree(thinkpad_id.bios_version_str);
6713 kfree(thinkpad_id.ec_version_str); 6722 kfree(thinkpad_id.ec_version_str);
6714 kfree(thinkpad_id.model_str); 6723 kfree(thinkpad_id.model_str);
6715 } 6724 }
6716 6725
6717 6726
6718 static int __init thinkpad_acpi_module_init(void) 6727 static int __init thinkpad_acpi_module_init(void)
6719 { 6728 {
6720 int ret, i; 6729 int ret, i;
6721 6730
6722 tpacpi_lifecycle = TPACPI_LIFE_INIT; 6731 tpacpi_lifecycle = TPACPI_LIFE_INIT;
6723 6732
6724 /* Parameter checking */ 6733 /* Parameter checking */
6725 if (hotkey_report_mode > 2) 6734 if (hotkey_report_mode > 2)
6726 return -EINVAL; 6735 return -EINVAL;
6727 6736
6728 /* Driver-level probe */ 6737 /* Driver-level probe */
6729 6738
6730 ret = get_thinkpad_model_data(&thinkpad_id); 6739 ret = get_thinkpad_model_data(&thinkpad_id);
6731 if (ret) { 6740 if (ret) {
6732 printk(TPACPI_ERR 6741 printk(TPACPI_ERR
6733 "unable to get DMI data: %d\n", ret); 6742 "unable to get DMI data: %d\n", ret);
6734 thinkpad_acpi_module_exit(); 6743 thinkpad_acpi_module_exit();
6735 return ret; 6744 return ret;
6736 } 6745 }
6737 ret = probe_for_thinkpad(); 6746 ret = probe_for_thinkpad();
6738 if (ret) { 6747 if (ret) {
6739 thinkpad_acpi_module_exit(); 6748 thinkpad_acpi_module_exit();
6740 return ret; 6749 return ret;
6741 } 6750 }
6742 6751
6743 /* Driver initialization */ 6752 /* Driver initialization */
6744 6753
6745 TPACPI_ACPIHANDLE_INIT(ecrd); 6754 TPACPI_ACPIHANDLE_INIT(ecrd);
6746 TPACPI_ACPIHANDLE_INIT(ecwr); 6755 TPACPI_ACPIHANDLE_INIT(ecwr);
6747 6756
6748 tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME); 6757 tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME);
6749 if (!tpacpi_wq) { 6758 if (!tpacpi_wq) {
6750 thinkpad_acpi_module_exit(); 6759 thinkpad_acpi_module_exit();
6751 return -ENOMEM; 6760 return -ENOMEM;
6752 } 6761 }
6753 6762
6754 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); 6763 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);
6755 if (!proc_dir) { 6764 if (!proc_dir) {
6756 printk(TPACPI_ERR 6765 printk(TPACPI_ERR
6757 "unable to create proc dir " TPACPI_PROC_DIR); 6766 "unable to create proc dir " TPACPI_PROC_DIR);
6758 thinkpad_acpi_module_exit(); 6767 thinkpad_acpi_module_exit();
6759 return -ENODEV; 6768 return -ENODEV;
6760 } 6769 }
6761 proc_dir->owner = THIS_MODULE; 6770 proc_dir->owner = THIS_MODULE;
6762 6771
6763 ret = platform_driver_register(&tpacpi_pdriver); 6772 ret = platform_driver_register(&tpacpi_pdriver);
6764 if (ret) { 6773 if (ret) {
6765 printk(TPACPI_ERR 6774 printk(TPACPI_ERR
6766 "unable to register main platform driver\n"); 6775 "unable to register main platform driver\n");
6767 thinkpad_acpi_module_exit(); 6776 thinkpad_acpi_module_exit();
6768 return ret; 6777 return ret;
6769 } 6778 }
6770 tp_features.platform_drv_registered = 1; 6779 tp_features.platform_drv_registered = 1;
6771 6780
6772 ret = platform_driver_register(&tpacpi_hwmon_pdriver); 6781 ret = platform_driver_register(&tpacpi_hwmon_pdriver);
6773 if (ret) { 6782 if (ret) {
6774 printk(TPACPI_ERR 6783 printk(TPACPI_ERR
6775 "unable to register hwmon platform driver\n"); 6784 "unable to register hwmon platform driver\n");
6776 thinkpad_acpi_module_exit(); 6785 thinkpad_acpi_module_exit();
6777 return ret; 6786 return ret;
6778 } 6787 }
6779 tp_features.sensors_pdrv_registered = 1; 6788 tp_features.sensors_pdrv_registered = 1;
6780 6789
6781 ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); 6790 ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
6782 if (!ret) { 6791 if (!ret) {
6783 tp_features.platform_drv_attrs_registered = 1; 6792 tp_features.platform_drv_attrs_registered = 1;
6784 ret = tpacpi_create_driver_attributes( 6793 ret = tpacpi_create_driver_attributes(
6785 &tpacpi_hwmon_pdriver.driver); 6794 &tpacpi_hwmon_pdriver.driver);
6786 } 6795 }
6787 if (ret) { 6796 if (ret) {
6788 printk(TPACPI_ERR 6797 printk(TPACPI_ERR
6789 "unable to create sysfs driver attributes\n"); 6798 "unable to create sysfs driver attributes\n");
6790 thinkpad_acpi_module_exit(); 6799 thinkpad_acpi_module_exit();
6791 return ret; 6800 return ret;
6792 } 6801 }
6793 tp_features.sensors_pdrv_attrs_registered = 1; 6802 tp_features.sensors_pdrv_attrs_registered = 1;
6794 6803
6795 6804
6796 /* Device initialization */ 6805 /* Device initialization */
6797 tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, -1, 6806 tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, -1,
6798 NULL, 0); 6807 NULL, 0);
6799 if (IS_ERR(tpacpi_pdev)) { 6808 if (IS_ERR(tpacpi_pdev)) {
6800 ret = PTR_ERR(tpacpi_pdev); 6809 ret = PTR_ERR(tpacpi_pdev);
6801 tpacpi_pdev = NULL; 6810 tpacpi_pdev = NULL;
6802 printk(TPACPI_ERR "unable to register platform device\n"); 6811 printk(TPACPI_ERR "unable to register platform device\n");
6803 thinkpad_acpi_module_exit(); 6812 thinkpad_acpi_module_exit();
6804 return ret; 6813 return ret;
6805 } 6814 }
6806 tpacpi_sensors_pdev = platform_device_register_simple( 6815 tpacpi_sensors_pdev = platform_device_register_simple(
6807 TPACPI_HWMON_DRVR_NAME, 6816 TPACPI_HWMON_DRVR_NAME,
6808 -1, NULL, 0); 6817 -1, NULL, 0);
6809 if (IS_ERR(tpacpi_sensors_pdev)) { 6818 if (IS_ERR(tpacpi_sensors_pdev)) {
6810 ret = PTR_ERR(tpacpi_sensors_pdev); 6819 ret = PTR_ERR(tpacpi_sensors_pdev);
6811 tpacpi_sensors_pdev = NULL; 6820 tpacpi_sensors_pdev = NULL;
6812 printk(TPACPI_ERR 6821 printk(TPACPI_ERR
6813 "unable to register hwmon platform device\n"); 6822 "unable to register hwmon platform device\n");
6814 thinkpad_acpi_module_exit(); 6823 thinkpad_acpi_module_exit();
6815 return ret; 6824 return ret;
6816 } 6825 }
6817 ret = device_create_file(&tpacpi_sensors_pdev->dev, 6826 ret = device_create_file(&tpacpi_sensors_pdev->dev,
6818 &dev_attr_thinkpad_acpi_pdev_name); 6827 &dev_attr_thinkpad_acpi_pdev_name);
6819 if (ret) { 6828 if (ret) {
6820 printk(TPACPI_ERR 6829 printk(TPACPI_ERR
6821 "unable to create sysfs hwmon device attributes\n"); 6830 "unable to create sysfs hwmon device attributes\n");
6822 thinkpad_acpi_module_exit(); 6831 thinkpad_acpi_module_exit();
6823 return ret; 6832 return ret;
6824 } 6833 }
6825 tp_features.sensors_pdev_attrs_registered = 1; 6834 tp_features.sensors_pdev_attrs_registered = 1;
6826 tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev); 6835 tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
6827 if (IS_ERR(tpacpi_hwmon)) { 6836 if (IS_ERR(tpacpi_hwmon)) {
6828 ret = PTR_ERR(tpacpi_hwmon); 6837 ret = PTR_ERR(tpacpi_hwmon);
6829 tpacpi_hwmon = NULL; 6838 tpacpi_hwmon = NULL;
6830 printk(TPACPI_ERR "unable to register hwmon device\n"); 6839 printk(TPACPI_ERR "unable to register hwmon device\n");
6831 thinkpad_acpi_module_exit(); 6840 thinkpad_acpi_module_exit();
6832 return ret; 6841 return ret;
6833 } 6842 }
6834 mutex_init(&tpacpi_inputdev_send_mutex); 6843 mutex_init(&tpacpi_inputdev_send_mutex);
6835 tpacpi_inputdev = input_allocate_device(); 6844 tpacpi_inputdev = input_allocate_device();
6836 if (!tpacpi_inputdev) { 6845 if (!tpacpi_inputdev) {
6837 printk(TPACPI_ERR "unable to allocate input device\n"); 6846 printk(TPACPI_ERR "unable to allocate input device\n");
6838 thinkpad_acpi_module_exit(); 6847 thinkpad_acpi_module_exit();
6839 return -ENOMEM; 6848 return -ENOMEM;
6840 } else { 6849 } else {
6841 /* Prepare input device, but don't register */ 6850 /* Prepare input device, but don't register */
6842 tpacpi_inputdev->name = "ThinkPad Extra Buttons"; 6851 tpacpi_inputdev->name = "ThinkPad Extra Buttons";
6843 tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0"; 6852 tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";
6844 tpacpi_inputdev->id.bustype = BUS_HOST; 6853 tpacpi_inputdev->id.bustype = BUS_HOST;
6845 tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ? 6854 tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ?
6846 thinkpad_id.vendor : 6855 thinkpad_id.vendor :
6847 PCI_VENDOR_ID_IBM; 6856 PCI_VENDOR_ID_IBM;
6848 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; 6857 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
6849 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; 6858 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
6850 } 6859 }
6851 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 6860 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
6852 ret = ibm_init(&ibms_init[i]); 6861 ret = ibm_init(&ibms_init[i]);
6853 if (ret >= 0 && *ibms_init[i].param) 6862 if (ret >= 0 && *ibms_init[i].param)
6854 ret = ibms_init[i].data->write(ibms_init[i].param); 6863 ret = ibms_init[i].data->write(ibms_init[i].param);
6855 if (ret < 0) { 6864 if (ret < 0) {
6856 thinkpad_acpi_module_exit(); 6865 thinkpad_acpi_module_exit();
6857 return ret; 6866 return ret;
6858 } 6867 }
6859 } 6868 }
6860 ret = input_register_device(tpacpi_inputdev); 6869 ret = input_register_device(tpacpi_inputdev);
6861 if (ret < 0) { 6870 if (ret < 0) {
6862 printk(TPACPI_ERR "unable to register input device\n"); 6871 printk(TPACPI_ERR "unable to register input device\n");
6863 thinkpad_acpi_module_exit(); 6872 thinkpad_acpi_module_exit();
6864 return ret; 6873 return ret;
6865 } else { 6874 } else {
6866 tp_features.input_device_registered = 1; 6875 tp_features.input_device_registered = 1;
6867 } 6876 }
6868 6877
6869 tpacpi_lifecycle = TPACPI_LIFE_RUNNING; 6878 tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
6870 return 0; 6879 return 0;
6871 } 6880 }
6872 6881
6873 /* Please remove this in year 2009 */ 6882 /* Please remove this in year 2009 */
6874 MODULE_ALIAS("ibm_acpi"); 6883 MODULE_ALIAS("ibm_acpi");
6875 6884
6876 MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); 6885 MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
6877 6886
6878 /* 6887 /*
6879 * DMI matching for module autoloading 6888 * DMI matching for module autoloading
6880 * 6889 *
6881 * See http://thinkwiki.org/wiki/List_of_DMI_IDs 6890 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
6882 * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads 6891 * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads
6883 * 6892 *
6884 * Only models listed in thinkwiki will be supported, so add yours 6893 * Only models listed in thinkwiki will be supported, so add yours
6885 * if it is not there yet. 6894 * if it is not there yet.
6886 */ 6895 */
6887 #define IBM_BIOS_MODULE_ALIAS(__type) \ 6896 #define IBM_BIOS_MODULE_ALIAS(__type) \
6888 MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW") 6897 MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW")
6889 6898
6890 /* Non-ancient thinkpads */ 6899 /* Non-ancient thinkpads */
6891 MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); 6900 MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
6892 MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*"); 6901 MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
6893 6902
6894 /* Ancient thinkpad BIOSes have to be identified by 6903 /* Ancient thinkpad BIOSes have to be identified by
6895 * BIOS type or model number, and there are far less 6904 * BIOS type or model number, and there are far less
6896 * BIOS types than model numbers... */ 6905 * BIOS types than model numbers... */
6897 IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]"); 6906 IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]");
6898 IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]"); 6907 IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]");
6899 IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); 6908 IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
6900 6909
6901 MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); 6910 MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
6902 MODULE_DESCRIPTION(TPACPI_DESC); 6911 MODULE_DESCRIPTION(TPACPI_DESC);
6903 MODULE_VERSION(TPACPI_VERSION); 6912 MODULE_VERSION(TPACPI_VERSION);
6904 MODULE_LICENSE("GPL"); 6913 MODULE_LICENSE("GPL");
6905 6914
6906 module_init(thinkpad_acpi_module_init); 6915 module_init(thinkpad_acpi_module_init);
6907 module_exit(thinkpad_acpi_module_exit); 6916 module_exit(thinkpad_acpi_module_exit);
6908 6917
include/acpi/acpi_bus.h
1 /* 1 /*
2 * acpi_bus.h - ACPI Bus Driver ($Revision: 22 $) 2 * acpi_bus.h - ACPI Bus Driver ($Revision: 22 $)
3 * 3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * 6 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at 11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version. 12 * your option) any later version.
13 * 13 *
14 * This program is distributed in the hope that it will be useful, but 14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. 17 * General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License along 19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc., 20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 * 22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */ 24 */
25 25
26 #ifndef __ACPI_BUS_H__ 26 #ifndef __ACPI_BUS_H__
27 #define __ACPI_BUS_H__ 27 #define __ACPI_BUS_H__
28 28
29 #include <linux/device.h> 29 #include <linux/device.h>
30 30
31 #include <acpi/acpi.h> 31 #include <acpi/acpi.h>
32 32
33 #define PREFIX "ACPI: " 33 #define PREFIX "ACPI: "
34 34
35 /* TBD: Make dynamic */ 35 /* TBD: Make dynamic */
36 #define ACPI_MAX_HANDLES 10 36 #define ACPI_MAX_HANDLES 10
37 struct acpi_handle_list { 37 struct acpi_handle_list {
38 u32 count; 38 u32 count;
39 acpi_handle handles[ACPI_MAX_HANDLES]; 39 acpi_handle handles[ACPI_MAX_HANDLES];
40 }; 40 };
41 41
42 /* acpi_utils.h */ 42 /* acpi_utils.h */
43 acpi_status 43 acpi_status
44 acpi_extract_package(union acpi_object *package, 44 acpi_extract_package(union acpi_object *package,
45 struct acpi_buffer *format, struct acpi_buffer *buffer); 45 struct acpi_buffer *format, struct acpi_buffer *buffer);
46 acpi_status 46 acpi_status
47 acpi_evaluate_integer(acpi_handle handle, 47 acpi_evaluate_integer(acpi_handle handle,
48 acpi_string pathname, 48 acpi_string pathname,
49 struct acpi_object_list *arguments, unsigned long long *data); 49 struct acpi_object_list *arguments, unsigned long long *data);
50 acpi_status 50 acpi_status
51 acpi_evaluate_reference(acpi_handle handle, 51 acpi_evaluate_reference(acpi_handle handle,
52 acpi_string pathname, 52 acpi_string pathname,
53 struct acpi_object_list *arguments, 53 struct acpi_object_list *arguments,
54 struct acpi_handle_list *list); 54 struct acpi_handle_list *list);
55 55
56 #ifdef CONFIG_ACPI 56 #ifdef CONFIG_ACPI
57 57
58 #include <linux/proc_fs.h> 58 #include <linux/proc_fs.h>
59 59
60 #define ACPI_BUS_FILE_ROOT "acpi" 60 #define ACPI_BUS_FILE_ROOT "acpi"
61 extern struct proc_dir_entry *acpi_root_dir; 61 extern struct proc_dir_entry *acpi_root_dir;
62 62
63 enum acpi_bus_removal_type { 63 enum acpi_bus_removal_type {
64 ACPI_BUS_REMOVAL_NORMAL = 0, 64 ACPI_BUS_REMOVAL_NORMAL = 0,
65 ACPI_BUS_REMOVAL_EJECT, 65 ACPI_BUS_REMOVAL_EJECT,
66 ACPI_BUS_REMOVAL_SUPRISE, 66 ACPI_BUS_REMOVAL_SUPRISE,
67 ACPI_BUS_REMOVAL_TYPE_COUNT 67 ACPI_BUS_REMOVAL_TYPE_COUNT
68 }; 68 };
69 69
70 enum acpi_bus_device_type { 70 enum acpi_bus_device_type {
71 ACPI_BUS_TYPE_DEVICE = 0, 71 ACPI_BUS_TYPE_DEVICE = 0,
72 ACPI_BUS_TYPE_POWER, 72 ACPI_BUS_TYPE_POWER,
73 ACPI_BUS_TYPE_PROCESSOR, 73 ACPI_BUS_TYPE_PROCESSOR,
74 ACPI_BUS_TYPE_THERMAL, 74 ACPI_BUS_TYPE_THERMAL,
75 ACPI_BUS_TYPE_SYSTEM, 75 ACPI_BUS_TYPE_SYSTEM,
76 ACPI_BUS_TYPE_POWER_BUTTON, 76 ACPI_BUS_TYPE_POWER_BUTTON,
77 ACPI_BUS_TYPE_SLEEP_BUTTON, 77 ACPI_BUS_TYPE_SLEEP_BUTTON,
78 ACPI_BUS_DEVICE_TYPE_COUNT 78 ACPI_BUS_DEVICE_TYPE_COUNT
79 }; 79 };
80 80
81 struct acpi_driver; 81 struct acpi_driver;
82 struct acpi_device; 82 struct acpi_device;
83 83
84 /* 84 /*
85 * ACPI Driver 85 * ACPI Driver
86 * ----------- 86 * -----------
87 */ 87 */
88 88
89 typedef int (*acpi_op_add) (struct acpi_device * device); 89 typedef int (*acpi_op_add) (struct acpi_device * device);
90 typedef int (*acpi_op_remove) (struct acpi_device * device, int type); 90 typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
91 typedef int (*acpi_op_lock) (struct acpi_device * device, int type); 91 typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
92 typedef int (*acpi_op_start) (struct acpi_device * device); 92 typedef int (*acpi_op_start) (struct acpi_device * device);
93 typedef int (*acpi_op_stop) (struct acpi_device * device, int type); 93 typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
94 typedef int (*acpi_op_suspend) (struct acpi_device * device, 94 typedef int (*acpi_op_suspend) (struct acpi_device * device,
95 pm_message_t state); 95 pm_message_t state);
96 typedef int (*acpi_op_resume) (struct acpi_device * device); 96 typedef int (*acpi_op_resume) (struct acpi_device * device);
97 typedef int (*acpi_op_scan) (struct acpi_device * device); 97 typedef int (*acpi_op_scan) (struct acpi_device * device);
98 typedef int (*acpi_op_bind) (struct acpi_device * device); 98 typedef int (*acpi_op_bind) (struct acpi_device * device);
99 typedef int (*acpi_op_unbind) (struct acpi_device * device); 99 typedef int (*acpi_op_unbind) (struct acpi_device * device);
100 typedef int (*acpi_op_shutdown) (struct acpi_device * device); 100 typedef int (*acpi_op_shutdown) (struct acpi_device * device);
101 101
102 struct acpi_bus_ops { 102 struct acpi_bus_ops {
103 u32 acpi_op_add:1; 103 u32 acpi_op_add:1;
104 u32 acpi_op_remove:1; 104 u32 acpi_op_remove:1;
105 u32 acpi_op_lock:1; 105 u32 acpi_op_lock:1;
106 u32 acpi_op_start:1; 106 u32 acpi_op_start:1;
107 u32 acpi_op_stop:1; 107 u32 acpi_op_stop:1;
108 u32 acpi_op_suspend:1; 108 u32 acpi_op_suspend:1;
109 u32 acpi_op_resume:1; 109 u32 acpi_op_resume:1;
110 u32 acpi_op_scan:1; 110 u32 acpi_op_scan:1;
111 u32 acpi_op_bind:1; 111 u32 acpi_op_bind:1;
112 u32 acpi_op_unbind:1; 112 u32 acpi_op_unbind:1;
113 u32 acpi_op_shutdown:1; 113 u32 acpi_op_shutdown:1;
114 u32 reserved:21; 114 u32 reserved:21;
115 }; 115 };
116 116
117 struct acpi_device_ops { 117 struct acpi_device_ops {
118 acpi_op_add add; 118 acpi_op_add add;
119 acpi_op_remove remove; 119 acpi_op_remove remove;
120 acpi_op_lock lock; 120 acpi_op_lock lock;
121 acpi_op_start start; 121 acpi_op_start start;
122 acpi_op_stop stop; 122 acpi_op_stop stop;
123 acpi_op_suspend suspend; 123 acpi_op_suspend suspend;
124 acpi_op_resume resume; 124 acpi_op_resume resume;
125 acpi_op_scan scan; 125 acpi_op_scan scan;
126 acpi_op_bind bind; 126 acpi_op_bind bind;
127 acpi_op_unbind unbind; 127 acpi_op_unbind unbind;
128 acpi_op_shutdown shutdown; 128 acpi_op_shutdown shutdown;
129 }; 129 };
130 130
131 struct acpi_driver { 131 struct acpi_driver {
132 char name[80]; 132 char name[80];
133 char class[80]; 133 char class[80];
134 const struct acpi_device_id *ids; /* Supported Hardware IDs */ 134 const struct acpi_device_id *ids; /* Supported Hardware IDs */
135 struct acpi_device_ops ops; 135 struct acpi_device_ops ops;
136 struct device_driver drv; 136 struct device_driver drv;
137 struct module *owner; 137 struct module *owner;
138 }; 138 };
139 139
140 /* 140 /*
141 * ACPI Device 141 * ACPI Device
142 * ----------- 142 * -----------
143 */ 143 */
144 144
145 /* Status (_STA) */ 145 /* Status (_STA) */
146 146
147 struct acpi_device_status { 147 struct acpi_device_status {
148 u32 present:1; 148 u32 present:1;
149 u32 enabled:1; 149 u32 enabled:1;
150 u32 show_in_ui:1; 150 u32 show_in_ui:1;
151 u32 functional:1; 151 u32 functional:1;
152 u32 battery_present:1; 152 u32 battery_present:1;
153 u32 reserved:27; 153 u32 reserved:27;
154 }; 154 };
155 155
156 /* Flags */ 156 /* Flags */
157 157
158 struct acpi_device_flags { 158 struct acpi_device_flags {
159 u32 dynamic_status:1; 159 u32 dynamic_status:1;
160 u32 hardware_id:1; 160 u32 hardware_id:1;
161 u32 compatible_ids:1; 161 u32 compatible_ids:1;
162 u32 bus_address:1; 162 u32 bus_address:1;
163 u32 unique_id:1; 163 u32 unique_id:1;
164 u32 removable:1; 164 u32 removable:1;
165 u32 ejectable:1; 165 u32 ejectable:1;
166 u32 lockable:1; 166 u32 lockable:1;
167 u32 suprise_removal_ok:1; 167 u32 suprise_removal_ok:1;
168 u32 power_manageable:1; 168 u32 power_manageable:1;
169 u32 performance_manageable:1; 169 u32 performance_manageable:1;
170 u32 wake_capable:1; /* Wakeup(_PRW) supported? */ 170 u32 wake_capable:1; /* Wakeup(_PRW) supported? */
171 u32 force_power_state:1; 171 u32 force_power_state:1;
172 u32 reserved:19; 172 u32 reserved:19;
173 }; 173 };
174 174
175 /* File System */ 175 /* File System */
176 176
177 struct acpi_device_dir { 177 struct acpi_device_dir {
178 struct proc_dir_entry *entry; 178 struct proc_dir_entry *entry;
179 }; 179 };
180 180
181 #define acpi_device_dir(d) ((d)->dir.entry) 181 #define acpi_device_dir(d) ((d)->dir.entry)
182 182
183 /* Plug and Play */ 183 /* Plug and Play */
184 184
185 typedef char acpi_bus_id[5]; 185 typedef char acpi_bus_id[5];
186 typedef unsigned long acpi_bus_address; 186 typedef unsigned long acpi_bus_address;
187 typedef char acpi_hardware_id[15]; 187 typedef char acpi_hardware_id[15];
188 typedef char acpi_unique_id[9]; 188 typedef char acpi_unique_id[9];
189 typedef char acpi_device_name[40]; 189 typedef char acpi_device_name[40];
190 typedef char acpi_device_class[20]; 190 typedef char acpi_device_class[20];
191 191
192 struct acpi_device_pnp { 192 struct acpi_device_pnp {
193 acpi_bus_id bus_id; /* Object name */ 193 acpi_bus_id bus_id; /* Object name */
194 acpi_bus_address bus_address; /* _ADR */ 194 acpi_bus_address bus_address; /* _ADR */
195 acpi_hardware_id hardware_id; /* _HID */ 195 acpi_hardware_id hardware_id; /* _HID */
196 struct acpi_compatible_id_list *cid_list; /* _CIDs */ 196 struct acpi_compatible_id_list *cid_list; /* _CIDs */
197 acpi_unique_id unique_id; /* _UID */ 197 acpi_unique_id unique_id; /* _UID */
198 acpi_device_name device_name; /* Driver-determined */ 198 acpi_device_name device_name; /* Driver-determined */
199 acpi_device_class device_class; /* " */ 199 acpi_device_class device_class; /* " */
200 }; 200 };
201 201
202 #define acpi_device_bid(d) ((d)->pnp.bus_id) 202 #define acpi_device_bid(d) ((d)->pnp.bus_id)
203 #define acpi_device_adr(d) ((d)->pnp.bus_address) 203 #define acpi_device_adr(d) ((d)->pnp.bus_address)
204 #define acpi_device_hid(d) ((d)->pnp.hardware_id) 204 #define acpi_device_hid(d) ((d)->pnp.hardware_id)
205 #define acpi_device_uid(d) ((d)->pnp.unique_id) 205 #define acpi_device_uid(d) ((d)->pnp.unique_id)
206 #define acpi_device_name(d) ((d)->pnp.device_name) 206 #define acpi_device_name(d) ((d)->pnp.device_name)
207 #define acpi_device_class(d) ((d)->pnp.device_class) 207 #define acpi_device_class(d) ((d)->pnp.device_class)
208 208
209 /* Power Management */ 209 /* Power Management */
210 210
211 struct acpi_device_power_flags { 211 struct acpi_device_power_flags {
212 u32 explicit_get:1; /* _PSC present? */ 212 u32 explicit_get:1; /* _PSC present? */
213 u32 power_resources:1; /* Power resources */ 213 u32 power_resources:1; /* Power resources */
214 u32 inrush_current:1; /* Serialize Dx->D0 */ 214 u32 inrush_current:1; /* Serialize Dx->D0 */
215 u32 power_removed:1; /* Optimize Dx->D0 */ 215 u32 power_removed:1; /* Optimize Dx->D0 */
216 u32 reserved:28; 216 u32 reserved:28;
217 }; 217 };
218 218
219 struct acpi_device_power_state { 219 struct acpi_device_power_state {
220 struct { 220 struct {
221 u8 valid:1; 221 u8 valid:1;
222 u8 explicit_set:1; /* _PSx present? */ 222 u8 explicit_set:1; /* _PSx present? */
223 u8 reserved:6; 223 u8 reserved:6;
224 } flags; 224 } flags;
225 int power; /* % Power (compared to D0) */ 225 int power; /* % Power (compared to D0) */
226 int latency; /* Dx->D0 time (microseconds) */ 226 int latency; /* Dx->D0 time (microseconds) */
227 struct acpi_handle_list resources; /* Power resources referenced */ 227 struct acpi_handle_list resources; /* Power resources referenced */
228 }; 228 };
229 229
230 struct acpi_device_power { 230 struct acpi_device_power {
231 int state; /* Current state */ 231 int state; /* Current state */
232 struct acpi_device_power_flags flags; 232 struct acpi_device_power_flags flags;
233 struct acpi_device_power_state states[4]; /* Power states (D0-D3) */ 233 struct acpi_device_power_state states[4]; /* Power states (D0-D3) */
234 }; 234 };
235 235
236 /* Performance Management */ 236 /* Performance Management */
237 237
238 struct acpi_device_perf_flags { 238 struct acpi_device_perf_flags {
239 u8 reserved:8; 239 u8 reserved:8;
240 }; 240 };
241 241
242 struct acpi_device_perf_state { 242 struct acpi_device_perf_state {
243 struct { 243 struct {
244 u8 valid:1; 244 u8 valid:1;
245 u8 reserved:7; 245 u8 reserved:7;
246 } flags; 246 } flags;
247 u8 power; /* % Power (compared to P0) */ 247 u8 power; /* % Power (compared to P0) */
248 u8 performance; /* % Performance ( " ) */ 248 u8 performance; /* % Performance ( " ) */
249 int latency; /* Px->P0 time (microseconds) */ 249 int latency; /* Px->P0 time (microseconds) */
250 }; 250 };
251 251
252 struct acpi_device_perf { 252 struct acpi_device_perf {
253 int state; 253 int state;
254 struct acpi_device_perf_flags flags; 254 struct acpi_device_perf_flags flags;
255 int state_count; 255 int state_count;
256 struct acpi_device_perf_state *states; 256 struct acpi_device_perf_state *states;
257 }; 257 };
258 258
259 /* Wakeup Management */ 259 /* Wakeup Management */
260 struct acpi_device_wakeup_flags { 260 struct acpi_device_wakeup_flags {
261 u8 valid:1; /* Can successfully enable wakeup? */ 261 u8 valid:1; /* Can successfully enable wakeup? */
262 u8 prepared:1; /* Has the wake-up capability been enabled? */ 262 u8 prepared:1; /* Has the wake-up capability been enabled? */
263 u8 run_wake:1; /* Run-Wake GPE devices */ 263 u8 run_wake:1; /* Run-Wake GPE devices */
264 }; 264 };
265 265
266 struct acpi_device_wakeup_state { 266 struct acpi_device_wakeup_state {
267 u8 enabled:1; 267 u8 enabled:1;
268 }; 268 };
269 269
270 struct acpi_device_wakeup { 270 struct acpi_device_wakeup {
271 acpi_handle gpe_device; 271 acpi_handle gpe_device;
272 acpi_integer gpe_number; 272 acpi_integer gpe_number;
273 acpi_integer sleep_state; 273 acpi_integer sleep_state;
274 struct acpi_handle_list resources; 274 struct acpi_handle_list resources;
275 struct acpi_device_wakeup_state state; 275 struct acpi_device_wakeup_state state;
276 struct acpi_device_wakeup_flags flags; 276 struct acpi_device_wakeup_flags flags;
277 }; 277 };
278 278
279 /* Device */ 279 /* Device */
280 280
281 struct acpi_device { 281 struct acpi_device {
282 acpi_handle handle; 282 acpi_handle handle;
283 struct acpi_device *parent; 283 struct acpi_device *parent;
284 struct list_head children; 284 struct list_head children;
285 struct list_head node; 285 struct list_head node;
286 struct list_head wakeup_list; 286 struct list_head wakeup_list;
287 struct list_head g_list; 287 struct list_head g_list;
288 struct acpi_device_status status; 288 struct acpi_device_status status;
289 struct acpi_device_flags flags; 289 struct acpi_device_flags flags;
290 struct acpi_device_pnp pnp; 290 struct acpi_device_pnp pnp;
291 struct acpi_device_power power; 291 struct acpi_device_power power;
292 struct acpi_device_wakeup wakeup; 292 struct acpi_device_wakeup wakeup;
293 struct acpi_device_perf performance; 293 struct acpi_device_perf performance;
294 struct acpi_device_dir dir; 294 struct acpi_device_dir dir;
295 struct acpi_device_ops ops; 295 struct acpi_device_ops ops;
296 struct acpi_driver *driver; 296 struct acpi_driver *driver;
297 void *driver_data; 297 void *driver_data;
298 struct device dev; 298 struct device dev;
299 struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */ 299 struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */
300 enum acpi_bus_removal_type removal_type; /* indicate for different removal type */ 300 enum acpi_bus_removal_type removal_type; /* indicate for different removal type */
301 }; 301 };
302 302
303 static inline void *acpi_driver_data(struct acpi_device *d) 303 static inline void *acpi_driver_data(struct acpi_device *d)
304 { 304 {
305 return d->driver_data; 305 return d->driver_data;
306 } 306 }
307 307
308 #define to_acpi_device(d) container_of(d, struct acpi_device, dev) 308 #define to_acpi_device(d) container_of(d, struct acpi_device, dev)
309 #define to_acpi_driver(d) container_of(d, struct acpi_driver, drv) 309 #define to_acpi_driver(d) container_of(d, struct acpi_driver, drv)
310 310
311 /* acpi_device.dev.bus == &acpi_bus_type */ 311 /* acpi_device.dev.bus == &acpi_bus_type */
312 extern struct bus_type acpi_bus_type; 312 extern struct bus_type acpi_bus_type;
313 313
314 /* 314 /*
315 * Events 315 * Events
316 * ------ 316 * ------
317 */ 317 */
318 318
319 struct acpi_bus_event { 319 struct acpi_bus_event {
320 struct list_head node; 320 struct list_head node;
321 acpi_device_class device_class; 321 acpi_device_class device_class;
322 acpi_bus_id bus_id; 322 acpi_bus_id bus_id;
323 u32 type; 323 u32 type;
324 u32 data; 324 u32 data;
325 }; 325 };
326 326
327 extern struct kobject *acpi_kobj; 327 extern struct kobject *acpi_kobj;
328 extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); 328 extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
329 void acpi_bus_private_data_handler(acpi_handle, u32, void *); 329 void acpi_bus_private_data_handler(acpi_handle, u32, void *);
330 int acpi_bus_get_private_data(acpi_handle, void **); 330 int acpi_bus_get_private_data(acpi_handle, void **);
331 extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); 331 extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
332 extern int register_acpi_notifier(struct notifier_block *); 332 extern int register_acpi_notifier(struct notifier_block *);
333 extern int unregister_acpi_notifier(struct notifier_block *); 333 extern int unregister_acpi_notifier(struct notifier_block *);
334 334
335 extern int register_acpi_bus_notifier(struct notifier_block *nb); 335 extern int register_acpi_bus_notifier(struct notifier_block *nb);
336 extern void unregister_acpi_bus_notifier(struct notifier_block *nb); 336 extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
337 /* 337 /*
338 * External Functions 338 * External Functions
339 */ 339 */
340 340
341 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); 341 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
342 void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context); 342 void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context);
343 int acpi_bus_get_status(struct acpi_device *device); 343 int acpi_bus_get_status(struct acpi_device *device);
344 int acpi_bus_get_power(acpi_handle handle, int *state); 344 int acpi_bus_get_power(acpi_handle handle, int *state);
345 int acpi_bus_set_power(acpi_handle handle, int state); 345 int acpi_bus_set_power(acpi_handle handle, int state);
346 bool acpi_bus_power_manageable(acpi_handle handle); 346 bool acpi_bus_power_manageable(acpi_handle handle);
347 bool acpi_bus_can_wakeup(acpi_handle handle); 347 bool acpi_bus_can_wakeup(acpi_handle handle);
348 #ifdef CONFIG_ACPI_PROC_EVENT 348 #ifdef CONFIG_ACPI_PROC_EVENT
349 int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); 349 int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
350 int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data); 350 int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data);
351 int acpi_bus_receive_event(struct acpi_bus_event *event); 351 int acpi_bus_receive_event(struct acpi_bus_event *event);
352 #else 352 #else
353 static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) 353 static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
354 { return 0; } 354 { return 0; }
355 #endif 355 #endif
356 int acpi_bus_register_driver(struct acpi_driver *driver); 356 int acpi_bus_register_driver(struct acpi_driver *driver);
357 void acpi_bus_unregister_driver(struct acpi_driver *driver); 357 void acpi_bus_unregister_driver(struct acpi_driver *driver);
358 int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent, 358 int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
359 acpi_handle handle, int type); 359 acpi_handle handle, int type);
360 int acpi_bus_trim(struct acpi_device *start, int rmdevice); 360 int acpi_bus_trim(struct acpi_device *start, int rmdevice);
361 int acpi_bus_start(struct acpi_device *device); 361 int acpi_bus_start(struct acpi_device *device);
362 acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd); 362 acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
363 int acpi_match_device_ids(struct acpi_device *device, 363 int acpi_match_device_ids(struct acpi_device *device,
364 const struct acpi_device_id *ids); 364 const struct acpi_device_id *ids);
365 int acpi_create_dir(struct acpi_device *); 365 int acpi_create_dir(struct acpi_device *);
366 void acpi_remove_dir(struct acpi_device *); 366 void acpi_remove_dir(struct acpi_device *);
367 367
368 /* 368 /*
369 * Bind physical devices with ACPI devices 369 * Bind physical devices with ACPI devices
370 */ 370 */
371 #include <linux/device.h> 371 #include <linux/device.h>
372 struct acpi_bus_type { 372 struct acpi_bus_type {
373 struct list_head list; 373 struct list_head list;
374 struct bus_type *bus; 374 struct bus_type *bus;
375 /* For general devices under the bus */ 375 /* For general devices under the bus */
376 int (*find_device) (struct device *, acpi_handle *); 376 int (*find_device) (struct device *, acpi_handle *);
377 /* For bridges, such as PCI root bridge, IDE controller */ 377 /* For bridges, such as PCI root bridge, IDE controller */
378 int (*find_bridge) (struct device *, acpi_handle *); 378 int (*find_bridge) (struct device *, acpi_handle *);
379 }; 379 };
380 int register_acpi_bus_type(struct acpi_bus_type *); 380 int register_acpi_bus_type(struct acpi_bus_type *);
381 int unregister_acpi_bus_type(struct acpi_bus_type *); 381 int unregister_acpi_bus_type(struct acpi_bus_type *);
382 struct device *acpi_get_physical_device(acpi_handle); 382 struct device *acpi_get_physical_device(acpi_handle);
383 struct device *acpi_get_physical_pci_device(acpi_handle);
384
383 /* helper */ 385 /* helper */
384 acpi_handle acpi_get_child(acpi_handle, acpi_integer); 386 acpi_handle acpi_get_child(acpi_handle, acpi_integer);
385 acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); 387 acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
386 #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) 388 #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
387 389
388 #ifdef CONFIG_PM_SLEEP 390 #ifdef CONFIG_PM_SLEEP
389 int acpi_pm_device_sleep_state(struct device *, int *); 391 int acpi_pm_device_sleep_state(struct device *, int *);
390 int acpi_pm_device_sleep_wake(struct device *, bool); 392 int acpi_pm_device_sleep_wake(struct device *, bool);
391 #else /* !CONFIG_PM_SLEEP */ 393 #else /* !CONFIG_PM_SLEEP */
392 static inline int acpi_pm_device_sleep_state(struct device *d, int *p) 394 static inline int acpi_pm_device_sleep_state(struct device *d, int *p)
393 { 395 {
394 if (p) 396 if (p)
395 *p = ACPI_STATE_D0; 397 *p = ACPI_STATE_D0;
396 return ACPI_STATE_D3; 398 return ACPI_STATE_D3;
397 } 399 }
398 static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) 400 static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
399 { 401 {
400 return -ENODEV; 402 return -ENODEV;
401 } 403 }
402 #endif /* !CONFIG_PM_SLEEP */ 404 #endif /* !CONFIG_PM_SLEEP */
403 405
404 #endif /* CONFIG_ACPI */ 406 #endif /* CONFIG_ACPI */
405 407
406 #endif /*__ACPI_BUS_H__*/ 408 #endif /*__ACPI_BUS_H__*/
407 409
include/linux/acpi.h
1 /* 1 /*
2 * acpi.h - ACPI Interface 2 * acpi.h - ACPI Interface
3 * 3 *
4 * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 4 * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5 * 5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * 21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */ 23 */
24 24
25 #ifndef _LINUX_ACPI_H 25 #ifndef _LINUX_ACPI_H
26 #define _LINUX_ACPI_H 26 #define _LINUX_ACPI_H
27 27
28 #include <linux/ioport.h> /* for struct resource */ 28 #include <linux/ioport.h> /* for struct resource */
29 29
30 #ifdef CONFIG_ACPI 30 #ifdef CONFIG_ACPI
31 31
32 #ifndef _LINUX 32 #ifndef _LINUX
33 #define _LINUX 33 #define _LINUX
34 #endif 34 #endif
35 35
36 #include <linux/list.h> 36 #include <linux/list.h>
37 #include <linux/mod_devicetable.h> 37 #include <linux/mod_devicetable.h>
38 38
39 #include <acpi/acpi.h> 39 #include <acpi/acpi.h>
40 #include <acpi/acpi_bus.h> 40 #include <acpi/acpi_bus.h>
41 #include <acpi/acpi_drivers.h> 41 #include <acpi/acpi_drivers.h>
42 #include <acpi/acpi_numa.h> 42 #include <acpi/acpi_numa.h>
43 #include <asm/acpi.h> 43 #include <asm/acpi.h>
44 #include <linux/dmi.h> 44 #include <linux/dmi.h>
45 45
46 46
47 enum acpi_irq_model_id { 47 enum acpi_irq_model_id {
48 ACPI_IRQ_MODEL_PIC = 0, 48 ACPI_IRQ_MODEL_PIC = 0,
49 ACPI_IRQ_MODEL_IOAPIC, 49 ACPI_IRQ_MODEL_IOAPIC,
50 ACPI_IRQ_MODEL_IOSAPIC, 50 ACPI_IRQ_MODEL_IOSAPIC,
51 ACPI_IRQ_MODEL_PLATFORM, 51 ACPI_IRQ_MODEL_PLATFORM,
52 ACPI_IRQ_MODEL_COUNT 52 ACPI_IRQ_MODEL_COUNT
53 }; 53 };
54 54
55 extern enum acpi_irq_model_id acpi_irq_model; 55 extern enum acpi_irq_model_id acpi_irq_model;
56 56
57 enum acpi_interrupt_id { 57 enum acpi_interrupt_id {
58 ACPI_INTERRUPT_PMI = 1, 58 ACPI_INTERRUPT_PMI = 1,
59 ACPI_INTERRUPT_INIT, 59 ACPI_INTERRUPT_INIT,
60 ACPI_INTERRUPT_CPEI, 60 ACPI_INTERRUPT_CPEI,
61 ACPI_INTERRUPT_COUNT 61 ACPI_INTERRUPT_COUNT
62 }; 62 };
63 63
64 #define ACPI_SPACE_MEM 0 64 #define ACPI_SPACE_MEM 0
65 65
66 enum acpi_address_range_id { 66 enum acpi_address_range_id {
67 ACPI_ADDRESS_RANGE_MEMORY = 1, 67 ACPI_ADDRESS_RANGE_MEMORY = 1,
68 ACPI_ADDRESS_RANGE_RESERVED = 2, 68 ACPI_ADDRESS_RANGE_RESERVED = 2,
69 ACPI_ADDRESS_RANGE_ACPI = 3, 69 ACPI_ADDRESS_RANGE_ACPI = 3,
70 ACPI_ADDRESS_RANGE_NVS = 4, 70 ACPI_ADDRESS_RANGE_NVS = 4,
71 ACPI_ADDRESS_RANGE_COUNT 71 ACPI_ADDRESS_RANGE_COUNT
72 }; 72 };
73 73
74 74
75 /* Table Handlers */ 75 /* Table Handlers */
76 76
77 typedef int (*acpi_table_handler) (struct acpi_table_header *table); 77 typedef int (*acpi_table_handler) (struct acpi_table_header *table);
78 78
79 typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); 79 typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
80 80
81 char * __acpi_map_table (unsigned long phys_addr, unsigned long size); 81 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
82 int early_acpi_boot_init(void); 82 int early_acpi_boot_init(void);
83 int acpi_boot_init (void); 83 int acpi_boot_init (void);
84 int acpi_boot_table_init (void); 84 int acpi_boot_table_init (void);
85 int acpi_mps_check (void); 85 int acpi_mps_check (void);
86 int acpi_numa_init (void); 86 int acpi_numa_init (void);
87 87
88 int acpi_table_init (void); 88 int acpi_table_init (void);
89 int acpi_table_parse (char *id, acpi_table_handler handler); 89 int acpi_table_parse (char *id, acpi_table_handler handler);
90 int __init acpi_table_parse_entries(char *id, unsigned long table_size, 90 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
91 int entry_id, acpi_table_entry_handler handler, unsigned int max_entries); 91 int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
92 int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries); 92 int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries);
93 int acpi_parse_mcfg (struct acpi_table_header *header); 93 int acpi_parse_mcfg (struct acpi_table_header *header);
94 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); 94 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
95 95
96 /* the following four functions are architecture-dependent */ 96 /* the following four functions are architecture-dependent */
97 void acpi_numa_slit_init (struct acpi_table_slit *slit); 97 void acpi_numa_slit_init (struct acpi_table_slit *slit);
98 void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); 98 void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
99 void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); 99 void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
100 void acpi_numa_arch_fixup(void); 100 void acpi_numa_arch_fixup(void);
101 101
102 #ifdef CONFIG_ACPI_HOTPLUG_CPU 102 #ifdef CONFIG_ACPI_HOTPLUG_CPU
103 /* Arch dependent functions for cpu hotplug support */ 103 /* Arch dependent functions for cpu hotplug support */
104 int acpi_map_lsapic(acpi_handle handle, int *pcpu); 104 int acpi_map_lsapic(acpi_handle handle, int *pcpu);
105 int acpi_unmap_lsapic(int cpu); 105 int acpi_unmap_lsapic(int cpu);
106 #endif /* CONFIG_ACPI_HOTPLUG_CPU */ 106 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
107 107
108 int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); 108 int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base);
109 int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); 109 int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base);
110 void acpi_irq_stats_init(void); 110 void acpi_irq_stats_init(void);
111 extern u32 acpi_irq_handled; 111 extern u32 acpi_irq_handled;
112 112
113 extern struct acpi_mcfg_allocation *pci_mmcfg_config; 113 extern struct acpi_mcfg_allocation *pci_mmcfg_config;
114 extern int pci_mmcfg_config_num; 114 extern int pci_mmcfg_config_num;
115 115
116 extern int sbf_port; 116 extern int sbf_port;
117 extern unsigned long acpi_realmode_flags; 117 extern unsigned long acpi_realmode_flags;
118 118
119 int acpi_register_gsi (u32 gsi, int triggering, int polarity); 119 int acpi_register_gsi (u32 gsi, int triggering, int polarity);
120 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); 120 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
121 121
122 #ifdef CONFIG_X86_IO_APIC 122 #ifdef CONFIG_X86_IO_APIC
123 extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity); 123 extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
124 #else 124 #else
125 #define acpi_get_override_irq(bus, trigger, polarity) (-1) 125 #define acpi_get_override_irq(bus, trigger, polarity) (-1)
126 #endif 126 #endif
127 /* 127 /*
128 * This function undoes the effect of one call to acpi_register_gsi(). 128 * This function undoes the effect of one call to acpi_register_gsi().
129 * If this matches the last registration, any IRQ resources for gsi 129 * If this matches the last registration, any IRQ resources for gsi
130 * are freed. 130 * are freed.
131 */ 131 */
132 void acpi_unregister_gsi (u32 gsi); 132 void acpi_unregister_gsi (u32 gsi);
133 133
134 struct acpi_prt_entry { 134 struct acpi_prt_entry {
135 struct list_head node; 135 struct list_head node;
136 struct acpi_pci_id id; 136 struct acpi_pci_id id;
137 u8 pin; 137 u8 pin;
138 struct { 138 struct {
139 acpi_handle handle; 139 acpi_handle handle;
140 u32 index; 140 u32 index;
141 } link; 141 } link;
142 u32 irq; 142 u32 irq;
143 }; 143 };
144 144
145 struct acpi_prt_list { 145 struct acpi_prt_list {
146 int count; 146 int count;
147 struct list_head entries; 147 struct list_head entries;
148 }; 148 };
149 149
150 struct pci_dev; 150 struct pci_dev;
151 151
152 int acpi_pci_irq_enable (struct pci_dev *dev); 152 int acpi_pci_irq_enable (struct pci_dev *dev);
153 void acpi_penalize_isa_irq(int irq, int active); 153 void acpi_penalize_isa_irq(int irq, int active);
154 154
155 void acpi_pci_irq_disable (struct pci_dev *dev); 155 void acpi_pci_irq_disable (struct pci_dev *dev);
156 156
157 struct acpi_pci_driver { 157 struct acpi_pci_driver {
158 struct acpi_pci_driver *next; 158 struct acpi_pci_driver *next;
159 int (*add)(acpi_handle handle); 159 int (*add)(acpi_handle handle);
160 void (*remove)(acpi_handle handle); 160 void (*remove)(acpi_handle handle);
161 }; 161 };
162 162
163 int acpi_pci_register_driver(struct acpi_pci_driver *driver); 163 int acpi_pci_register_driver(struct acpi_pci_driver *driver);
164 void acpi_pci_unregister_driver(struct acpi_pci_driver *driver); 164 void acpi_pci_unregister_driver(struct acpi_pci_driver *driver);
165 165
166 extern int ec_read(u8 addr, u8 *val); 166 extern int ec_read(u8 addr, u8 *val);
167 extern int ec_write(u8 addr, u8 val); 167 extern int ec_write(u8 addr, u8 val);
168 extern int ec_transaction(u8 command, 168 extern int ec_transaction(u8 command,
169 const u8 *wdata, unsigned wdata_len, 169 const u8 *wdata, unsigned wdata_len,
170 u8 *rdata, unsigned rdata_len, 170 u8 *rdata, unsigned rdata_len,
171 int force_poll); 171 int force_poll);
172 172
173 #if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) 173 #if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
174 174
175 typedef void (*wmi_notify_handler) (u32 value, void *context); 175 typedef void (*wmi_notify_handler) (u32 value, void *context);
176 176
177 extern acpi_status wmi_evaluate_method(const char *guid, u8 instance, 177 extern acpi_status wmi_evaluate_method(const char *guid, u8 instance,
178 u32 method_id, 178 u32 method_id,
179 const struct acpi_buffer *in, 179 const struct acpi_buffer *in,
180 struct acpi_buffer *out); 180 struct acpi_buffer *out);
181 extern acpi_status wmi_query_block(const char *guid, u8 instance, 181 extern acpi_status wmi_query_block(const char *guid, u8 instance,
182 struct acpi_buffer *out); 182 struct acpi_buffer *out);
183 extern acpi_status wmi_set_block(const char *guid, u8 instance, 183 extern acpi_status wmi_set_block(const char *guid, u8 instance,
184 const struct acpi_buffer *in); 184 const struct acpi_buffer *in);
185 extern acpi_status wmi_install_notify_handler(const char *guid, 185 extern acpi_status wmi_install_notify_handler(const char *guid,
186 wmi_notify_handler handler, void *data); 186 wmi_notify_handler handler, void *data);
187 extern acpi_status wmi_remove_notify_handler(const char *guid); 187 extern acpi_status wmi_remove_notify_handler(const char *guid);
188 extern acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out); 188 extern acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out);
189 extern bool wmi_has_guid(const char *guid); 189 extern bool wmi_has_guid(const char *guid);
190 190
191 #endif /* CONFIG_ACPI_WMI */ 191 #endif /* CONFIG_ACPI_WMI */
192 192
193 #define ACPI_VIDEO_OUTPUT_SWITCHING 0x0001
194 #define ACPI_VIDEO_DEVICE_POSTING 0x0002
195 #define ACPI_VIDEO_ROM_AVAILABLE 0x0004
196 #define ACPI_VIDEO_BACKLIGHT 0x0008
197 #define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR 0x0010
198 #define ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO 0x0020
199 #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR 0x0040
200 #define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO 0x0080
201 #define ACPI_VIDEO_BACKLIGHT_DMI_VENDOR 0x0100
202 #define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO 0x0200
203 #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR 0x0400
204 #define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO 0x0800
205
206 #if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE)
207
208 extern long acpi_video_get_capabilities(acpi_handle graphics_dev_handle);
209 extern long acpi_is_video_device(struct acpi_device *device);
210 extern int acpi_video_backlight_support(void);
211 extern int acpi_video_display_switch_support(void);
212
213 #else
214
215 static inline long acpi_video_get_capabilities(acpi_handle graphics_dev_handle)
216 {
217 return 0;
218 }
219
220 static inline long acpi_is_video_device(struct acpi_device *device)
221 {
222 return 0;
223 }
224
225 static inline int acpi_video_backlight_support(void)
226 {
227 return 0;
228 }
229
230 static inline int acpi_video_display_switch_support(void)
231 {
232 return 0;
233 }
234
235 #endif /* defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) */
236
193 extern int acpi_blacklisted(void); 237 extern int acpi_blacklisted(void);
194 #ifdef CONFIG_DMI 238 #ifdef CONFIG_DMI
195 extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); 239 extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
196 extern int acpi_osi_setup(char *str); 240 extern int acpi_osi_setup(char *str);
197 #endif 241 #endif
198 242
199 #ifdef CONFIG_ACPI_NUMA 243 #ifdef CONFIG_ACPI_NUMA
200 int acpi_get_pxm(acpi_handle handle); 244 int acpi_get_pxm(acpi_handle handle);
201 int acpi_get_node(acpi_handle *handle); 245 int acpi_get_node(acpi_handle *handle);
202 #else 246 #else
203 static inline int acpi_get_pxm(acpi_handle handle) 247 static inline int acpi_get_pxm(acpi_handle handle)
204 { 248 {
205 return 0; 249 return 0;
206 } 250 }
207 static inline int acpi_get_node(acpi_handle *handle) 251 static inline int acpi_get_node(acpi_handle *handle)
208 { 252 {
209 return 0; 253 return 0;
210 } 254 }
211 #endif 255 #endif
212 extern int acpi_paddr_to_node(u64 start_addr, u64 size); 256 extern int acpi_paddr_to_node(u64 start_addr, u64 size);
213 257
214 extern int pnpacpi_disabled; 258 extern int pnpacpi_disabled;
215 259
216 #define PXM_INVAL (-1) 260 #define PXM_INVAL (-1)
217 #define NID_INVAL (-1) 261 #define NID_INVAL (-1)
218 262
219 int acpi_check_resource_conflict(struct resource *res); 263 int acpi_check_resource_conflict(struct resource *res);
220 264
221 int acpi_check_region(resource_size_t start, resource_size_t n, 265 int acpi_check_region(resource_size_t start, resource_size_t n,
222 const char *name); 266 const char *name);
223 int acpi_check_mem_region(resource_size_t start, resource_size_t n, 267 int acpi_check_mem_region(resource_size_t start, resource_size_t n,
224 const char *name); 268 const char *name);
225 269
226 #ifdef CONFIG_PM_SLEEP 270 #ifdef CONFIG_PM_SLEEP
227 void __init acpi_no_s4_hw_signature(void); 271 void __init acpi_no_s4_hw_signature(void);
228 void __init acpi_old_suspend_ordering(void); 272 void __init acpi_old_suspend_ordering(void);
229 #endif /* CONFIG_PM_SLEEP */ 273 #endif /* CONFIG_PM_SLEEP */
230 #else /* CONFIG_ACPI */ 274 #else /* CONFIG_ACPI */
231 275
232 static inline int early_acpi_boot_init(void) 276 static inline int early_acpi_boot_init(void)
233 { 277 {
234 return 0; 278 return 0;
235 } 279 }
236 static inline int acpi_boot_init(void) 280 static inline int acpi_boot_init(void)
237 { 281 {
238 return 0; 282 return 0;
239 } 283 }
240 284
241 static inline int acpi_boot_table_init(void) 285 static inline int acpi_boot_table_init(void)
242 { 286 {
243 return 0; 287 return 0;
244 } 288 }
245 289
246 static inline int acpi_mps_check(void) 290 static inline int acpi_mps_check(void)
247 { 291 {
248 return 0; 292 return 0;
249 } 293 }
250 294
251 static inline int acpi_check_resource_conflict(struct resource *res) 295 static inline int acpi_check_resource_conflict(struct resource *res)
252 { 296 {
253 return 0; 297 return 0;
254 } 298 }
255 299
256 static inline int acpi_check_region(resource_size_t start, resource_size_t n, 300 static inline int acpi_check_region(resource_size_t start, resource_size_t n,
257 const char *name) 301 const char *name)
258 { 302 {
259 return 0; 303 return 0;
260 } 304 }
261 305
262 static inline int acpi_check_mem_region(resource_size_t start, 306 static inline int acpi_check_mem_region(resource_size_t start,
263 resource_size_t n, const char *name) 307 resource_size_t n, const char *name)
264 { 308 {
265 return 0; 309 return 0;
266 } 310 }
267 311
268 #endif /* !CONFIG_ACPI */ 312 #endif /* !CONFIG_ACPI */
269 #endif /*_LINUX_ACPI_H*/ 313 #endif /*_LINUX_ACPI_H*/
270 314