aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig15
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c2
-rw-r--r--drivers/misc/hdpuftrs/hdpu_nexus.c2
-rw-r--r--drivers/misc/ibmasm/ibmasmfs.c10
-rw-r--r--drivers/misc/ioc4.c6
-rw-r--r--drivers/misc/sony-laptop.c562
-rw-r--r--drivers/misc/tifm_7xx1.c2
8 files changed, 588 insertions, 12 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index bedae4ad3f74..80b199fa0aa9 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -107,4 +107,19 @@ config MSI_LAPTOP
107 107
108 If you have an MSI S270 laptop, say Y or M here. 108 If you have an MSI S270 laptop, say Y or M here.
109 109
110config SONY_LAPTOP
111 tristate "Sony Laptop Extras"
112 depends on X86 && ACPI
113 select BACKLIGHT_CLASS_DEVICE
114 ---help---
115 This mini-driver drives the SNC device present in the ACPI BIOS of
116 the Sony Vaio laptops.
117
118 It gives access to some extra laptop functionalities. In its current
119 form, this driver let the user set or query the screen brightness
120 through the backlight subsystem and remove/apply power to some
121 devices.
122
123 Read <file:Documentation/sony-laptop.txt> for more information.
124
110endmenu 125endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 35da53c409c0..7793ccd79049 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_LKDTM) += lkdtm.o
11obj-$(CONFIG_TIFM_CORE) += tifm_core.o 11obj-$(CONFIG_TIFM_CORE) += tifm_core.o
12obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 12obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
13obj-$(CONFIG_SGI_IOC4) += ioc4.o 13obj-$(CONFIG_SGI_IOC4) += ioc4.o
14obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index 11a801be71c8..ca86f113f36a 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -169,7 +169,7 @@ static struct platform_driver hdpu_cpustate_driver = {
169/* 169/*
170 * The various file operations we support. 170 * The various file operations we support.
171 */ 171 */
172static struct file_operations cpustate_fops = { 172static const struct file_operations cpustate_fops = {
173 owner:THIS_MODULE, 173 owner:THIS_MODULE,
174 open:cpustate_open, 174 open:cpustate_open,
175 release:cpustate_release, 175 release:cpustate_release,
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
index ea9d5f233c83..6a51e99a8079 100644
--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
+++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
@@ -72,11 +72,9 @@ static int hdpu_nexus_probe(struct platform_device *pdev)
72 printk("Could not map slot id\n"); 72 printk("Could not map slot id\n");
73 hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, &proc_root); 73 hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, &proc_root);
74 hdpu_slot_id->read_proc = hdpu_slot_id_read; 74 hdpu_slot_id->read_proc = hdpu_slot_id_read;
75 hdpu_slot_id->nlink = 1;
76 75
77 hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, &proc_root); 76 hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, &proc_root);
78 hdpu_chassis_id->read_proc = hdpu_chassis_id_read; 77 hdpu_chassis_id->read_proc = hdpu_chassis_id_read;
79 hdpu_chassis_id->nlink = 1;
80 return 0; 78 return 0;
81} 79}
82 80
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
index b99dc507de2e..c436d3de8b8b 100644
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -156,7 +156,7 @@ static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode)
156static struct dentry *ibmasmfs_create_file (struct super_block *sb, 156static struct dentry *ibmasmfs_create_file (struct super_block *sb,
157 struct dentry *parent, 157 struct dentry *parent,
158 const char *name, 158 const char *name,
159 struct file_operations *fops, 159 const struct file_operations *fops,
160 void *data, 160 void *data,
161 int mode) 161 int mode)
162{ 162{
@@ -581,28 +581,28 @@ static ssize_t remote_settings_file_write(struct file *file, const char __user *
581 return count; 581 return count;
582} 582}
583 583
584static struct file_operations command_fops = { 584static const struct file_operations command_fops = {
585 .open = command_file_open, 585 .open = command_file_open,
586 .release = command_file_close, 586 .release = command_file_close,
587 .read = command_file_read, 587 .read = command_file_read,
588 .write = command_file_write, 588 .write = command_file_write,
589}; 589};
590 590
591static struct file_operations event_fops = { 591static const struct file_operations event_fops = {
592 .open = event_file_open, 592 .open = event_file_open,
593 .release = event_file_close, 593 .release = event_file_close,
594 .read = event_file_read, 594 .read = event_file_read,
595 .write = event_file_write, 595 .write = event_file_write,
596}; 596};
597 597
598static struct file_operations r_heartbeat_fops = { 598static const struct file_operations r_heartbeat_fops = {
599 .open = r_heartbeat_file_open, 599 .open = r_heartbeat_file_open,
600 .release = r_heartbeat_file_close, 600 .release = r_heartbeat_file_close,
601 .read = r_heartbeat_file_read, 601 .read = r_heartbeat_file_read,
602 .write = r_heartbeat_file_write, 602 .write = r_heartbeat_file_write,
603}; 603};
604 604
605static struct file_operations remote_settings_fops = { 605static const struct file_operations remote_settings_fops = {
606 .open = remote_settings_file_open, 606 .open = remote_settings_file_open,
607 .release = remote_settings_file_close, 607 .release = remote_settings_file_close,
608 .read = remote_settings_file_read, 608 .read = remote_settings_file_read,
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index b995a15b7526..6a5a05d1f392 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -309,7 +309,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
309 ret = -ENODEV; 309 ret = -ENODEV;
310 goto out_pci; 310 goto out_pci;
311 } 311 }
312 if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs), 312 if (!request_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
313 "ioc4_misc")) { 313 "ioc4_misc")) {
314 printk(KERN_WARNING 314 printk(KERN_WARNING
315 "%s: Unable to request IOC4 misc region " 315 "%s: Unable to request IOC4 misc region "
@@ -379,7 +379,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
379 return 0; 379 return 0;
380 380
381out_misc_region: 381out_misc_region:
382 release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); 382 release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
383out_pci: 383out_pci:
384 kfree(idd); 384 kfree(idd);
385out_idd: 385out_idd:
@@ -418,7 +418,7 @@ ioc4_remove(struct pci_dev *pdev)
418 "Device removal may be incomplete.\n", 418 "Device removal may be incomplete.\n",
419 __FUNCTION__, pci_name(idd->idd_pdev)); 419 __FUNCTION__, pci_name(idd->idd_pdev));
420 } 420 }
421 release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs)); 421 release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
422 422
423 /* Disable IOC4 and relinquish */ 423 /* Disable IOC4 and relinquish */
424 pci_disable_device(pdev); 424 pci_disable_device(pdev);
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
new file mode 100644
index 000000000000..cabbed0015e4
--- /dev/null
+++ b/drivers/misc/sony-laptop.c
@@ -0,0 +1,562 @@
1/*
2 * ACPI Sony Notebook Control Driver (SNC)
3 *
4 * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
5 * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
6 *
7 * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
8 * which are copyrighted by their respective authors.
9 *
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
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
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
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/types.h>
31#include <linux/backlight.h>
32#include <linux/platform_device.h>
33#include <linux/err.h>
34#include <acpi/acpi_drivers.h>
35#include <acpi/acpi_bus.h>
36#include <asm/uaccess.h>
37
38#define ACPI_SNC_CLASS "sony"
39#define ACPI_SNC_HID "SNY5001"
40#define ACPI_SNC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.4"
41
42/* the device uses 1-based values, while the backlight subsystem uses
43 0-based values */
44#define SONY_MAX_BRIGHTNESS 8
45
46#define LOG_PFX KERN_WARNING "sony-laptop: "
47
48MODULE_AUTHOR("Stelian Pop, Mattia Dongili");
49MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME);
50MODULE_LICENSE("GPL");
51
52static int debug;
53module_param(debug, int, 0);
54MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help "
55 "the development of this driver");
56
57static ssize_t sony_acpi_show(struct device *, struct device_attribute *,
58 char *);
59static ssize_t sony_acpi_store(struct device *, struct device_attribute *,
60 const char *, size_t);
61static int boolean_validate(const int, const int);
62static int brightness_default_validate(const int, const int);
63
64#define SNC_VALIDATE_IN 0
65#define SNC_VALIDATE_OUT 1
66
67struct sony_acpi_value {
68 char *name; /* name of the entry */
69 char **acpiget; /* names of the ACPI get function */
70 char **acpiset; /* names of the ACPI set function */
71 int (*validate)(const int, const int); /* input/output validation */
72 int value; /* current setting */
73 int valid; /* Has ever been set */
74 int debug; /* active only in debug mode ? */
75 struct device_attribute devattr; /* sysfs atribute */
76};
77
78#define HANDLE_NAMES(_name, _values...) \
79 static char *snc_##_name[] = { _values, NULL }
80
81#define SONY_ACPI_VALUE(_name, _getters, _setters, _validate, _debug) \
82 { \
83 .name = __stringify(_name), \
84 .acpiget = _getters, \
85 .acpiset = _setters, \
86 .validate = _validate, \
87 .debug = _debug, \
88 .devattr = __ATTR(_name, 0, sony_acpi_show, sony_acpi_store), \
89 }
90
91#define SONY_ACPI_VALUE_NULL { .name = NULL }
92
93HANDLE_NAMES(fnkey_get, "GHKE");
94
95HANDLE_NAMES(brightness_def_get, "GPBR");
96HANDLE_NAMES(brightness_def_set, "SPBR");
97
98HANDLE_NAMES(cdpower_get, "GCDP");
99HANDLE_NAMES(cdpower_set, "SCDP", "CDPW");
100
101HANDLE_NAMES(audiopower_get, "GAZP");
102HANDLE_NAMES(audiopower_set, "AZPW");
103
104HANDLE_NAMES(lanpower_get, "GLNP");
105HANDLE_NAMES(lanpower_set, "LNPW");
106
107HANDLE_NAMES(PID_get, "GPID");
108
109HANDLE_NAMES(CTR_get, "GCTR");
110HANDLE_NAMES(CTR_set, "SCTR");
111
112HANDLE_NAMES(PCR_get, "GPCR");
113HANDLE_NAMES(PCR_set, "SPCR");
114
115HANDLE_NAMES(CMI_get, "GCMI");
116HANDLE_NAMES(CMI_set, "SCMI");
117
118static struct sony_acpi_value sony_acpi_values[] = {
119 SONY_ACPI_VALUE(brightness_default, snc_brightness_def_get,
120 snc_brightness_def_set, brightness_default_validate, 0),
121 SONY_ACPI_VALUE(fnkey, snc_fnkey_get, NULL, NULL, 0),
122 SONY_ACPI_VALUE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0),
123 SONY_ACPI_VALUE(audiopower, snc_audiopower_get, snc_audiopower_set,
124 boolean_validate, 0),
125 SONY_ACPI_VALUE(lanpower, snc_lanpower_get, snc_lanpower_set,
126 boolean_validate, 1),
127 /* unknown methods */
128 SONY_ACPI_VALUE(PID, snc_PID_get, NULL, NULL, 1),
129 SONY_ACPI_VALUE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1),
130 SONY_ACPI_VALUE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1),
131 SONY_ACPI_VALUE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1),
132 SONY_ACPI_VALUE_NULL
133};
134
135static acpi_handle sony_acpi_handle;
136static struct acpi_device *sony_acpi_acpi_device = NULL;
137
138/*
139 * acpi_evaluate_object wrappers
140 */
141static int acpi_callgetfunc(acpi_handle handle, char *name, int *result)
142{
143 struct acpi_buffer output;
144 union acpi_object out_obj;
145 acpi_status status;
146
147 output.length = sizeof(out_obj);
148 output.pointer = &out_obj;
149
150 status = acpi_evaluate_object(handle, name, NULL, &output);
151 if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) {
152 *result = out_obj.integer.value;
153 return 0;
154 }
155
156 printk(LOG_PFX "acpi_callreadfunc failed\n");
157
158 return -1;
159}
160
161static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
162 int *result)
163{
164 struct acpi_object_list params;
165 union acpi_object in_obj;
166 struct acpi_buffer output;
167 union acpi_object out_obj;
168 acpi_status status;
169
170 params.count = 1;
171 params.pointer = &in_obj;
172 in_obj.type = ACPI_TYPE_INTEGER;
173 in_obj.integer.value = value;
174
175 output.length = sizeof(out_obj);
176 output.pointer = &out_obj;
177
178 status = acpi_evaluate_object(handle, name, &params, &output);
179 if (status == AE_OK) {
180 if (result != NULL) {
181 if (out_obj.type != ACPI_TYPE_INTEGER) {
182 printk(LOG_PFX "acpi_evaluate_object bad "
183 "return type\n");
184 return -1;
185 }
186 *result = out_obj.integer.value;
187 }
188 return 0;
189 }
190
191 printk(LOG_PFX "acpi_evaluate_object failed\n");
192
193 return -1;
194}
195
196/*
197 * sony_acpi_values input/output validate functions
198 */
199
200/* brightness_default_validate:
201 *
202 * manipulate input output values to keep consistency with the
203 * backlight framework for which brightness values are 0-based.
204 */
205static int brightness_default_validate(const int direction, const int value)
206{
207 switch (direction) {
208 case SNC_VALIDATE_OUT:
209 return value - 1;
210 case SNC_VALIDATE_IN:
211 if (value >= 0 && value < SONY_MAX_BRIGHTNESS)
212 return value + 1;
213 }
214 return -EINVAL;
215}
216
217/* boolean_validate:
218 *
219 * on input validate boolean values 0/1, on output just pass the
220 * received value.
221 */
222static int boolean_validate(const int direction, const int value)
223{
224 if (direction == SNC_VALIDATE_IN) {
225 if (value != 0 && value != 1)
226 return -EINVAL;
227 }
228 return value;
229}
230
231/*
232 * Sysfs show/store common to all sony_acpi_values
233 */
234static ssize_t sony_acpi_show(struct device *dev, struct device_attribute *attr,
235 char *buffer)
236{
237 int value;
238 struct sony_acpi_value *item =
239 container_of(attr, struct sony_acpi_value, devattr);
240
241 if (!*item->acpiget)
242 return -EIO;
243
244 if (acpi_callgetfunc(sony_acpi_handle, *item->acpiget, &value) < 0)
245 return -EIO;
246
247 if (item->validate)
248 value = item->validate(SNC_VALIDATE_OUT, value);
249
250 return snprintf(buffer, PAGE_SIZE, "%d\n", value);
251}
252
253static ssize_t sony_acpi_store(struct device *dev,
254 struct device_attribute *attr,
255 const char *buffer, size_t count)
256{
257 int value;
258 struct sony_acpi_value *item =
259 container_of(attr, struct sony_acpi_value, devattr);
260
261 if (!item->acpiset)
262 return -EIO;
263
264 if (count > 31)
265 return -EINVAL;
266
267 value = simple_strtoul(buffer, NULL, 10);
268
269 if (item->validate)
270 value = item->validate(SNC_VALIDATE_IN, value);
271
272 if (value < 0)
273 return value;
274
275 if (acpi_callsetfunc(sony_acpi_handle, *item->acpiset, value, NULL) < 0)
276 return -EIO;
277 item->value = value;
278 item->valid = 1;
279 return count;
280}
281
282/*
283 * Platform device
284 */
285static struct platform_driver sncpf_driver = {
286 .driver = {
287 .name = "sony-laptop",
288 .owner = THIS_MODULE,
289 }
290};
291static struct platform_device *sncpf_device;
292
293static int sony_snc_pf_add(void)
294{
295 acpi_handle handle;
296 struct sony_acpi_value *item;
297 int ret = 0;
298
299 ret = platform_driver_register(&sncpf_driver);
300 if (ret)
301 goto out;
302
303 sncpf_device = platform_device_alloc("sony-laptop", -1);
304 if (!sncpf_device) {
305 ret = -ENOMEM;
306 goto out_platform_registered;
307 }
308
309 ret = platform_device_add(sncpf_device);
310 if (ret)
311 goto out_platform_alloced;
312
313 for (item = sony_acpi_values; item->name; ++item) {
314
315 if (!debug && item->debug)
316 continue;
317
318 /* find the available acpiget as described in the DSDT */
319 for (; item->acpiget && *item->acpiget; ++item->acpiget) {
320 if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle,
321 *item->acpiget,
322 &handle))) {
323 if (debug)
324 printk(LOG_PFX "Found %s getter: %s\n",
325 item->name, *item->acpiget);
326 item->devattr.attr.mode |= S_IRUGO;
327 break;
328 }
329 }
330
331 /* find the available acpiset as described in the DSDT */
332 for (; item->acpiset && *item->acpiset; ++item->acpiset) {
333 if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle,
334 *item->acpiset,
335 &handle))) {
336 if (debug)
337 printk(LOG_PFX "Found %s setter: %s\n",
338 item->name, *item->acpiset);
339 item->devattr.attr.mode |= S_IWUSR;
340 break;
341 }
342 }
343
344 if (item->devattr.attr.mode != 0) {
345 ret =
346 device_create_file(&sncpf_device->dev,
347 &item->devattr);
348 if (ret)
349 goto out_sysfs;
350 }
351 }
352
353 return 0;
354
355 out_sysfs:
356 for (item = sony_acpi_values; item->name; ++item) {
357 device_remove_file(&sncpf_device->dev, &item->devattr);
358 }
359 platform_device_del(sncpf_device);
360 out_platform_alloced:
361 platform_device_put(sncpf_device);
362 out_platform_registered:
363 platform_driver_unregister(&sncpf_driver);
364 out:
365 return ret;
366}
367
368static void sony_snc_pf_remove(void)
369{
370 struct sony_acpi_value *item;
371
372 for (item = sony_acpi_values; item->name; ++item) {
373 device_remove_file(&sncpf_device->dev, &item->devattr);
374 }
375
376 platform_device_del(sncpf_device);
377 platform_device_put(sncpf_device);
378 platform_driver_unregister(&sncpf_driver);
379}
380
381/*
382 * Backlight device
383 */
384static int sony_backlight_update_status(struct backlight_device *bd)
385{
386 return acpi_callsetfunc(sony_acpi_handle, "SBRT",
387 bd->props->brightness + 1, NULL);
388}
389
390static int sony_backlight_get_brightness(struct backlight_device *bd)
391{
392 int value;
393
394 if (acpi_callgetfunc(sony_acpi_handle, "GBRT", &value))
395 return 0;
396 /* brightness levels are 1-based, while backlight ones are 0-based */
397 return value - 1;
398}
399
400static struct backlight_device *sony_backlight_device;
401static struct backlight_properties sony_backlight_properties = {
402 .owner = THIS_MODULE,
403 .update_status = sony_backlight_update_status,
404 .get_brightness = sony_backlight_get_brightness,
405 .max_brightness = SONY_MAX_BRIGHTNESS - 1,
406};
407
408/*
409 * ACPI callbacks
410 */
411static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
412{
413 if (debug)
414 printk(LOG_PFX "sony_acpi_notify, event: %d\n", event);
415 acpi_bus_generate_event(sony_acpi_acpi_device, 1, event);
416}
417
418static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
419 void *context, void **return_value)
420{
421 struct acpi_namespace_node *node;
422 union acpi_operand_object *operand;
423
424 node = (struct acpi_namespace_node *)handle;
425 operand = (union acpi_operand_object *)node->object;
426
427 printk(LOG_PFX "method: name: %4.4s, args %X\n", node->name.ascii,
428 (u32) operand->method.param_count);
429
430 return AE_OK;
431}
432
433/*
434 * ACPI device
435 */
436static int sony_acpi_resume(struct acpi_device *device)
437{
438 struct sony_acpi_value *item;
439
440 for (item = sony_acpi_values; item->name; item++) {
441 int ret;
442
443 if (!item->valid)
444 continue;
445 ret = acpi_callsetfunc(sony_acpi_handle, *item->acpiset,
446 item->value, NULL);
447 if (ret < 0) {
448 printk("%s: %d\n", __FUNCTION__, ret);
449 break;
450 }
451 }
452 return 0;
453}
454
455static int sony_acpi_add(struct acpi_device *device)
456{
457 acpi_status status;
458 int result;
459 acpi_handle handle;
460
461 sony_acpi_acpi_device = device;
462
463 sony_acpi_handle = device->handle;
464
465 if (debug) {
466 status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle,
467 1, sony_walk_callback, NULL, NULL);
468 if (ACPI_FAILURE(status)) {
469 printk(LOG_PFX "unable to walk acpi resources\n");
470 result = -ENODEV;
471 goto outwalk;
472 }
473 }
474
475 status = acpi_install_notify_handler(sony_acpi_handle,
476 ACPI_DEVICE_NOTIFY,
477 sony_acpi_notify, NULL);
478 if (ACPI_FAILURE(status)) {
479 printk(LOG_PFX "unable to install notify handler\n");
480 result = -ENODEV;
481 goto outwalk;
482 }
483
484 if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) {
485 sony_backlight_device = backlight_device_register("sony", NULL,
486 NULL,
487 &sony_backlight_properties);
488
489 if (IS_ERR(sony_backlight_device)) {
490 printk(LOG_PFX "unable to register backlight device\n");
491 sony_backlight_device = NULL;
492 } else
493 sony_backlight_properties.brightness =
494 sony_backlight_get_brightness
495 (sony_backlight_device);
496 }
497
498 if (sony_snc_pf_add())
499 goto outbacklight;
500
501 printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n");
502
503 return 0;
504
505 outbacklight:
506 if (sony_backlight_device)
507 backlight_device_unregister(sony_backlight_device);
508
509 status = acpi_remove_notify_handler(sony_acpi_handle,
510 ACPI_DEVICE_NOTIFY,
511 sony_acpi_notify);
512 if (ACPI_FAILURE(status))
513 printk(LOG_PFX "unable to remove notify handler\n");
514 outwalk:
515 return result;
516}
517
518static int sony_acpi_remove(struct acpi_device *device, int type)
519{
520 acpi_status status;
521
522 if (sony_backlight_device)
523 backlight_device_unregister(sony_backlight_device);
524
525 sony_acpi_acpi_device = NULL;
526
527 status = acpi_remove_notify_handler(sony_acpi_handle,
528 ACPI_DEVICE_NOTIFY,
529 sony_acpi_notify);
530 if (ACPI_FAILURE(status))
531 printk(LOG_PFX "unable to remove notify handler\n");
532
533 sony_snc_pf_remove();
534
535 printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n");
536
537 return 0;
538}
539
540static struct acpi_driver sony_acpi_driver = {
541 .name = ACPI_SNC_DRIVER_NAME,
542 .class = ACPI_SNC_CLASS,
543 .ids = ACPI_SNC_HID,
544 .ops = {
545 .add = sony_acpi_add,
546 .remove = sony_acpi_remove,
547 .resume = sony_acpi_resume,
548 },
549};
550
551static int __init sony_acpi_init(void)
552{
553 return acpi_bus_register_driver(&sony_acpi_driver);
554}
555
556static void __exit sony_acpi_exit(void)
557{
558 acpi_bus_unregister_driver(&sony_acpi_driver);
559}
560
561module_init(sony_acpi_init);
562module_exit(sony_acpi_exit);
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index e21e490fedb0..bc60e2fc3c2c 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -367,7 +367,7 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
367 if (!fm->addr) 367 if (!fm->addr)
368 goto err_out_free; 368 goto err_out_free;
369 369
370 rc = request_irq(dev->irq, tifm_7xx1_isr, SA_SHIRQ, DRIVER_NAME, fm); 370 rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm);
371 if (rc) 371 if (rc)
372 goto err_out_unmap; 372 goto err_out_unmap;
373 373