diff options
Diffstat (limited to 'drivers/acpi/fan.c')
-rw-r--r-- | drivers/acpi/fan.c | 166 |
1 files changed, 8 insertions, 158 deletions
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index d94d2953c974..467479f07c1f 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -27,8 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/seq_file.h> | ||
32 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
33 | #include <linux/thermal.h> | 31 | #include <linux/thermal.h> |
34 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
@@ -88,7 +86,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long | |||
88 | if (!device) | 86 | if (!device) |
89 | return -EINVAL; | 87 | return -EINVAL; |
90 | 88 | ||
91 | result = acpi_bus_get_power(device->handle, &acpi_state); | 89 | result = acpi_bus_update_power(device->handle, &acpi_state); |
92 | if (result) | 90 | if (result) |
93 | return result; | 91 | return result; |
94 | 92 | ||
@@ -119,129 +117,12 @@ static struct thermal_cooling_device_ops fan_cooling_ops = { | |||
119 | }; | 117 | }; |
120 | 118 | ||
121 | /* -------------------------------------------------------------------------- | 119 | /* -------------------------------------------------------------------------- |
122 | FS Interface (/proc) | ||
123 | -------------------------------------------------------------------------- */ | ||
124 | #ifdef CONFIG_ACPI_PROCFS | ||
125 | |||
126 | static struct proc_dir_entry *acpi_fan_dir; | ||
127 | |||
128 | static int acpi_fan_read_state(struct seq_file *seq, void *offset) | ||
129 | { | ||
130 | struct acpi_device *device = seq->private; | ||
131 | int state = 0; | ||
132 | |||
133 | |||
134 | if (device) { | ||
135 | if (acpi_bus_get_power(device->handle, &state)) | ||
136 | seq_printf(seq, "status: ERROR\n"); | ||
137 | else | ||
138 | seq_printf(seq, "status: %s\n", | ||
139 | !state ? "on" : "off"); | ||
140 | } | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int acpi_fan_state_open_fs(struct inode *inode, struct file *file) | ||
145 | { | ||
146 | return single_open(file, acpi_fan_read_state, PDE(inode)->data); | ||
147 | } | ||
148 | |||
149 | static ssize_t | ||
150 | acpi_fan_write_state(struct file *file, const char __user * buffer, | ||
151 | size_t count, loff_t * ppos) | ||
152 | { | ||
153 | int result = 0; | ||
154 | struct seq_file *m = file->private_data; | ||
155 | struct acpi_device *device = m->private; | ||
156 | char state_string[3] = { '\0' }; | ||
157 | |||
158 | if (count > sizeof(state_string) - 1) | ||
159 | return -EINVAL; | ||
160 | |||
161 | if (copy_from_user(state_string, buffer, count)) | ||
162 | return -EFAULT; | ||
163 | |||
164 | state_string[count] = '\0'; | ||
165 | if ((state_string[0] < '0') || (state_string[0] > '3')) | ||
166 | return -EINVAL; | ||
167 | if (state_string[1] == '\n') | ||
168 | state_string[1] = '\0'; | ||
169 | if (state_string[1] != '\0') | ||
170 | return -EINVAL; | ||
171 | |||
172 | result = acpi_bus_set_power(device->handle, | ||
173 | simple_strtoul(state_string, NULL, 0)); | ||
174 | if (result) | ||
175 | return result; | ||
176 | |||
177 | return count; | ||
178 | } | ||
179 | |||
180 | static const struct file_operations acpi_fan_state_ops = { | ||
181 | .open = acpi_fan_state_open_fs, | ||
182 | .read = seq_read, | ||
183 | .write = acpi_fan_write_state, | ||
184 | .llseek = seq_lseek, | ||
185 | .release = single_release, | ||
186 | .owner = THIS_MODULE, | ||
187 | }; | ||
188 | |||
189 | static int acpi_fan_add_fs(struct acpi_device *device) | ||
190 | { | ||
191 | struct proc_dir_entry *entry = NULL; | ||
192 | |||
193 | |||
194 | if (!device) | ||
195 | return -EINVAL; | ||
196 | |||
197 | if (!acpi_device_dir(device)) { | ||
198 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
199 | acpi_fan_dir); | ||
200 | if (!acpi_device_dir(device)) | ||
201 | return -ENODEV; | ||
202 | } | ||
203 | |||
204 | /* 'status' [R/W] */ | ||
205 | entry = proc_create_data(ACPI_FAN_FILE_STATE, | ||
206 | S_IFREG | S_IRUGO | S_IWUSR, | ||
207 | acpi_device_dir(device), | ||
208 | &acpi_fan_state_ops, | ||
209 | device); | ||
210 | if (!entry) | ||
211 | return -ENODEV; | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static int acpi_fan_remove_fs(struct acpi_device *device) | ||
216 | { | ||
217 | |||
218 | if (acpi_device_dir(device)) { | ||
219 | remove_proc_entry(ACPI_FAN_FILE_STATE, acpi_device_dir(device)); | ||
220 | remove_proc_entry(acpi_device_bid(device), acpi_fan_dir); | ||
221 | acpi_device_dir(device) = NULL; | ||
222 | } | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | #else | ||
227 | static int acpi_fan_add_fs(struct acpi_device *device) | ||
228 | { | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static int acpi_fan_remove_fs(struct acpi_device *device) | ||
233 | { | ||
234 | return 0; | ||
235 | } | ||
236 | #endif | ||
237 | /* -------------------------------------------------------------------------- | ||
238 | Driver Interface | 120 | Driver Interface |
239 | -------------------------------------------------------------------------- */ | 121 | -------------------------------------------------------------------------- */ |
240 | 122 | ||
241 | static int acpi_fan_add(struct acpi_device *device) | 123 | static int acpi_fan_add(struct acpi_device *device) |
242 | { | 124 | { |
243 | int result = 0; | 125 | int result = 0; |
244 | int state = 0; | ||
245 | struct thermal_cooling_device *cdev; | 126 | struct thermal_cooling_device *cdev; |
246 | 127 | ||
247 | if (!device) | 128 | if (!device) |
@@ -250,16 +131,12 @@ static int acpi_fan_add(struct acpi_device *device) | |||
250 | strcpy(acpi_device_name(device), "Fan"); | 131 | strcpy(acpi_device_name(device), "Fan"); |
251 | strcpy(acpi_device_class(device), ACPI_FAN_CLASS); | 132 | strcpy(acpi_device_class(device), ACPI_FAN_CLASS); |
252 | 133 | ||
253 | result = acpi_bus_get_power(device->handle, &state); | 134 | result = acpi_bus_update_power(device->handle, NULL); |
254 | if (result) { | 135 | if (result) { |
255 | printk(KERN_ERR PREFIX "Reading power state\n"); | 136 | printk(KERN_ERR PREFIX "Setting initial power state\n"); |
256 | goto end; | 137 | goto end; |
257 | } | 138 | } |
258 | 139 | ||
259 | device->flags.force_power_state = 1; | ||
260 | acpi_bus_set_power(device->handle, state); | ||
261 | device->flags.force_power_state = 0; | ||
262 | |||
263 | cdev = thermal_cooling_device_register("Fan", device, | 140 | cdev = thermal_cooling_device_register("Fan", device, |
264 | &fan_cooling_ops); | 141 | &fan_cooling_ops); |
265 | if (IS_ERR(cdev)) { | 142 | if (IS_ERR(cdev)) { |
@@ -284,10 +161,6 @@ static int acpi_fan_add(struct acpi_device *device) | |||
284 | dev_err(&device->dev, "Failed to create sysfs link " | 161 | dev_err(&device->dev, "Failed to create sysfs link " |
285 | "'device'\n"); | 162 | "'device'\n"); |
286 | 163 | ||
287 | result = acpi_fan_add_fs(device); | ||
288 | if (result) | ||
289 | goto end; | ||
290 | |||
291 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 164 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", |
292 | acpi_device_name(device), acpi_device_bid(device), | 165 | acpi_device_name(device), acpi_device_bid(device), |
293 | !device->power.state ? "on" : "off"); | 166 | !device->power.state ? "on" : "off"); |
@@ -303,7 +176,6 @@ static int acpi_fan_remove(struct acpi_device *device, int type) | |||
303 | if (!device || !cdev) | 176 | if (!device || !cdev) |
304 | return -EINVAL; | 177 | return -EINVAL; |
305 | 178 | ||
306 | acpi_fan_remove_fs(device); | ||
307 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | 179 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); |
308 | sysfs_remove_link(&cdev->device.kobj, "device"); | 180 | sysfs_remove_link(&cdev->device.kobj, "device"); |
309 | thermal_cooling_device_unregister(cdev); | 181 | thermal_cooling_device_unregister(cdev); |
@@ -323,22 +195,14 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state) | |||
323 | 195 | ||
324 | static int acpi_fan_resume(struct acpi_device *device) | 196 | static int acpi_fan_resume(struct acpi_device *device) |
325 | { | 197 | { |
326 | int result = 0; | 198 | int result; |
327 | int power_state = 0; | ||
328 | 199 | ||
329 | if (!device) | 200 | if (!device) |
330 | return -EINVAL; | 201 | return -EINVAL; |
331 | 202 | ||
332 | result = acpi_bus_get_power(device->handle, &power_state); | 203 | result = acpi_bus_update_power(device->handle, NULL); |
333 | if (result) { | 204 | if (result) |
334 | printk(KERN_ERR PREFIX | 205 | printk(KERN_ERR PREFIX "Error updating fan power state\n"); |
335 | "Error reading fan power state\n"); | ||
336 | return result; | ||
337 | } | ||
338 | |||
339 | device->flags.force_power_state = 1; | ||
340 | acpi_bus_set_power(device->handle, power_state); | ||
341 | device->flags.force_power_state = 0; | ||
342 | 206 | ||
343 | return result; | 207 | return result; |
344 | } | 208 | } |
@@ -347,19 +211,9 @@ static int __init acpi_fan_init(void) | |||
347 | { | 211 | { |
348 | int result = 0; | 212 | int result = 0; |
349 | 213 | ||
350 | #ifdef CONFIG_ACPI_PROCFS | ||
351 | acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); | ||
352 | if (!acpi_fan_dir) | ||
353 | return -ENODEV; | ||
354 | #endif | ||
355 | |||
356 | result = acpi_bus_register_driver(&acpi_fan_driver); | 214 | result = acpi_bus_register_driver(&acpi_fan_driver); |
357 | if (result < 0) { | 215 | if (result < 0) |
358 | #ifdef CONFIG_ACPI_PROCFS | ||
359 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); | ||
360 | #endif | ||
361 | return -ENODEV; | 216 | return -ENODEV; |
362 | } | ||
363 | 217 | ||
364 | return 0; | 218 | return 0; |
365 | } | 219 | } |
@@ -369,10 +223,6 @@ static void __exit acpi_fan_exit(void) | |||
369 | 223 | ||
370 | acpi_bus_unregister_driver(&acpi_fan_driver); | 224 | acpi_bus_unregister_driver(&acpi_fan_driver); |
371 | 225 | ||
372 | #ifdef CONFIG_ACPI_PROCFS | ||
373 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); | ||
374 | #endif | ||
375 | |||
376 | return; | 226 | return; |
377 | } | 227 | } |
378 | 228 | ||