aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/fan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/fan.c')
-rw-r--r--drivers/acpi/fan.c166
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
126static struct proc_dir_entry *acpi_fan_dir;
127
128static 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
144static 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
149static ssize_t
150acpi_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
180static 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
189static 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
215static 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
227static int acpi_fan_add_fs(struct acpi_device *device)
228{
229 return 0;
230}
231
232static 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
241static int acpi_fan_add(struct acpi_device *device) 123static 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
324static int acpi_fan_resume(struct acpi_device *device) 196static 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