diff options
author | Mattia Dongili <malattia@linux.it> | 2007-02-07 14:01:54 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-02-13 03:07:00 -0500 |
commit | ed3aa4b729478978f117269b5266a2d18948912c (patch) | |
tree | ddc24d2933722eb2d1a4f71257e2cc4418488723 /drivers/misc | |
parent | 91fbc1d311c1b8b71203b96f1a0629da7360eb4c (diff) |
sony-laptop: Remove /proc/acpi/sony interface and implement platform_device.
Rework method names list to allow an easier management of multiple
values.
Add myself as author/maintainer and bump the version number.
Signed-off-by: Mattia Dongili <malattia@linux.it>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/sony-laptop.c | 396 |
1 files changed, 198 insertions, 198 deletions
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 103657e1b449..1d14969fe6e7 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * ACPI Sony Notebook Control Driver (SNC) | 2 | * ACPI Sony Notebook Control Driver (SNC) |
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 | * | 6 | * |
6 | * 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 |
7 | * which are copyrighted by their respective authors. | 8 | * which are copyrighted by their respective authors. |
@@ -28,6 +29,7 @@ | |||
28 | #include <linux/init.h> | 29 | #include <linux/init.h> |
29 | #include <linux/types.h> | 30 | #include <linux/types.h> |
30 | #include <linux/backlight.h> | 31 | #include <linux/backlight.h> |
32 | #include <linux/platform_device.h> | ||
31 | #include <linux/err.h> | 33 | #include <linux/err.h> |
32 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
33 | #include <acpi/acpi_bus.h> | 35 | #include <acpi/acpi_bus.h> |
@@ -35,15 +37,15 @@ | |||
35 | 37 | ||
36 | #define ACPI_SNC_CLASS "sony" | 38 | #define ACPI_SNC_CLASS "sony" |
37 | #define ACPI_SNC_HID "SNY5001" | 39 | #define ACPI_SNC_HID "SNY5001" |
38 | #define ACPI_SNC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.3" | 40 | #define ACPI_SNC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.4" |
39 | 41 | ||
40 | /* the device uses 1-based values, while the backlight subsystem uses | 42 | /* the device uses 1-based values, while the backlight subsystem uses |
41 | 0-based values */ | 43 | 0-based values */ |
42 | #define SONY_MAX_BRIGHTNESS 8 | 44 | #define SONY_MAX_BRIGHTNESS 8 |
43 | 45 | ||
44 | #define LOG_PFX KERN_WARNING "sony_acpi: " | 46 | #define LOG_PFX KERN_WARNING "sony-laptop: " |
45 | 47 | ||
46 | MODULE_AUTHOR("Stelian Pop"); | 48 | MODULE_AUTHOR("Stelian Pop, Mattia Dongili"); |
47 | MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME); | 49 | MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME); |
48 | MODULE_LICENSE("GPL"); | 50 | MODULE_LICENSE("GPL"); |
49 | 51 | ||
@@ -52,10 +54,6 @@ module_param(debug, int, 0); | |||
52 | MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " | 54 | MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help " |
53 | "the development of this driver"); | 55 | "the development of this driver"); |
54 | 56 | ||
55 | static acpi_handle sony_acpi_handle; | ||
56 | static struct proc_dir_entry *sony_acpi_dir; | ||
57 | static struct acpi_device *sony_acpi_acpi_device = NULL; | ||
58 | |||
59 | static int sony_backlight_update_status(struct backlight_device *bd); | 57 | static int sony_backlight_update_status(struct backlight_device *bd); |
60 | static int sony_backlight_get_brightness(struct backlight_device *bd); | 58 | static int sony_backlight_get_brightness(struct backlight_device *bd); |
61 | static struct backlight_device *sony_backlight_device; | 59 | static struct backlight_device *sony_backlight_device; |
@@ -66,105 +64,79 @@ static struct backlight_properties sony_backlight_properties = { | |||
66 | .max_brightness = SONY_MAX_BRIGHTNESS - 1, | 64 | .max_brightness = SONY_MAX_BRIGHTNESS - 1, |
67 | }; | 65 | }; |
68 | 66 | ||
69 | static struct sony_acpi_value { | 67 | static ssize_t sony_acpi_show(struct device *, struct device_attribute *, char *); |
70 | char *name; /* name of the entry */ | 68 | static ssize_t sony_acpi_store(struct device *, struct device_attribute *, const char *, size_t); |
71 | struct proc_dir_entry *proc; /* /proc entry */ | 69 | |
72 | char *acpiget;/* name of the ACPI get function */ | 70 | struct sony_acpi_value { |
73 | char *acpiset;/* name of the ACPI get function */ | 71 | char *name; /* name of the entry */ |
74 | int min; /* minimum allowed value or -1 */ | 72 | char **acpiget; /* names of the ACPI get function */ |
75 | int max; /* maximum allowed value or -1 */ | 73 | char **acpiset; /* names of the ACPI set function */ |
76 | int value; /* current setting */ | 74 | int min; /* minimum allowed value or -1 */ |
77 | int valid; /* Has ever been set */ | 75 | int max; /* maximum allowed value or -1 */ |
78 | int debug; /* active only in debug mode ? */ | 76 | int value; /* current setting */ |
79 | } sony_acpi_values[] = { | 77 | int valid; /* Has ever been set */ |
80 | { | 78 | int debug; /* active only in debug mode ? */ |
81 | /* for backward compatibility only */ | 79 | struct device_attribute devattr; /* sysfs atribute */ |
82 | .name = "brightness", | 80 | }; |
83 | .acpiget = "GBRT", | 81 | |
84 | .acpiset = "SBRT", | 82 | #define HANDLE_NAMES(_name, _values...) \ |
85 | .min = 1, | 83 | static char *snc_##_name[] = { _values, NULL } |
86 | .max = SONY_MAX_BRIGHTNESS, | 84 | |
87 | .debug = 0, | 85 | #define SONY_ACPI_VALUE(_name, _getters, _setters, _min, _max, _debug) \ |
88 | }, | 86 | { \ |
89 | { | 87 | .name = __stringify(_name), \ |
90 | .name = "brightness_default", | 88 | .acpiget = _getters, \ |
91 | .acpiget = "GPBR", | 89 | .acpiset = _setters, \ |
92 | .acpiset = "SPBR", | 90 | .min = _min, \ |
93 | .min = 1, | 91 | .max = _max, \ |
94 | .max = SONY_MAX_BRIGHTNESS, | 92 | .debug = _debug, \ |
95 | .debug = 0, | 93 | .devattr = __ATTR(_name, 0, sony_acpi_show, sony_acpi_store), \ |
96 | }, | ||
97 | { | ||
98 | .name = "fnkey", | ||
99 | .acpiget = "GHKE", | ||
100 | .debug = 0, | ||
101 | }, | ||
102 | { | ||
103 | .name = "cdpower", | ||
104 | .acpiget = "GCDP", | ||
105 | .acpiset = "SCDP", | ||
106 | .min = 0, | ||
107 | .max = 1, | ||
108 | .debug = 0, | ||
109 | }, | ||
110 | { | ||
111 | .name = "cdpower", | ||
112 | .acpiget = "GCDP", | ||
113 | .acpiset = "CDPW", | ||
114 | .min = 0, | ||
115 | .max = 1, | ||
116 | .debug = 0, | ||
117 | }, | ||
118 | { | ||
119 | .name = "audiopower", | ||
120 | .acpiget = "GAZP", | ||
121 | .acpiset = "AZPW", | ||
122 | .min = 0, | ||
123 | .max = 1, | ||
124 | .debug = 0, | ||
125 | }, | ||
126 | { | ||
127 | .name = "lanpower", | ||
128 | .acpiget = "GLNP", | ||
129 | .acpiset = "LNPW", | ||
130 | .min = 0, | ||
131 | .max = 1, | ||
132 | .debug = 1, | ||
133 | }, | ||
134 | { | ||
135 | .name = "PID", | ||
136 | .acpiget = "GPID", | ||
137 | .debug = 1, | ||
138 | }, | ||
139 | { | ||
140 | .name = "CTR", | ||
141 | .acpiget = "GCTR", | ||
142 | .acpiset = "SCTR", | ||
143 | .min = -1, | ||
144 | .max = -1, | ||
145 | .debug = 1, | ||
146 | }, | ||
147 | { | ||
148 | .name = "PCR", | ||
149 | .acpiget = "GPCR", | ||
150 | .acpiset = "SPCR", | ||
151 | .min = -1, | ||
152 | .max = -1, | ||
153 | .debug = 1, | ||
154 | }, | ||
155 | { | ||
156 | .name = "CMI", | ||
157 | .acpiget = "GCMI", | ||
158 | .acpiset = "SCMI", | ||
159 | .min = -1, | ||
160 | .max = -1, | ||
161 | .debug = 1, | ||
162 | }, | ||
163 | { | ||
164 | .name = NULL, | ||
165 | } | 94 | } |
95 | |||
96 | #define SONY_ACPI_VALUE_NULL { .name = NULL } | ||
97 | |||
98 | HANDLE_NAMES(fnkey_get, "GHKE"); | ||
99 | |||
100 | HANDLE_NAMES(brightness_def_get, "GPBR"); | ||
101 | HANDLE_NAMES(brightness_def_set, "SPBR"); | ||
102 | |||
103 | HANDLE_NAMES(cdpower_get, "GCDP"); | ||
104 | HANDLE_NAMES(cdpower_set, "SCDP", "CDPW"); | ||
105 | |||
106 | HANDLE_NAMES(audiopower_get, "GAZP"); | ||
107 | HANDLE_NAMES(audiopower_set, "AZPW"); | ||
108 | |||
109 | HANDLE_NAMES(lanpower_get, "GLNP"); | ||
110 | HANDLE_NAMES(lanpower_set, "LNPW"); | ||
111 | |||
112 | HANDLE_NAMES(PID_get, "GPID"); | ||
113 | |||
114 | HANDLE_NAMES(CTR_get, "GCTR"); | ||
115 | HANDLE_NAMES(CTR_set, "SCTR"); | ||
116 | |||
117 | HANDLE_NAMES(PCR_get, "GPCR"); | ||
118 | HANDLE_NAMES(PCR_set, "SPCR"); | ||
119 | |||
120 | HANDLE_NAMES(CMI_get, "GCMI"); | ||
121 | HANDLE_NAMES(CMI_set, "SCMI"); | ||
122 | |||
123 | static struct sony_acpi_value sony_acpi_values[] = { | ||
124 | SONY_ACPI_VALUE(brightness_default, snc_brightness_def_get, snc_brightness_def_set, 1, SONY_MAX_BRIGHTNESS, 0), | ||
125 | SONY_ACPI_VALUE(fnkey, snc_fnkey_get, NULL, -1, -1, 0), | ||
126 | SONY_ACPI_VALUE(cdpower, snc_cdpower_get, snc_cdpower_set, 0, 1, 0), | ||
127 | SONY_ACPI_VALUE(audiopower, snc_audiopower_get, snc_audiopower_set, 0, 1, 0), | ||
128 | SONY_ACPI_VALUE(lanpower, snc_lanpower_get, snc_lanpower_set, 0, 1, 1), | ||
129 | /* unknown methods */ | ||
130 | SONY_ACPI_VALUE(PID, snc_PID_get, NULL, -1, -1, 1), | ||
131 | SONY_ACPI_VALUE(CTR, snc_CTR_get, snc_CTR_set, -1, -1, 1), | ||
132 | SONY_ACPI_VALUE(PCR, snc_PCR_get, snc_PCR_set, -1, -1, 1), | ||
133 | SONY_ACPI_VALUE(CMI, snc_CMI_get, snc_CMI_set, -1, -1, 1), | ||
134 | SONY_ACPI_VALUE_NULL | ||
166 | }; | 135 | }; |
167 | 136 | ||
137 | static acpi_handle sony_acpi_handle; | ||
138 | static struct acpi_device *sony_acpi_acpi_device = NULL; | ||
139 | |||
168 | static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) | 140 | static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) |
169 | { | 141 | { |
170 | struct acpi_buffer output; | 142 | struct acpi_buffer output; |
@@ -220,61 +192,149 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value, | |||
220 | return -1; | 192 | return -1; |
221 | } | 193 | } |
222 | 194 | ||
223 | static int parse_buffer(const char __user *buffer, unsigned long count, | 195 | /* |
224 | int *val) { | 196 | * Sysfs show/store common to all sony_acpi_values |
225 | char s[32]; | 197 | */ |
226 | int ret; | 198 | static ssize_t sony_acpi_show(struct device *dev, struct device_attribute *attr, |
227 | 199 | char *buffer) | |
228 | if (count > 31) | ||
229 | return -EINVAL; | ||
230 | if (copy_from_user(s, buffer, count)) | ||
231 | return -EFAULT; | ||
232 | s[count] = '\0'; | ||
233 | ret = simple_strtoul(s, NULL, 10); | ||
234 | *val = ret; | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static int sony_acpi_read(char* page, char** start, off_t off, int count, | ||
239 | int* eof, void *data) | ||
240 | { | 200 | { |
241 | struct sony_acpi_value *item = data; | ||
242 | int value; | 201 | int value; |
202 | struct sony_acpi_value *item = container_of(attr, struct sony_acpi_value, devattr); | ||
243 | 203 | ||
244 | if (!item->acpiget) | 204 | if (!*item->acpiget) |
245 | return -EIO; | 205 | return -EIO; |
246 | 206 | ||
247 | if (acpi_callgetfunc(sony_acpi_handle, item->acpiget, &value) < 0) | 207 | if (acpi_callgetfunc(sony_acpi_handle, *item->acpiget, &value) < 0) |
248 | return -EIO; | 208 | return -EIO; |
249 | 209 | ||
250 | return sprintf(page, "%d\n", value); | 210 | return snprintf(buffer, PAGE_SIZE, "%d\n", value); |
251 | } | 211 | } |
252 | 212 | ||
253 | static int sony_acpi_write(struct file *file, const char __user *buffer, | 213 | static ssize_t sony_acpi_store(struct device *dev, struct device_attribute *attr, |
254 | unsigned long count, void *data) | 214 | const char *buffer, size_t count) |
255 | { | 215 | { |
256 | struct sony_acpi_value *item = data; | ||
257 | int result; | ||
258 | int value; | 216 | int value; |
217 | struct sony_acpi_value *item = container_of(attr, struct sony_acpi_value, devattr); | ||
259 | 218 | ||
260 | if (!item->acpiset) | 219 | if (!item->acpiset) |
261 | return -EIO; | 220 | return -EIO; |
262 | 221 | ||
263 | if ((result = parse_buffer(buffer, count, &value)) < 0) | 222 | if (count > 31) |
264 | return result; | 223 | return -EINVAL; |
224 | |||
225 | value = simple_strtoul(buffer, NULL, 10); | ||
265 | 226 | ||
266 | if (item->min != -1 && value < item->min) | 227 | if (item->min != -1 && value < item->min) |
267 | return -EINVAL; | 228 | return -EINVAL; |
268 | if (item->max != -1 && value > item->max) | 229 | if (item->max != -1 && value > item->max) |
269 | return -EINVAL; | 230 | return -EINVAL; |
270 | 231 | ||
271 | if (acpi_callsetfunc(sony_acpi_handle, item->acpiset, value, NULL) < 0) | 232 | if (acpi_callsetfunc(sony_acpi_handle, *item->acpiset, value, NULL) < 0) |
272 | return -EIO; | 233 | return -EIO; |
273 | item->value = value; | 234 | item->value = value; |
274 | item->valid = 1; | 235 | item->valid = 1; |
275 | return count; | 236 | return count; |
276 | } | 237 | } |
277 | 238 | ||
239 | /* | ||
240 | * Platform device | ||
241 | */ | ||
242 | static struct platform_driver sncpf_driver = { | ||
243 | .driver = { | ||
244 | .name = "sony-laptop", | ||
245 | .owner = THIS_MODULE, | ||
246 | } | ||
247 | }; | ||
248 | static struct platform_device *sncpf_device; | ||
249 | |||
250 | static int sony_snc_pf_add(void) | ||
251 | { | ||
252 | acpi_handle handle; | ||
253 | struct sony_acpi_value *item; | ||
254 | int ret = 0; | ||
255 | |||
256 | ret = platform_driver_register(&sncpf_driver); | ||
257 | if (ret) | ||
258 | goto out; | ||
259 | |||
260 | sncpf_device = platform_device_alloc("sony-laptop", -1); | ||
261 | if (!sncpf_device) { | ||
262 | ret = -ENOMEM; | ||
263 | goto out_platform_registered; | ||
264 | } | ||
265 | |||
266 | ret = platform_device_add(sncpf_device); | ||
267 | if (ret) | ||
268 | goto out_platform_alloced; | ||
269 | |||
270 | for (item = sony_acpi_values; item->name; ++item) { | ||
271 | |||
272 | if (!debug && item->debug) | ||
273 | continue; | ||
274 | |||
275 | /* find the available acpiget as described in the DSDT */ | ||
276 | for (; item->acpiget && *item->acpiget; ++item->acpiget) { | ||
277 | if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, | ||
278 | *item->acpiget, | ||
279 | &handle))) { | ||
280 | if (debug) | ||
281 | printk(LOG_PFX "Found %s getter: %s\n", | ||
282 | item->name, | ||
283 | *item->acpiget); | ||
284 | item->devattr.attr.mode |= S_IRUGO; | ||
285 | break; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /* find the available acpiset as described in the DSDT */ | ||
290 | for (; item->acpiset && *item->acpiset; ++item->acpiset) { | ||
291 | if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, | ||
292 | *item->acpiset, | ||
293 | &handle))) { | ||
294 | if (debug) | ||
295 | printk(LOG_PFX "Found %s setter: %s\n", | ||
296 | item->name, | ||
297 | *item->acpiset); | ||
298 | item->devattr.attr.mode |= S_IWUSR; | ||
299 | break; | ||
300 | } | ||
301 | } | ||
302 | |||
303 | if (item->devattr.attr.mode != 0) { | ||
304 | ret = device_create_file(&sncpf_device->dev, &item->devattr); | ||
305 | if (ret) | ||
306 | goto out_sysfs; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | return 0; | ||
311 | |||
312 | out_sysfs: | ||
313 | for (item = sony_acpi_values; item->name; ++item) { | ||
314 | device_remove_file(&sncpf_device->dev, &item->devattr); | ||
315 | } | ||
316 | platform_device_del(sncpf_device); | ||
317 | out_platform_alloced: | ||
318 | platform_device_put(sncpf_device); | ||
319 | out_platform_registered: | ||
320 | platform_driver_unregister(&sncpf_driver); | ||
321 | out: | ||
322 | return ret; | ||
323 | } | ||
324 | |||
325 | static void sony_snc_pf_remove(void) | ||
326 | { | ||
327 | struct sony_acpi_value *item; | ||
328 | |||
329 | for (item = sony_acpi_values; item->name; ++item) { | ||
330 | device_remove_file(&sncpf_device->dev, &item->devattr); | ||
331 | } | ||
332 | |||
333 | platform_device_del(sncpf_device); | ||
334 | platform_device_put(sncpf_device); | ||
335 | platform_driver_unregister(&sncpf_driver); | ||
336 | } | ||
337 | |||
278 | static int sony_acpi_resume(struct acpi_device *device) | 338 | static int sony_acpi_resume(struct acpi_device *device) |
279 | { | 339 | { |
280 | struct sony_acpi_value *item; | 340 | struct sony_acpi_value *item; |
@@ -284,7 +344,7 @@ static int sony_acpi_resume(struct acpi_device *device) | |||
284 | 344 | ||
285 | if (!item->valid) | 345 | if (!item->valid) |
286 | continue; | 346 | continue; |
287 | ret = acpi_callsetfunc(sony_acpi_handle, item->acpiset, | 347 | ret = acpi_callsetfunc(sony_acpi_handle, *item->acpiset, |
288 | item->value, NULL); | 348 | item->value, NULL); |
289 | if (ret < 0) { | 349 | if (ret < 0) { |
290 | printk("%s: %d\n", __FUNCTION__, ret); | 350 | printk("%s: %d\n", __FUNCTION__, ret); |
@@ -321,16 +381,11 @@ static int sony_acpi_add(struct acpi_device *device) | |||
321 | acpi_status status; | 381 | acpi_status status; |
322 | int result; | 382 | int result; |
323 | acpi_handle handle; | 383 | acpi_handle handle; |
324 | mode_t proc_file_mode; | ||
325 | struct sony_acpi_value *item; | ||
326 | 384 | ||
327 | sony_acpi_acpi_device = device; | 385 | sony_acpi_acpi_device = device; |
328 | 386 | ||
329 | sony_acpi_handle = device->handle; | 387 | sony_acpi_handle = device->handle; |
330 | 388 | ||
331 | acpi_driver_data(device) = NULL; | ||
332 | acpi_device_dir(device) = sony_acpi_dir; | ||
333 | |||
334 | if (debug) { | 389 | if (debug) { |
335 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle, | 390 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle, |
336 | 1, sony_walk_callback, NULL, NULL); | 391 | 1, sony_walk_callback, NULL, NULL); |
@@ -348,7 +403,7 @@ static int sony_acpi_add(struct acpi_device *device) | |||
348 | if (ACPI_FAILURE(status)) { | 403 | if (ACPI_FAILURE(status)) { |
349 | printk(LOG_PFX "unable to install notify handler\n"); | 404 | printk(LOG_PFX "unable to install notify handler\n"); |
350 | result = -ENODEV; | 405 | result = -ENODEV; |
351 | goto outnotify; | 406 | goto outwalk; |
352 | } | 407 | } |
353 | 408 | ||
354 | if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) { | 409 | if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) { |
@@ -364,54 +419,17 @@ static int sony_acpi_add(struct acpi_device *device) | |||
364 | sony_backlight_get_brightness(sony_backlight_device); | 419 | sony_backlight_get_brightness(sony_backlight_device); |
365 | } | 420 | } |
366 | 421 | ||
367 | for (item = sony_acpi_values; item->name; ++item) { | 422 | if (sony_snc_pf_add()) |
368 | proc_file_mode = 0; | 423 | goto outbacklight; |
369 | |||
370 | if (!debug && item->debug) | ||
371 | continue; | ||
372 | |||
373 | if (item->acpiget) { | ||
374 | if (ACPI_FAILURE(acpi_get_handle(sony_acpi_handle, | ||
375 | item->acpiget, &handle))) | ||
376 | continue; | ||
377 | |||
378 | proc_file_mode |= S_IRUSR; | ||
379 | } | ||
380 | |||
381 | if (item->acpiset) { | ||
382 | if (ACPI_FAILURE(acpi_get_handle(sony_acpi_handle, | ||
383 | item->acpiset, &handle))) | ||
384 | continue; | ||
385 | |||
386 | proc_file_mode |= S_IWUSR; | ||
387 | } | ||
388 | |||
389 | item->proc = create_proc_entry(item->name, proc_file_mode, | ||
390 | acpi_device_dir(device)); | ||
391 | if (!item->proc) { | ||
392 | printk(LOG_PFX "unable to create proc entry\n"); | ||
393 | result = -EIO; | ||
394 | goto outproc; | ||
395 | } | ||
396 | |||
397 | item->proc->read_proc = sony_acpi_read; | ||
398 | item->proc->write_proc = sony_acpi_write; | ||
399 | item->proc->data = item; | ||
400 | item->proc->owner = THIS_MODULE; | ||
401 | } | ||
402 | 424 | ||
403 | printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n"); | 425 | printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n"); |
404 | 426 | ||
405 | return 0; | 427 | return 0; |
406 | 428 | ||
407 | outproc: | 429 | outbacklight: |
408 | if (sony_backlight_device) | 430 | if (sony_backlight_device) |
409 | backlight_device_unregister(sony_backlight_device); | 431 | backlight_device_unregister(sony_backlight_device); |
410 | 432 | ||
411 | for (item = sony_acpi_values; item->name; ++item) | ||
412 | if (item->proc) | ||
413 | remove_proc_entry(item->name, acpi_device_dir(device)); | ||
414 | outnotify: | ||
415 | status = acpi_remove_notify_handler(sony_acpi_handle, | 433 | status = acpi_remove_notify_handler(sony_acpi_handle, |
416 | ACPI_DEVICE_NOTIFY, | 434 | ACPI_DEVICE_NOTIFY, |
417 | sony_acpi_notify); | 435 | sony_acpi_notify); |
@@ -424,7 +442,6 @@ outwalk: | |||
424 | static int sony_acpi_remove(struct acpi_device *device, int type) | 442 | static int sony_acpi_remove(struct acpi_device *device, int type) |
425 | { | 443 | { |
426 | acpi_status status; | 444 | acpi_status status; |
427 | struct sony_acpi_value *item; | ||
428 | 445 | ||
429 | if (sony_backlight_device) | 446 | if (sony_backlight_device) |
430 | backlight_device_unregister(sony_backlight_device); | 447 | backlight_device_unregister(sony_backlight_device); |
@@ -437,9 +454,7 @@ static int sony_acpi_remove(struct acpi_device *device, int type) | |||
437 | if (ACPI_FAILURE(status)) | 454 | if (ACPI_FAILURE(status)) |
438 | printk(LOG_PFX "unable to remove notify handler\n"); | 455 | printk(LOG_PFX "unable to remove notify handler\n"); |
439 | 456 | ||
440 | for (item = sony_acpi_values; item->name; ++item) | 457 | sony_snc_pf_remove(); |
441 | if (item->proc) | ||
442 | remove_proc_entry(item->name, acpi_device_dir(device)); | ||
443 | 458 | ||
444 | printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n"); | 459 | printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n"); |
445 | 460 | ||
@@ -476,28 +491,13 @@ static struct acpi_driver sony_acpi_driver = { | |||
476 | 491 | ||
477 | static int __init sony_acpi_init(void) | 492 | static int __init sony_acpi_init(void) |
478 | { | 493 | { |
479 | int result; | 494 | return acpi_bus_register_driver(&sony_acpi_driver); |
480 | |||
481 | sony_acpi_dir = proc_mkdir("sony", acpi_root_dir); | ||
482 | if (!sony_acpi_dir) { | ||
483 | printk(LOG_PFX "unable to create /proc entry\n"); | ||
484 | return -ENODEV; | ||
485 | } | ||
486 | sony_acpi_dir->owner = THIS_MODULE; | ||
487 | |||
488 | result = acpi_bus_register_driver(&sony_acpi_driver); | ||
489 | if (result < 0) { | ||
490 | remove_proc_entry("sony", acpi_root_dir); | ||
491 | return -ENODEV; | ||
492 | } | ||
493 | return 0; | ||
494 | } | 495 | } |
495 | 496 | ||
496 | 497 | ||
497 | static void __exit sony_acpi_exit(void) | 498 | static void __exit sony_acpi_exit(void) |
498 | { | 499 | { |
499 | acpi_bus_unregister_driver(&sony_acpi_driver); | 500 | acpi_bus_unregister_driver(&sony_acpi_driver); |
500 | remove_proc_entry("sony", acpi_root_dir); | ||
501 | } | 501 | } |
502 | 502 | ||
503 | module_init(sony_acpi_init); | 503 | module_init(sony_acpi_init); |