aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig16
-rw-r--r--drivers/misc/Makefile2
-rw-r--r--drivers/misc/acer-wmi.c6
-rw-r--r--drivers/misc/asus-laptop.c10
-rw-r--r--drivers/misc/c2port/Kconfig35
-rw-r--r--drivers/misc/c2port/Makefile3
-rw-r--r--drivers/misc/c2port/c2port-duramar2150.c158
-rw-r--r--drivers/misc/c2port/core.c1002
-rw-r--r--drivers/misc/compal-laptop.c12
-rw-r--r--drivers/misc/eeepc-laptop.c12
-rw-r--r--drivers/misc/fujitsu-laptop.c43
-rw-r--r--drivers/misc/ics932s401.c515
-rw-r--r--drivers/misc/intel_menlow.c10
-rw-r--r--drivers/misc/msi-laptop.c16
-rw-r--r--drivers/misc/sony-laptop.c6
-rw-r--r--drivers/misc/thinkpad_acpi.c29
16 files changed, 1831 insertions, 44 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 9494400e8fd0..fee7304102af 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -227,10 +227,20 @@ config HP_WMI
227 To compile this driver as a module, choose M here: the module will 227 To compile this driver as a module, choose M here: the module will
228 be called hp-wmi. 228 be called hp-wmi.
229 229
230config ICS932S401
231 tristate "Integrated Circuits ICS932S401"
232 depends on I2C && EXPERIMENTAL
233 help
234 If you say yes here you get support for the Integrated Circuits
235 ICS932S401 clock control chips.
236
237 This driver can also be built as a module. If so, the module
238 will be called ics932s401.
239
230config MSI_LAPTOP 240config MSI_LAPTOP
231 tristate "MSI Laptop Extras" 241 tristate "MSI Laptop Extras"
232 depends on X86 242 depends on X86
233 depends on ACPI_EC 243 depends on ACPI
234 depends on BACKLIGHT_CLASS_DEVICE 244 depends on BACKLIGHT_CLASS_DEVICE
235 ---help--- 245 ---help---
236 This is a driver for laptops built by MSI (MICRO-STAR 246 This is a driver for laptops built by MSI (MICRO-STAR
@@ -260,7 +270,7 @@ config PANASONIC_LAPTOP
260config COMPAL_LAPTOP 270config COMPAL_LAPTOP
261 tristate "Compal Laptop Extras" 271 tristate "Compal Laptop Extras"
262 depends on X86 272 depends on X86
263 depends on ACPI_EC 273 depends on ACPI
264 depends on BACKLIGHT_CLASS_DEVICE 274 depends on BACKLIGHT_CLASS_DEVICE
265 ---help--- 275 ---help---
266 This is a driver for laptops built by Compal: 276 This is a driver for laptops built by Compal:
@@ -488,4 +498,6 @@ config SGI_GRU_DEBUG
488 This option enables addition debugging code for the SGI GRU driver. If 498 This option enables addition debugging code for the SGI GRU driver. If
489 you are unsure, say N. 499 you are unsure, say N.
490 500
501source "drivers/misc/c2port/Kconfig"
502
491endif # MISC_DEVICES 503endif # MISC_DEVICES
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 909e2468cdc9..817f7f5ab3bd 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
14obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o 14obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
15obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o 15obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
16obj-$(CONFIG_HP_WMI) += hp-wmi.o 16obj-$(CONFIG_HP_WMI) += hp-wmi.o
17obj-$(CONFIG_ICS932S401) += ics932s401.o
17obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o 18obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
18obj-$(CONFIG_LKDTM) += lkdtm.o 19obj-$(CONFIG_LKDTM) += lkdtm.o
19obj-$(CONFIG_TIFM_CORE) += tifm_core.o 20obj-$(CONFIG_TIFM_CORE) += tifm_core.o
@@ -31,3 +32,4 @@ obj-$(CONFIG_KGDB_TESTS) += kgdbts.o
31obj-$(CONFIG_SGI_XP) += sgi-xp/ 32obj-$(CONFIG_SGI_XP) += sgi-xp/
32obj-$(CONFIG_SGI_GRU) += sgi-gru/ 33obj-$(CONFIG_SGI_GRU) += sgi-gru/
33obj-$(CONFIG_HP_ILO) += hpilo.o 34obj-$(CONFIG_HP_ILO) += hpilo.o
35obj-$(CONFIG_C2PORT) += c2port/
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c
index 0532a2de2ce4..94c9f911824e 100644
--- a/drivers/misc/acer-wmi.c
+++ b/drivers/misc/acer-wmi.c
@@ -1297,6 +1297,12 @@ static int __init acer_wmi_init(void)
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;
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index a9d5228724a6..8fb8b3591048 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -1208,9 +1208,13 @@ static int __init asus_laptop_init(void)
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)
diff --git a/drivers/misc/c2port/Kconfig b/drivers/misc/c2port/Kconfig
new file mode 100644
index 000000000000..e46af9a5810d
--- /dev/null
+++ b/drivers/misc/c2port/Kconfig
@@ -0,0 +1,35 @@
1#
2# C2 port devices
3#
4
5menuconfig C2PORT
6 tristate "Silicon Labs C2 port support (EXPERIMENTAL)"
7 depends on EXPERIMENTAL
8 default no
9 help
10 This option enables support for Silicon Labs C2 port used to
11 program Silicon micro controller chips (and other 8051 compatible).
12
13 If your board have no such micro controllers you don't need this
14 interface at all.
15
16 To compile this driver as a module, choose M here: the module will
17 be called c2port_core. Note that you also need a client module
18 usually called c2port-*.
19
20 If you are not sure, say N here.
21
22if C2PORT
23
24config C2PORT_DURAMAR_2150
25 tristate "C2 port support for Eurotech's Duramar 2150 (EXPERIMENTAL)"
26 depends on X86 && C2PORT
27 default no
28 help
29 This option enables C2 support for the Eurotech's Duramar 2150
30 on board micro controller.
31
32 To compile this driver as a module, choose M here: the module will
33 be called c2port-duramar2150.
34
35endif # C2PORT
diff --git a/drivers/misc/c2port/Makefile b/drivers/misc/c2port/Makefile
new file mode 100644
index 000000000000..3b2cf43d60f5
--- /dev/null
+++ b/drivers/misc/c2port/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_C2PORT) += core.o
2
3obj-$(CONFIG_C2PORT_DURAMAR_2150) += c2port-duramar2150.o
diff --git a/drivers/misc/c2port/c2port-duramar2150.c b/drivers/misc/c2port/c2port-duramar2150.c
new file mode 100644
index 000000000000..338dcc121507
--- /dev/null
+++ b/drivers/misc/c2port/c2port-duramar2150.c
@@ -0,0 +1,158 @@
1/*
2 * Silicon Labs C2 port Linux support for Eurotech Duramar 2150
3 *
4 * Copyright (c) 2008 Rodolfo Giometti <giometti@linux.it>
5 * Copyright (c) 2008 Eurotech S.p.A. <info@eurotech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation
10 */
11
12#include <linux/errno.h>
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/delay.h>
17#include <linux/io.h>
18#include <linux/c2port.h>
19
20#define DATA_PORT 0x325
21#define DIR_PORT 0x326
22#define C2D (1 << 0)
23#define C2CK (1 << 1)
24
25static DEFINE_MUTEX(update_lock);
26
27/*
28 * C2 port operations
29 */
30
31static void duramar2150_c2port_access(struct c2port_device *dev, int status)
32{
33 u8 v;
34
35 mutex_lock(&update_lock);
36
37 v = inb(DIR_PORT);
38
39 /* 0 = input, 1 = output */
40 if (status)
41 outb(v | (C2D | C2CK), DIR_PORT);
42 else
43 /* When access is "off" is important that both lines are set
44 * as inputs or hi-impedence */
45 outb(v & ~(C2D | C2CK), DIR_PORT);
46
47 mutex_unlock(&update_lock);
48}
49
50static void duramar2150_c2port_c2d_dir(struct c2port_device *dev, int dir)
51{
52 u8 v;
53
54 mutex_lock(&update_lock);
55
56 v = inb(DIR_PORT);
57
58 if (dir)
59 outb(v & ~C2D, DIR_PORT);
60 else
61 outb(v | C2D, DIR_PORT);
62
63 mutex_unlock(&update_lock);
64}
65
66static int duramar2150_c2port_c2d_get(struct c2port_device *dev)
67{
68 return inb(DATA_PORT) & C2D;
69}
70
71static void duramar2150_c2port_c2d_set(struct c2port_device *dev, int status)
72{
73 u8 v;
74
75 mutex_lock(&update_lock);
76
77 v = inb(DATA_PORT);
78
79 if (status)
80 outb(v | C2D, DATA_PORT);
81 else
82 outb(v & ~C2D, DATA_PORT);
83
84 mutex_unlock(&update_lock);
85}
86
87static void duramar2150_c2port_c2ck_set(struct c2port_device *dev, int status)
88{
89 u8 v;
90
91 mutex_lock(&update_lock);
92
93 v = inb(DATA_PORT);
94
95 if (status)
96 outb(v | C2CK, DATA_PORT);
97 else
98 outb(v & ~C2CK, DATA_PORT);
99
100 mutex_unlock(&update_lock);
101}
102
103static struct c2port_ops duramar2150_c2port_ops = {
104 .block_size = 512, /* bytes */
105 .blocks_num = 30, /* total flash size: 15360 bytes */
106
107 .access = duramar2150_c2port_access,
108 .c2d_dir = duramar2150_c2port_c2d_dir,
109 .c2d_get = duramar2150_c2port_c2d_get,
110 .c2d_set = duramar2150_c2port_c2d_set,
111 .c2ck_set = duramar2150_c2port_c2ck_set,
112};
113
114static struct c2port_device *duramar2150_c2port_dev;
115
116/*
117 * Module stuff
118 */
119
120static int __init duramar2150_c2port_init(void)
121{
122 struct resource *res;
123 int ret = 0;
124
125 res = request_region(0x325, 2, "c2port");
126 if (!res)
127 return -EBUSY;
128
129 duramar2150_c2port_dev = c2port_device_register("uc",
130 &duramar2150_c2port_ops, NULL);
131 if (!duramar2150_c2port_dev) {
132 ret = -ENODEV;
133 goto free_region;
134 }
135
136 return 0;
137
138free_region:
139 release_region(0x325, 2);
140 return ret;
141}
142
143static void __exit duramar2150_c2port_exit(void)
144{
145 /* Setup the GPIOs as input by default (access = 0) */
146 duramar2150_c2port_access(duramar2150_c2port_dev, 0);
147
148 c2port_device_unregister(duramar2150_c2port_dev);
149
150 release_region(0x325, 2);
151}
152
153module_init(duramar2150_c2port_init);
154module_exit(duramar2150_c2port_exit);
155
156MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
157MODULE_DESCRIPTION("Silicon Labs C2 port Linux support for Duramar 2150");
158MODULE_LICENSE("GPL");
diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c
new file mode 100644
index 000000000000..976b35d1d035
--- /dev/null
+++ b/drivers/misc/c2port/core.c
@@ -0,0 +1,1002 @@
1/*
2 * Silicon Labs C2 port core Linux support
3 *
4 * Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it>
5 * Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/err.h>
17#include <linux/kernel.h>
18#include <linux/ctype.h>
19#include <linux/delay.h>
20#include <linux/idr.h>
21
22#include <linux/c2port.h>
23
24#define DRIVER_NAME "c2port"
25#define DRIVER_VERSION "0.51.0"
26
27static DEFINE_SPINLOCK(c2port_idr_lock);
28static DEFINE_IDR(c2port_idr);
29
30/*
31 * Local variables
32 */
33
34static struct class *c2port_class;
35
36/*
37 * C2 registers & commands defines
38 */
39
40/* C2 registers */
41#define C2PORT_DEVICEID 0x00
42#define C2PORT_REVID 0x01
43#define C2PORT_FPCTL 0x02
44#define C2PORT_FPDAT 0xB4
45
46/* C2 interface commands */
47#define C2PORT_GET_VERSION 0x01
48#define C2PORT_DEVICE_ERASE 0x03
49#define C2PORT_BLOCK_READ 0x06
50#define C2PORT_BLOCK_WRITE 0x07
51#define C2PORT_PAGE_ERASE 0x08
52
53/* C2 status return codes */
54#define C2PORT_INVALID_COMMAND 0x00
55#define C2PORT_COMMAND_FAILED 0x02
56#define C2PORT_COMMAND_OK 0x0d
57
58/*
59 * C2 port low level signal managements
60 */
61
62static void c2port_reset(struct c2port_device *dev)
63{
64 struct c2port_ops *ops = dev->ops;
65
66 /* To reset the device we have to keep clock line low for at least
67 * 20us.
68 */
69 local_irq_disable();
70 ops->c2ck_set(dev, 0);
71 udelay(25);
72 ops->c2ck_set(dev, 1);
73 local_irq_enable();
74
75 udelay(1);
76}
77
78static void c2port_strobe_ck(struct c2port_device *dev)
79{
80 struct c2port_ops *ops = dev->ops;
81
82 /* During hi-low-hi transition we disable local IRQs to avoid
83 * interructions since C2 port specification says that it must be
84 * shorter than 5us, otherwise the microcontroller may consider
85 * it as a reset signal!
86 */
87 local_irq_disable();
88 ops->c2ck_set(dev, 0);
89 udelay(1);
90 ops->c2ck_set(dev, 1);
91 local_irq_enable();
92
93 udelay(1);
94}
95
96/*
97 * C2 port basic functions
98 */
99
100static void c2port_write_ar(struct c2port_device *dev, u8 addr)
101{
102 struct c2port_ops *ops = dev->ops;
103 int i;
104
105 /* START field */
106 c2port_strobe_ck(dev);
107
108 /* INS field (11b, LSB first) */
109 ops->c2d_dir(dev, 0);
110 ops->c2d_set(dev, 1);
111 c2port_strobe_ck(dev);
112 ops->c2d_set(dev, 1);
113 c2port_strobe_ck(dev);
114
115 /* ADDRESS field */
116 for (i = 0; i < 8; i++) {
117 ops->c2d_set(dev, addr & 0x01);
118 c2port_strobe_ck(dev);
119
120 addr >>= 1;
121 }
122
123 /* STOP field */
124 ops->c2d_dir(dev, 1);
125 c2port_strobe_ck(dev);
126}
127
128static int c2port_read_ar(struct c2port_device *dev, u8 *addr)
129{
130 struct c2port_ops *ops = dev->ops;
131 int i;
132
133 /* START field */
134 c2port_strobe_ck(dev);
135
136 /* INS field (10b, LSB first) */
137 ops->c2d_dir(dev, 0);
138 ops->c2d_set(dev, 0);
139 c2port_strobe_ck(dev);
140 ops->c2d_set(dev, 1);
141 c2port_strobe_ck(dev);
142
143 /* ADDRESS field */
144 ops->c2d_dir(dev, 1);
145 *addr = 0;
146 for (i = 0; i < 8; i++) {
147 *addr >>= 1; /* shift in 8-bit ADDRESS field LSB first */
148
149 c2port_strobe_ck(dev);
150 if (ops->c2d_get(dev))
151 *addr |= 0x80;
152 }
153
154 /* STOP field */
155 c2port_strobe_ck(dev);
156
157 return 0;
158}
159
160static int c2port_write_dr(struct c2port_device *dev, u8 data)
161{
162 struct c2port_ops *ops = dev->ops;
163 int timeout, i;
164
165 /* START field */
166 c2port_strobe_ck(dev);
167
168 /* INS field (01b, LSB first) */
169 ops->c2d_dir(dev, 0);
170 ops->c2d_set(dev, 1);
171 c2port_strobe_ck(dev);
172 ops->c2d_set(dev, 0);
173 c2port_strobe_ck(dev);
174
175 /* LENGTH field (00b, LSB first -> 1 byte) */
176 ops->c2d_set(dev, 0);
177 c2port_strobe_ck(dev);
178 ops->c2d_set(dev, 0);
179 c2port_strobe_ck(dev);
180
181 /* DATA field */
182 for (i = 0; i < 8; i++) {
183 ops->c2d_set(dev, data & 0x01);
184 c2port_strobe_ck(dev);
185
186 data >>= 1;
187 }
188
189 /* WAIT field */
190 ops->c2d_dir(dev, 1);
191 timeout = 20;
192 do {
193 c2port_strobe_ck(dev);
194 if (ops->c2d_get(dev))
195 break;
196
197 udelay(1);
198 } while (--timeout > 0);
199 if (timeout == 0)
200 return -EIO;
201
202 /* STOP field */
203 c2port_strobe_ck(dev);
204
205 return 0;
206}
207
208static int c2port_read_dr(struct c2port_device *dev, u8 *data)
209{
210 struct c2port_ops *ops = dev->ops;
211 int timeout, i;
212
213 /* START field */
214 c2port_strobe_ck(dev);
215
216 /* INS field (00b, LSB first) */
217 ops->c2d_dir(dev, 0);
218 ops->c2d_set(dev, 0);
219 c2port_strobe_ck(dev);
220 ops->c2d_set(dev, 0);
221 c2port_strobe_ck(dev);
222
223 /* LENGTH field (00b, LSB first -> 1 byte) */
224 ops->c2d_set(dev, 0);
225 c2port_strobe_ck(dev);
226 ops->c2d_set(dev, 0);
227 c2port_strobe_ck(dev);
228
229 /* WAIT field */
230 ops->c2d_dir(dev, 1);
231 timeout = 20;
232 do {
233 c2port_strobe_ck(dev);
234 if (ops->c2d_get(dev))
235 break;
236
237 udelay(1);
238 } while (--timeout > 0);
239 if (timeout == 0)
240 return -EIO;
241
242 /* DATA field */
243 *data = 0;
244 for (i = 0; i < 8; i++) {
245 *data >>= 1; /* shift in 8-bit DATA field LSB first */
246
247 c2port_strobe_ck(dev);
248 if (ops->c2d_get(dev))
249 *data |= 0x80;
250 }
251
252 /* STOP field */
253 c2port_strobe_ck(dev);
254
255 return 0;
256}
257
258static int c2port_poll_in_busy(struct c2port_device *dev)
259{
260 u8 addr;
261 int ret, timeout = 20;
262
263 do {
264 ret = (c2port_read_ar(dev, &addr));
265 if (ret < 0)
266 return -EIO;
267
268 if (!(addr & 0x02))
269 break;
270
271 udelay(1);
272 } while (--timeout > 0);
273 if (timeout == 0)
274 return -EIO;
275
276 return 0;
277}
278
279static int c2port_poll_out_ready(struct c2port_device *dev)
280{
281 u8 addr;
282 int ret, timeout = 10000; /* erase flash needs long time... */
283
284 do {
285 ret = (c2port_read_ar(dev, &addr));
286 if (ret < 0)
287 return -EIO;
288
289 if (addr & 0x01)
290 break;
291
292 udelay(1);
293 } while (--timeout > 0);
294 if (timeout == 0)
295 return -EIO;
296
297 return 0;
298}
299
300/*
301 * sysfs methods
302 */
303
304static ssize_t c2port_show_name(struct device *dev,
305 struct device_attribute *attr, char *buf)
306{
307 struct c2port_device *c2dev = dev_get_drvdata(dev);
308
309 return sprintf(buf, "%s\n", c2dev->name);
310}
311
312static ssize_t c2port_show_flash_blocks_num(struct device *dev,
313 struct device_attribute *attr, char *buf)
314{
315 struct c2port_device *c2dev = dev_get_drvdata(dev);
316 struct c2port_ops *ops = c2dev->ops;
317
318 return sprintf(buf, "%d\n", ops->blocks_num);
319}
320
321static ssize_t c2port_show_flash_block_size(struct device *dev,
322 struct device_attribute *attr, char *buf)
323{
324 struct c2port_device *c2dev = dev_get_drvdata(dev);
325 struct c2port_ops *ops = c2dev->ops;
326
327 return sprintf(buf, "%d\n", ops->block_size);
328}
329
330static ssize_t c2port_show_flash_size(struct device *dev,
331 struct device_attribute *attr, char *buf)
332{
333 struct c2port_device *c2dev = dev_get_drvdata(dev);
334 struct c2port_ops *ops = c2dev->ops;
335
336 return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
337}
338
339static ssize_t c2port_show_access(struct device *dev,
340 struct device_attribute *attr, char *buf)
341{
342 struct c2port_device *c2dev = dev_get_drvdata(dev);
343
344 return sprintf(buf, "%d\n", c2dev->access);
345}
346
347static ssize_t c2port_store_access(struct device *dev,
348 struct device_attribute *attr,
349 const char *buf, size_t count)
350{
351 struct c2port_device *c2dev = dev_get_drvdata(dev);
352 struct c2port_ops *ops = c2dev->ops;
353 int status, ret;
354
355 ret = sscanf(buf, "%d", &status);
356 if (ret != 1)
357 return -EINVAL;
358
359 mutex_lock(&c2dev->mutex);
360
361 c2dev->access = !!status;
362
363 /* If access is "on" clock should be HIGH _before_ setting the line
364 * as output and data line should be set as INPUT anyway */
365 if (c2dev->access)
366 ops->c2ck_set(c2dev, 1);
367 ops->access(c2dev, c2dev->access);
368 if (c2dev->access)
369 ops->c2d_dir(c2dev, 1);
370
371 mutex_unlock(&c2dev->mutex);
372
373 return count;
374}
375
376static ssize_t c2port_store_reset(struct device *dev,
377 struct device_attribute *attr,
378 const char *buf, size_t count)
379{
380 struct c2port_device *c2dev = dev_get_drvdata(dev);
381
382 /* Check the device access status */
383 if (!c2dev->access)
384 return -EBUSY;
385
386 mutex_lock(&c2dev->mutex);
387
388 c2port_reset(c2dev);
389 c2dev->flash_access = 0;
390
391 mutex_unlock(&c2dev->mutex);
392
393 return count;
394}
395
396static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
397{
398 u8 data;
399 int ret;
400
401 /* Select DEVICEID register for C2 data register accesses */
402 c2port_write_ar(dev, C2PORT_DEVICEID);
403
404 /* Read and return the device ID register */
405 ret = c2port_read_dr(dev, &data);
406 if (ret < 0)
407 return ret;
408
409 return sprintf(buf, "%d\n", data);
410}
411
412static ssize_t c2port_show_dev_id(struct device *dev,
413 struct device_attribute *attr, char *buf)
414{
415 struct c2port_device *c2dev = dev_get_drvdata(dev);
416 ssize_t ret;
417
418 /* Check the device access status */
419 if (!c2dev->access)
420 return -EBUSY;
421
422 mutex_lock(&c2dev->mutex);
423 ret = __c2port_show_dev_id(c2dev, buf);
424 mutex_unlock(&c2dev->mutex);
425
426 if (ret < 0)
427 dev_err(dev, "cannot read from %s\n", c2dev->name);
428
429 return ret;
430}
431
432static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
433{
434 u8 data;
435 int ret;
436
437 /* Select REVID register for C2 data register accesses */
438 c2port_write_ar(dev, C2PORT_REVID);
439
440 /* Read and return the revision ID register */
441 ret = c2port_read_dr(dev, &data);
442 if (ret < 0)
443 return ret;
444
445 return sprintf(buf, "%d\n", data);
446}
447
448static ssize_t c2port_show_rev_id(struct device *dev,
449 struct device_attribute *attr, char *buf)
450{
451 struct c2port_device *c2dev = dev_get_drvdata(dev);
452 ssize_t ret;
453
454 /* Check the device access status */
455 if (!c2dev->access)
456 return -EBUSY;
457
458 mutex_lock(&c2dev->mutex);
459 ret = __c2port_show_rev_id(c2dev, buf);
460 mutex_unlock(&c2dev->mutex);
461
462 if (ret < 0)
463 dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name);
464
465 return ret;
466}
467
468static ssize_t c2port_show_flash_access(struct device *dev,
469 struct device_attribute *attr, char *buf)
470{
471 struct c2port_device *c2dev = dev_get_drvdata(dev);
472
473 return sprintf(buf, "%d\n", c2dev->flash_access);
474}
475
476static ssize_t __c2port_store_flash_access(struct c2port_device *dev,
477 int status)
478{
479 int ret;
480
481 /* Check the device access status */
482 if (!dev->access)
483 return -EBUSY;
484
485 dev->flash_access = !!status;
486
487 /* If flash_access is off we have nothing to do... */
488 if (dev->flash_access == 0)
489 return 0;
490
491 /* Target the C2 flash programming control register for C2 data
492 * register access */
493 c2port_write_ar(dev, C2PORT_FPCTL);
494
495 /* Write the first keycode to enable C2 Flash programming */
496 ret = c2port_write_dr(dev, 0x02);
497 if (ret < 0)
498 return ret;
499
500 /* Write the second keycode to enable C2 Flash programming */
501 ret = c2port_write_dr(dev, 0x01);
502 if (ret < 0)
503 return ret;
504
505 /* Delay for at least 20ms to ensure the target is ready for
506 * C2 flash programming */
507 mdelay(25);
508
509 return 0;
510}
511
512static ssize_t c2port_store_flash_access(struct device *dev,
513 struct device_attribute *attr,
514 const char *buf, size_t count)
515{
516 struct c2port_device *c2dev = dev_get_drvdata(dev);
517 int status;
518 ssize_t ret;
519
520 ret = sscanf(buf, "%d", &status);
521 if (ret != 1)
522 return -EINVAL;
523
524 mutex_lock(&c2dev->mutex);
525 ret = __c2port_store_flash_access(c2dev, status);
526 mutex_unlock(&c2dev->mutex);
527
528 if (ret < 0) {
529 dev_err(c2dev->dev, "cannot enable %s flash programming\n",
530 c2dev->name);
531 return ret;
532 }
533
534 return count;
535}
536
537static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
538{
539 u8 status;
540 int ret;
541
542 /* Target the C2 flash programming data register for C2 data register
543 * access.
544 */
545 c2port_write_ar(dev, C2PORT_FPDAT);
546
547 /* Send device erase command */
548 c2port_write_dr(dev, C2PORT_DEVICE_ERASE);
549
550 /* Wait for input acknowledge */
551 ret = c2port_poll_in_busy(dev);
552 if (ret < 0)
553 return ret;
554
555 /* Should check status before starting FLASH access sequence */
556
557 /* Wait for status information */
558 ret = c2port_poll_out_ready(dev);
559 if (ret < 0)
560 return ret;
561
562 /* Read flash programming interface status */
563 ret = c2port_read_dr(dev, &status);
564 if (ret < 0)
565 return ret;
566 if (status != C2PORT_COMMAND_OK)
567 return -EBUSY;
568
569 /* Send a three-byte arming sequence to enable the device erase.
570 * If the sequence is not received correctly, the command will be
571 * ignored.
572 * Sequence is: 0xde, 0xad, 0xa5.
573 */
574 c2port_write_dr(dev, 0xde);
575 ret = c2port_poll_in_busy(dev);
576 if (ret < 0)
577 return ret;
578 c2port_write_dr(dev, 0xad);
579 ret = c2port_poll_in_busy(dev);
580 if (ret < 0)
581 return ret;
582 c2port_write_dr(dev, 0xa5);
583 ret = c2port_poll_in_busy(dev);
584 if (ret < 0)
585 return ret;
586
587 ret = c2port_poll_out_ready(dev);
588 if (ret < 0)
589 return ret;
590
591 return 0;
592}
593
594static ssize_t c2port_store_flash_erase(struct device *dev,
595 struct device_attribute *attr,
596 const char *buf, size_t count)
597{
598 struct c2port_device *c2dev = dev_get_drvdata(dev);
599 int ret;
600
601 /* Check the device and flash access status */
602 if (!c2dev->access || !c2dev->flash_access)
603 return -EBUSY;
604
605 mutex_lock(&c2dev->mutex);
606 ret = __c2port_write_flash_erase(c2dev);
607 mutex_unlock(&c2dev->mutex);
608
609 if (ret < 0) {
610 dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name);
611 return ret;
612 }
613
614 return count;
615}
616
617static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
618 char *buffer, loff_t offset, size_t count)
619{
620 struct c2port_ops *ops = dev->ops;
621 u8 status, nread = 128;
622 int i, ret;
623
624 /* Check for flash end */
625 if (offset >= ops->block_size * ops->blocks_num)
626 return 0;
627
628 if (ops->block_size * ops->blocks_num - offset < nread)
629 nread = ops->block_size * ops->blocks_num - offset;
630 if (count < nread)
631 nread = count;
632 if (nread == 0)
633 return nread;
634
635 /* Target the C2 flash programming data register for C2 data register
636 * access */
637 c2port_write_ar(dev, C2PORT_FPDAT);
638
639 /* Send flash block read command */
640 c2port_write_dr(dev, C2PORT_BLOCK_READ);
641
642 /* Wait for input acknowledge */
643 ret = c2port_poll_in_busy(dev);
644 if (ret < 0)
645 return ret;
646
647 /* Should check status before starting FLASH access sequence */
648
649 /* Wait for status information */
650 ret = c2port_poll_out_ready(dev);
651 if (ret < 0)
652 return ret;
653
654 /* Read flash programming interface status */
655 ret = c2port_read_dr(dev, &status);
656 if (ret < 0)
657 return ret;
658 if (status != C2PORT_COMMAND_OK)
659 return -EBUSY;
660
661 /* Send address high byte */
662 c2port_write_dr(dev, offset >> 8);
663 ret = c2port_poll_in_busy(dev);
664 if (ret < 0)
665 return ret;
666
667 /* Send address low byte */
668 c2port_write_dr(dev, offset & 0x00ff);
669 ret = c2port_poll_in_busy(dev);
670 if (ret < 0)
671 return ret;
672
673 /* Send address block size */
674 c2port_write_dr(dev, nread);
675 ret = c2port_poll_in_busy(dev);
676 if (ret < 0)
677 return ret;
678
679 /* Should check status before reading FLASH block */
680
681 /* Wait for status information */
682 ret = c2port_poll_out_ready(dev);
683 if (ret < 0)
684 return ret;
685
686 /* Read flash programming interface status */
687 ret = c2port_read_dr(dev, &status);
688 if (ret < 0)
689 return ret;
690 if (status != C2PORT_COMMAND_OK)
691 return -EBUSY;
692
693 /* Read flash block */
694 for (i = 0; i < nread; i++) {
695 ret = c2port_poll_out_ready(dev);
696 if (ret < 0)
697 return ret;
698
699 ret = c2port_read_dr(dev, buffer+i);
700 if (ret < 0)
701 return ret;
702 }
703
704 return nread;
705}
706
707static ssize_t c2port_read_flash_data(struct kobject *kobj,
708 struct bin_attribute *attr,
709 char *buffer, loff_t offset, size_t count)
710{
711 struct c2port_device *c2dev =
712 dev_get_drvdata(container_of(kobj,
713 struct device, kobj));
714 ssize_t ret;
715
716 /* Check the device and flash access status */
717 if (!c2dev->access || !c2dev->flash_access)
718 return -EBUSY;
719
720 mutex_lock(&c2dev->mutex);
721 ret = __c2port_read_flash_data(c2dev, buffer, offset, count);
722 mutex_unlock(&c2dev->mutex);
723
724 if (ret < 0)
725 dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name);
726
727 return ret;
728}
729
730static ssize_t __c2port_write_flash_data(struct c2port_device *dev,
731 char *buffer, loff_t offset, size_t count)
732{
733 struct c2port_ops *ops = dev->ops;
734 u8 status, nwrite = 128;
735 int i, ret;
736
737 if (nwrite > count)
738 nwrite = count;
739 if (ops->block_size * ops->blocks_num - offset < nwrite)
740 nwrite = ops->block_size * ops->blocks_num - offset;
741
742 /* Check for flash end */
743 if (offset >= ops->block_size * ops->blocks_num)
744 return -EINVAL;
745
746 /* Target the C2 flash programming data register for C2 data register
747 * access */
748 c2port_write_ar(dev, C2PORT_FPDAT);
749
750 /* Send flash block write command */
751 c2port_write_dr(dev, C2PORT_BLOCK_WRITE);
752
753 /* Wait for input acknowledge */
754 ret = c2port_poll_in_busy(dev);
755 if (ret < 0)
756 return ret;
757
758 /* Should check status before starting FLASH access sequence */
759
760 /* Wait for status information */
761 ret = c2port_poll_out_ready(dev);
762 if (ret < 0)
763 return ret;
764
765 /* Read flash programming interface status */
766 ret = c2port_read_dr(dev, &status);
767 if (ret < 0)
768 return ret;
769 if (status != C2PORT_COMMAND_OK)
770 return -EBUSY;
771
772 /* Send address high byte */
773 c2port_write_dr(dev, offset >> 8);
774 ret = c2port_poll_in_busy(dev);
775 if (ret < 0)
776 return ret;
777
778 /* Send address low byte */
779 c2port_write_dr(dev, offset & 0x00ff);
780 ret = c2port_poll_in_busy(dev);
781 if (ret < 0)
782 return ret;
783
784 /* Send address block size */
785 c2port_write_dr(dev, nwrite);
786 ret = c2port_poll_in_busy(dev);
787 if (ret < 0)
788 return ret;
789
790 /* Should check status before writing FLASH block */
791
792 /* Wait for status information */
793 ret = c2port_poll_out_ready(dev);
794 if (ret < 0)
795 return ret;
796
797 /* Read flash programming interface status */
798 ret = c2port_read_dr(dev, &status);
799 if (ret < 0)
800 return ret;
801 if (status != C2PORT_COMMAND_OK)
802 return -EBUSY;
803
804 /* Write flash block */
805 for (i = 0; i < nwrite; i++) {
806 ret = c2port_write_dr(dev, *(buffer+i));
807 if (ret < 0)
808 return ret;
809
810 ret = c2port_poll_in_busy(dev);
811 if (ret < 0)
812 return ret;
813
814 }
815
816 /* Wait for last flash write to complete */
817 ret = c2port_poll_out_ready(dev);
818 if (ret < 0)
819 return ret;
820
821 return nwrite;
822}
823
824static ssize_t c2port_write_flash_data(struct kobject *kobj,
825 struct bin_attribute *attr,
826 char *buffer, loff_t offset, size_t count)
827{
828 struct c2port_device *c2dev =
829 dev_get_drvdata(container_of(kobj,
830 struct device, kobj));
831 int ret;
832
833 /* Check the device access status */
834 if (!c2dev->access || !c2dev->flash_access)
835 return -EBUSY;
836
837 mutex_lock(&c2dev->mutex);
838 ret = __c2port_write_flash_data(c2dev, buffer, offset, count);
839 mutex_unlock(&c2dev->mutex);
840
841 if (ret < 0)
842 dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name);
843
844 return ret;
845}
846
847/*
848 * Class attributes
849 */
850
851static struct device_attribute c2port_attrs[] = {
852 __ATTR(name, 0444, c2port_show_name, NULL),
853 __ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL),
854 __ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL),
855 __ATTR(flash_size, 0444, c2port_show_flash_size, NULL),
856 __ATTR(access, 0644, c2port_show_access, c2port_store_access),
857 __ATTR(reset, 0200, NULL, c2port_store_reset),
858 __ATTR(dev_id, 0444, c2port_show_dev_id, NULL),
859 __ATTR(rev_id, 0444, c2port_show_rev_id, NULL),
860
861 __ATTR(flash_access, 0644, c2port_show_flash_access,
862 c2port_store_flash_access),
863 __ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase),
864 __ATTR_NULL,
865};
866
867static struct bin_attribute c2port_bin_attrs = {
868 .attr = {
869 .name = "flash_data",
870 .mode = 0644
871 },
872 .read = c2port_read_flash_data,
873 .write = c2port_write_flash_data,
874 /* .size is computed at run-time */
875};
876
877/*
878 * Exported functions
879 */
880
881struct c2port_device *c2port_device_register(char *name,
882 struct c2port_ops *ops, void *devdata)
883{
884 struct c2port_device *c2dev;
885 int id, ret;
886
887 if (unlikely(!ops) || unlikely(!ops->access) || \
888 unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
889 unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set))
890 return ERR_PTR(-EINVAL);
891
892 c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL);
893 if (unlikely(!c2dev))
894 return ERR_PTR(-ENOMEM);
895
896 ret = idr_pre_get(&c2port_idr, GFP_KERNEL);
897 if (!ret) {
898 ret = -ENOMEM;
899 goto error_idr_get_new;
900 }
901
902 spin_lock_irq(&c2port_idr_lock);
903 ret = idr_get_new(&c2port_idr, c2dev, &id);
904 spin_unlock_irq(&c2port_idr_lock);
905
906 if (ret < 0)
907 goto error_idr_get_new;
908 c2dev->id = id;
909
910 c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
911 "c2port%d", id);
912 if (unlikely(!c2dev->dev)) {
913 ret = -ENOMEM;
914 goto error_device_create;
915 }
916 dev_set_drvdata(c2dev->dev, c2dev);
917
918 strncpy(c2dev->name, name, C2PORT_NAME_LEN);
919 c2dev->ops = ops;
920 mutex_init(&c2dev->mutex);
921
922 /* Create binary file */
923 c2port_bin_attrs.size = ops->blocks_num * ops->block_size;
924 ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs);
925 if (unlikely(ret))
926 goto error_device_create_bin_file;
927
928 /* By default C2 port access is off */
929 c2dev->access = c2dev->flash_access = 0;
930 ops->access(c2dev, 0);
931
932 dev_info(c2dev->dev, "C2 port %s added\n", name);
933 dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes "
934 "(%d bytes total)\n",
935 name, ops->blocks_num, ops->block_size,
936 ops->blocks_num * ops->block_size);
937
938 return c2dev;
939
940error_device_create_bin_file:
941 device_destroy(c2port_class, 0);
942
943error_device_create:
944 spin_lock_irq(&c2port_idr_lock);
945 idr_remove(&c2port_idr, id);
946 spin_unlock_irq(&c2port_idr_lock);
947
948error_idr_get_new:
949 kfree(c2dev);
950
951 return ERR_PTR(ret);
952}
953EXPORT_SYMBOL(c2port_device_register);
954
955void c2port_device_unregister(struct c2port_device *c2dev)
956{
957 if (!c2dev)
958 return;
959
960 dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
961
962 device_remove_bin_file(c2dev->dev, &c2port_bin_attrs);
963 spin_lock_irq(&c2port_idr_lock);
964 idr_remove(&c2port_idr, c2dev->id);
965 spin_unlock_irq(&c2port_idr_lock);
966
967 device_destroy(c2port_class, c2dev->id);
968
969 kfree(c2dev);
970}
971EXPORT_SYMBOL(c2port_device_unregister);
972
973/*
974 * Module stuff
975 */
976
977static int __init c2port_init(void)
978{
979 printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION
980 " - (C) 2007 Rodolfo Giometti\n");
981
982 c2port_class = class_create(THIS_MODULE, "c2port");
983 if (!c2port_class) {
984 printk(KERN_ERR "c2port: failed to allocate class\n");
985 return -ENOMEM;
986 }
987 c2port_class->dev_attrs = c2port_attrs;
988
989 return 0;
990}
991
992static void __exit c2port_exit(void)
993{
994 class_destroy(c2port_class);
995}
996
997module_init(c2port_init);
998module_exit(c2port_exit);
999
1000MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
1001MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION);
1002MODULE_LICENSE("GPL");
diff --git a/drivers/misc/compal-laptop.c b/drivers/misc/compal-laptop.c
index 344b790a6253..11003bba10d3 100644
--- a/drivers/misc/compal-laptop.c
+++ b/drivers/misc/compal-laptop.c
@@ -326,12 +326,14 @@ static int __init compal_init(void)
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)
diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c
index 9ef98b2d5039..02fe2b8b8939 100644
--- a/drivers/misc/eeepc-laptop.c
+++ b/drivers/misc/eeepc-laptop.c
@@ -825,9 +825,15 @@ static int __init eeepc_laptop_init(void)
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;
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c
index d2cf0bfe3163..a7dd3e9fb79d 100644
--- a/drivers/misc/fujitsu-laptop.c
+++ b/drivers/misc/fujitsu-laptop.c
@@ -464,6 +464,14 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id)
464 return 0; 464 return 0;
465} 465}
466 466
467static int dmi_check_cb_s6420(const struct dmi_system_id *id)
468{
469 dmi_check_cb_common(id);
470 fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */
471 fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */
472 return 0;
473}
474
467static int dmi_check_cb_p8010(const struct dmi_system_id *id) 475static int dmi_check_cb_p8010(const struct dmi_system_id *id)
468{ 476{
469 dmi_check_cb_common(id); 477 dmi_check_cb_common(id);
@@ -473,7 +481,7 @@ static int dmi_check_cb_p8010(const struct dmi_system_id *id)
473 return 0; 481 return 0;
474} 482}
475 483
476static struct dmi_system_id __initdata fujitsu_dmi_table[] = { 484static struct dmi_system_id fujitsu_dmi_table[] = {
477 { 485 {
478 .ident = "Fujitsu Siemens S6410", 486 .ident = "Fujitsu Siemens S6410",
479 .matches = { 487 .matches = {
@@ -482,6 +490,13 @@ static struct dmi_system_id __initdata fujitsu_dmi_table[] = {
482 }, 490 },
483 .callback = dmi_check_cb_s6410}, 491 .callback = dmi_check_cb_s6410},
484 { 492 {
493 .ident = "Fujitsu Siemens S6420",
494 .matches = {
495 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
496 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6420"),
497 },
498 .callback = dmi_check_cb_s6420},
499 {
485 .ident = "Fujitsu LifeBook P8010", 500 .ident = "Fujitsu LifeBook P8010",
486 .matches = { 501 .matches = {
487 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 502 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
@@ -990,16 +1005,16 @@ static int __init fujitsu_init(void)
990 1005
991 /* Register backlight stuff */ 1006 /* Register backlight stuff */
992 1007
993 fujitsu->bl_device = 1008 if (!acpi_video_backlight_support()) {
994 backlight_device_register("fujitsu-laptop", NULL, NULL, 1009 fujitsu->bl_device =
995 &fujitsubl_ops); 1010 backlight_device_register("fujitsu-laptop", NULL, NULL,
996 if (IS_ERR(fujitsu->bl_device)) 1011 &fujitsubl_ops);
997 return PTR_ERR(fujitsu->bl_device); 1012 if (IS_ERR(fujitsu->bl_device))
998 1013 return PTR_ERR(fujitsu->bl_device);
999 max_brightness = fujitsu->max_brightness; 1014 max_brightness = fujitsu->max_brightness;
1000 1015 fujitsu->bl_device->props.max_brightness = max_brightness - 1;
1001 fujitsu->bl_device->props.max_brightness = max_brightness - 1; 1016 fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
1002 fujitsu->bl_device->props.brightness = fujitsu->brightness_level; 1017 }
1003 1018
1004 ret = platform_driver_register(&fujitsupf_driver); 1019 ret = platform_driver_register(&fujitsupf_driver);
1005 if (ret) 1020 if (ret)
@@ -1035,7 +1050,8 @@ fail_hotkey:
1035 1050
1036fail_backlight: 1051fail_backlight:
1037 1052
1038 backlight_device_unregister(fujitsu->bl_device); 1053 if (fujitsu->bl_device)
1054 backlight_device_unregister(fujitsu->bl_device);
1039 1055
1040fail_platform_device2: 1056fail_platform_device2:
1041 1057
@@ -1062,7 +1078,8 @@ static void __exit fujitsu_cleanup(void)
1062 &fujitsupf_attribute_group); 1078 &fujitsupf_attribute_group);
1063 platform_device_unregister(fujitsu->pf_device); 1079 platform_device_unregister(fujitsu->pf_device);
1064 platform_driver_unregister(&fujitsupf_driver); 1080 platform_driver_unregister(&fujitsupf_driver);
1065 backlight_device_unregister(fujitsu->bl_device); 1081 if (fujitsu->bl_device)
1082 backlight_device_unregister(fujitsu->bl_device);
1066 1083
1067 acpi_bus_unregister_driver(&acpi_fujitsu_driver); 1084 acpi_bus_unregister_driver(&acpi_fujitsu_driver);
1068 1085
diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c
new file mode 100644
index 000000000000..6e43ab4231ae
--- /dev/null
+++ b/drivers/misc/ics932s401.c
@@ -0,0 +1,515 @@
1/*
2 * A driver for the Integrated Circuits ICS932S401
3 * Copyright (C) 2008 IBM
4 *
5 * Author: Darrick J. Wong <djwong@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/module.h>
23#include <linux/jiffies.h>
24#include <linux/i2c.h>
25#include <linux/err.h>
26#include <linux/mutex.h>
27#include <linux/delay.h>
28#include <linux/log2.h>
29
30/* Addresses to scan */
31static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END };
32
33/* Insmod parameters */
34I2C_CLIENT_INSMOD_1(ics932s401);
35
36/* ICS932S401 registers */
37#define ICS932S401_REG_CFG2 0x01
38#define ICS932S401_CFG1_SPREAD 0x01
39#define ICS932S401_REG_CFG7 0x06
40#define ICS932S401_FS_MASK 0x07
41#define ICS932S401_REG_VENDOR_REV 0x07
42#define ICS932S401_VENDOR 1
43#define ICS932S401_VENDOR_MASK 0x0F
44#define ICS932S401_REV 4
45#define ICS932S401_REV_SHIFT 4
46#define ICS932S401_REG_DEVICE 0x09
47#define ICS932S401_DEVICE 11
48#define ICS932S401_REG_CTRL 0x0A
49#define ICS932S401_MN_ENABLED 0x80
50#define ICS932S401_CPU_ALT 0x04
51#define ICS932S401_SRC_ALT 0x08
52#define ICS932S401_REG_CPU_M_CTRL 0x0B
53#define ICS932S401_M_MASK 0x3F
54#define ICS932S401_REG_CPU_N_CTRL 0x0C
55#define ICS932S401_REG_CPU_SPREAD1 0x0D
56#define ICS932S401_REG_CPU_SPREAD2 0x0E
57#define ICS932S401_SPREAD_MASK 0x7FFF
58#define ICS932S401_REG_SRC_M_CTRL 0x0F
59#define ICS932S401_REG_SRC_N_CTRL 0x10
60#define ICS932S401_REG_SRC_SPREAD1 0x11
61#define ICS932S401_REG_SRC_SPREAD2 0x12
62#define ICS932S401_REG_CPU_DIVISOR 0x13
63#define ICS932S401_CPU_DIVISOR_SHIFT 4
64#define ICS932S401_REG_PCISRC_DIVISOR 0x14
65#define ICS932S401_SRC_DIVISOR_MASK 0x0F
66#define ICS932S401_PCI_DIVISOR_SHIFT 4
67
68/* Base clock is 14.318MHz */
69#define BASE_CLOCK 14318
70
71#define NUM_REGS 21
72#define NUM_MIRRORED_REGS 15
73
74static int regs_to_copy[NUM_MIRRORED_REGS] = {
75 ICS932S401_REG_CFG2,
76 ICS932S401_REG_CFG7,
77 ICS932S401_REG_VENDOR_REV,
78 ICS932S401_REG_DEVICE,
79 ICS932S401_REG_CTRL,
80 ICS932S401_REG_CPU_M_CTRL,
81 ICS932S401_REG_CPU_N_CTRL,
82 ICS932S401_REG_CPU_SPREAD1,
83 ICS932S401_REG_CPU_SPREAD2,
84 ICS932S401_REG_SRC_M_CTRL,
85 ICS932S401_REG_SRC_N_CTRL,
86 ICS932S401_REG_SRC_SPREAD1,
87 ICS932S401_REG_SRC_SPREAD2,
88 ICS932S401_REG_CPU_DIVISOR,
89 ICS932S401_REG_PCISRC_DIVISOR,
90};
91
92/* How often do we reread sensors values? (In jiffies) */
93#define SENSOR_REFRESH_INTERVAL (2 * HZ)
94
95/* How often do we reread sensor limit values? (In jiffies) */
96#define LIMIT_REFRESH_INTERVAL (60 * HZ)
97
98struct ics932s401_data {
99 struct attribute_group attrs;
100 struct mutex lock;
101 char sensors_valid;
102 unsigned long sensors_last_updated; /* In jiffies */
103
104 u8 regs[NUM_REGS];
105};
106
107static int ics932s401_probe(struct i2c_client *client,
108 const struct i2c_device_id *id);
109static int ics932s401_detect(struct i2c_client *client, int kind,
110 struct i2c_board_info *info);
111static int ics932s401_remove(struct i2c_client *client);
112
113static const struct i2c_device_id ics932s401_id[] = {
114 { "ics932s401", ics932s401 },
115 { }
116};
117MODULE_DEVICE_TABLE(i2c, ics932s401_id);
118
119static struct i2c_driver ics932s401_driver = {
120 .class = I2C_CLASS_HWMON,
121 .driver = {
122 .name = "ics932s401",
123 },
124 .probe = ics932s401_probe,
125 .remove = ics932s401_remove,
126 .id_table = ics932s401_id,
127 .detect = ics932s401_detect,
128 .address_data = &addr_data,
129};
130
131static struct ics932s401_data *ics932s401_update_device(struct device *dev)
132{
133 struct i2c_client *client = to_i2c_client(dev);
134 struct ics932s401_data *data = i2c_get_clientdata(client);
135 unsigned long local_jiffies = jiffies;
136 int i, temp;
137
138 mutex_lock(&data->lock);
139 if (time_before(local_jiffies, data->sensors_last_updated +
140 SENSOR_REFRESH_INTERVAL)
141 && data->sensors_valid)
142 goto out;
143
144 /*
145 * Each register must be read as a word and then right shifted 8 bits.
146 * Not really sure why this is; setting the "byte count programming"
147 * register to 1 does not fix this problem.
148 */
149 for (i = 0; i < NUM_MIRRORED_REGS; i++) {
150 temp = i2c_smbus_read_word_data(client, regs_to_copy[i]);
151 data->regs[regs_to_copy[i]] = temp >> 8;
152 }
153
154 data->sensors_last_updated = local_jiffies;
155 data->sensors_valid = 1;
156
157out:
158 mutex_unlock(&data->lock);
159 return data;
160}
161
162static ssize_t show_spread_enabled(struct device *dev,
163 struct device_attribute *devattr,
164 char *buf)
165{
166 struct ics932s401_data *data = ics932s401_update_device(dev);
167
168 if (data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD)
169 return sprintf(buf, "1\n");
170
171 return sprintf(buf, "0\n");
172}
173
174/* bit to cpu khz map */
175static const int fs_speeds[] = {
176 266666,
177 133333,
178 200000,
179 166666,
180 333333,
181 100000,
182 400000,
183 0,
184};
185
186/* clock divisor map */
187static const int divisors[] = {2, 3, 5, 15, 4, 6, 10, 30, 8, 12, 20, 60, 16,
188 24, 40, 120};
189
190/* Calculate CPU frequency from the M/N registers. */
191static int calculate_cpu_freq(struct ics932s401_data *data)
192{
193 int m, n, freq;
194
195 m = data->regs[ICS932S401_REG_CPU_M_CTRL] & ICS932S401_M_MASK;
196 n = data->regs[ICS932S401_REG_CPU_N_CTRL];
197
198 /* Pull in bits 8 & 9 from the M register */
199 n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x80) << 1;
200 n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x40) << 3;
201
202 freq = BASE_CLOCK * (n + 8) / (m + 2);
203 freq /= divisors[data->regs[ICS932S401_REG_CPU_DIVISOR] >>
204 ICS932S401_CPU_DIVISOR_SHIFT];
205
206 return freq;
207}
208
209static ssize_t show_cpu_clock(struct device *dev,
210 struct device_attribute *devattr,
211 char *buf)
212{
213 struct ics932s401_data *data = ics932s401_update_device(dev);
214
215 return sprintf(buf, "%d\n", calculate_cpu_freq(data));
216}
217
218static ssize_t show_cpu_clock_sel(struct device *dev,
219 struct device_attribute *devattr,
220 char *buf)
221{
222 struct ics932s401_data *data = ics932s401_update_device(dev);
223 int freq;
224
225 if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)
226 freq = calculate_cpu_freq(data);
227 else {
228 /* Freq is neatly wrapped up for us */
229 int fid = data->regs[ICS932S401_REG_CFG7] & ICS932S401_FS_MASK;
230 freq = fs_speeds[fid];
231 if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT) {
232 switch (freq) {
233 case 166666:
234 freq = 160000;
235 break;
236 case 333333:
237 freq = 320000;
238 break;
239 }
240 }
241 }
242
243 return sprintf(buf, "%d\n", freq);
244}
245
246/* Calculate SRC frequency from the M/N registers. */
247static int calculate_src_freq(struct ics932s401_data *data)
248{
249 int m, n, freq;
250
251 m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK;
252 n = data->regs[ICS932S401_REG_SRC_N_CTRL];
253
254 /* Pull in bits 8 & 9 from the M register */
255 n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1;
256 n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3;
257
258 freq = BASE_CLOCK * (n + 8) / (m + 2);
259 freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] &
260 ICS932S401_SRC_DIVISOR_MASK];
261
262 return freq;
263}
264
265static ssize_t show_src_clock(struct device *dev,
266 struct device_attribute *devattr,
267 char *buf)
268{
269 struct ics932s401_data *data = ics932s401_update_device(dev);
270
271 return sprintf(buf, "%d\n", calculate_src_freq(data));
272}
273
274static ssize_t show_src_clock_sel(struct device *dev,
275 struct device_attribute *devattr,
276 char *buf)
277{
278 struct ics932s401_data *data = ics932s401_update_device(dev);
279 int freq;
280
281 if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)
282 freq = calculate_src_freq(data);
283 else
284 /* Freq is neatly wrapped up for us */
285 if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT &&
286 data->regs[ICS932S401_REG_CTRL] & ICS932S401_SRC_ALT)
287 freq = 96000;
288 else
289 freq = 100000;
290
291 return sprintf(buf, "%d\n", freq);
292}
293
294/* Calculate PCI frequency from the SRC M/N registers. */
295static int calculate_pci_freq(struct ics932s401_data *data)
296{
297 int m, n, freq;
298
299 m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK;
300 n = data->regs[ICS932S401_REG_SRC_N_CTRL];
301
302 /* Pull in bits 8 & 9 from the M register */
303 n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1;
304 n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3;
305
306 freq = BASE_CLOCK * (n + 8) / (m + 2);
307 freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] >>
308 ICS932S401_PCI_DIVISOR_SHIFT];
309
310 return freq;
311}
312
313static ssize_t show_pci_clock(struct device *dev,
314 struct device_attribute *devattr,
315 char *buf)
316{
317 struct ics932s401_data *data = ics932s401_update_device(dev);
318
319 return sprintf(buf, "%d\n", calculate_pci_freq(data));
320}
321
322static ssize_t show_pci_clock_sel(struct device *dev,
323 struct device_attribute *devattr,
324 char *buf)
325{
326 struct ics932s401_data *data = ics932s401_update_device(dev);
327 int freq;
328
329 if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)
330 freq = calculate_pci_freq(data);
331 else
332 freq = 33333;
333
334 return sprintf(buf, "%d\n", freq);
335}
336
337static ssize_t show_value(struct device *dev,
338 struct device_attribute *devattr,
339 char *buf);
340
341static ssize_t show_spread(struct device *dev,
342 struct device_attribute *devattr,
343 char *buf);
344
345static DEVICE_ATTR(spread_enabled, S_IRUGO, show_spread_enabled, NULL);
346static DEVICE_ATTR(cpu_clock_selection, S_IRUGO, show_cpu_clock_sel, NULL);
347static DEVICE_ATTR(cpu_clock, S_IRUGO, show_cpu_clock, NULL);
348static DEVICE_ATTR(src_clock_selection, S_IRUGO, show_src_clock_sel, NULL);
349static DEVICE_ATTR(src_clock, S_IRUGO, show_src_clock, NULL);
350static DEVICE_ATTR(pci_clock_selection, S_IRUGO, show_pci_clock_sel, NULL);
351static DEVICE_ATTR(pci_clock, S_IRUGO, show_pci_clock, NULL);
352static DEVICE_ATTR(usb_clock, S_IRUGO, show_value, NULL);
353static DEVICE_ATTR(ref_clock, S_IRUGO, show_value, NULL);
354static DEVICE_ATTR(cpu_spread, S_IRUGO, show_spread, NULL);
355static DEVICE_ATTR(src_spread, S_IRUGO, show_spread, NULL);
356
357static struct attribute *ics932s401_attr[] =
358{
359 &dev_attr_spread_enabled.attr,
360 &dev_attr_cpu_clock_selection.attr,
361 &dev_attr_cpu_clock.attr,
362 &dev_attr_src_clock_selection.attr,
363 &dev_attr_src_clock.attr,
364 &dev_attr_pci_clock_selection.attr,
365 &dev_attr_pci_clock.attr,
366 &dev_attr_usb_clock.attr,
367 &dev_attr_ref_clock.attr,
368 &dev_attr_cpu_spread.attr,
369 &dev_attr_src_spread.attr,
370 NULL
371};
372
373static ssize_t show_value(struct device *dev,
374 struct device_attribute *devattr,
375 char *buf)
376{
377 int x;
378
379 if (devattr == &dev_attr_usb_clock)
380 x = 48000;
381 else if (devattr == &dev_attr_ref_clock)
382 x = BASE_CLOCK;
383 else
384 BUG();
385
386 return sprintf(buf, "%d\n", x);
387}
388
389static ssize_t show_spread(struct device *dev,
390 struct device_attribute *devattr,
391 char *buf)
392{
393 struct ics932s401_data *data = ics932s401_update_device(dev);
394 int reg;
395 unsigned long val;
396
397 if (!(data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD))
398 return sprintf(buf, "0%%\n");
399
400 if (devattr == &dev_attr_src_spread)
401 reg = ICS932S401_REG_SRC_SPREAD1;
402 else if (devattr == &dev_attr_cpu_spread)
403 reg = ICS932S401_REG_CPU_SPREAD1;
404 else
405 BUG();
406
407 val = data->regs[reg] | (data->regs[reg + 1] << 8);
408 val &= ICS932S401_SPREAD_MASK;
409
410 /* Scale 0..2^14 to -0.5. */
411 val = 500000 * val / 16384;
412 return sprintf(buf, "-0.%lu%%\n", val);
413}
414
415/* Return 0 if detection is successful, -ENODEV otherwise */
416static int ics932s401_detect(struct i2c_client *client, int kind,
417 struct i2c_board_info *info)
418{
419 struct i2c_adapter *adapter = client->adapter;
420
421 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
422 return -ENODEV;
423
424 if (kind <= 0) {
425 int vendor, device, revision;
426
427 vendor = i2c_smbus_read_word_data(client,
428 ICS932S401_REG_VENDOR_REV);
429 vendor >>= 8;
430 revision = vendor >> ICS932S401_REV_SHIFT;
431 vendor &= ICS932S401_VENDOR_MASK;
432 if (vendor != ICS932S401_VENDOR)
433 return -ENODEV;
434
435 device = i2c_smbus_read_word_data(client,
436 ICS932S401_REG_DEVICE);
437 device >>= 8;
438 if (device != ICS932S401_DEVICE)
439 return -ENODEV;
440
441 if (revision != ICS932S401_REV)
442 dev_info(&adapter->dev, "Unknown revision %d\n",
443 revision);
444 } else
445 dev_dbg(&adapter->dev, "detection forced\n");
446
447 strlcpy(info->type, "ics932s401", I2C_NAME_SIZE);
448
449 return 0;
450}
451
452static int ics932s401_probe(struct i2c_client *client,
453 const struct i2c_device_id *id)
454{
455 struct ics932s401_data *data;
456 int err;
457
458 data = kzalloc(sizeof(struct ics932s401_data), GFP_KERNEL);
459 if (!data) {
460 err = -ENOMEM;
461 goto exit;
462 }
463
464 i2c_set_clientdata(client, data);
465 mutex_init(&data->lock);
466
467 dev_info(&client->dev, "%s chip found\n", client->name);
468
469 /* Register sysfs hooks */
470 data->attrs.attrs = ics932s401_attr;
471 err = sysfs_create_group(&client->dev.kobj, &data->attrs);
472 if (err)
473 goto exit_free;
474
475 return 0;
476
477exit_free:
478 kfree(data);
479exit:
480 return err;
481}
482
483static int ics932s401_remove(struct i2c_client *client)
484{
485 struct ics932s401_data *data = i2c_get_clientdata(client);
486
487 sysfs_remove_group(&client->dev.kobj, &data->attrs);
488 kfree(data);
489 return 0;
490}
491
492static int __init ics932s401_init(void)
493{
494 return i2c_add_driver(&ics932s401_driver);
495}
496
497static void __exit ics932s401_exit(void)
498{
499 i2c_del_driver(&ics932s401_driver);
500}
501
502MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
503MODULE_DESCRIPTION("ICS932S401 driver");
504MODULE_LICENSE("GPL");
505
506module_init(ics932s401_init);
507module_exit(ics932s401_exit);
508
509/* IBM IntelliStation Z30 */
510MODULE_ALIAS("dmi:bvnIBM:*:rn9228:*");
511MODULE_ALIAS("dmi:bvnIBM:*:rn9232:*");
512
513/* IBM x3650/x3550 */
514MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650*");
515MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550*");
diff --git a/drivers/misc/intel_menlow.c b/drivers/misc/intel_menlow.c
index e00a2756e97e..27b7662955bb 100644
--- a/drivers/misc/intel_menlow.c
+++ b/drivers/misc/intel_menlow.c
@@ -52,6 +52,11 @@ MODULE_LICENSE("GPL");
52#define MEMORY_ARG_CUR_BANDWIDTH 1 52#define MEMORY_ARG_CUR_BANDWIDTH 1
53#define MEMORY_ARG_MAX_BANDWIDTH 0 53#define MEMORY_ARG_MAX_BANDWIDTH 0
54 54
55/*
56 * GTHS returning 'n' would mean that [0,n-1] states are supported
57 * In that case max_cstate would be n-1
58 * GTHS returning '0' would mean that no bandwidth control states are supported
59 */
55static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, 60static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
56 unsigned long *max_state) 61 unsigned long *max_state)
57{ 62{
@@ -71,6 +76,9 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
71 if (ACPI_FAILURE(status)) 76 if (ACPI_FAILURE(status))
72 return -EFAULT; 77 return -EFAULT;
73 78
79 if (!value)
80 return -EINVAL;
81
74 *max_state = value - 1; 82 *max_state = value - 1;
75 return 0; 83 return 0;
76} 84}
@@ -121,7 +129,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
121 if (memory_get_int_max_bandwidth(cdev, &max_state)) 129 if (memory_get_int_max_bandwidth(cdev, &max_state))
122 return -EFAULT; 130 return -EFAULT;
123 131
124 if (max_state < 0 || state > max_state) 132 if (state > max_state)
125 return -EINVAL; 133 return -EINVAL;
126 134
127 arg_list.count = 1; 135 arg_list.count = 1;
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
index de898c6938f3..759763d18e4c 100644
--- a/drivers/misc/msi-laptop.c
+++ b/drivers/misc/msi-laptop.c
@@ -347,12 +347,16 @@ static int __init msi_init(void)
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)
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 06f07e19dc70..7bcb81002dcf 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -1038,7 +1038,11 @@ static int sony_nc_add(struct acpi_device *device)
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);
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 4db1cf9078d9..7a4a26b0edd2 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -4932,16 +4932,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
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