OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [acpi/] [fan.c] - Blame information for rev 67

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  acpi_fan.c - ACPI Fan Driver ($Revision: 29 $)
3
 *
4
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6
 *
7
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or (at
12
 *  your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful, but
15
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 *  General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License along
20
 *  with this program; if not, write to the Free Software Foundation, Inc.,
21
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22
 *
23
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24
 */
25
 
26
#include <linux/kernel.h>
27
#include <linux/module.h>
28
#include <linux/init.h>
29
#include <linux/types.h>
30
#include <linux/proc_fs.h>
31
#include <linux/seq_file.h>
32
#include <asm/uaccess.h>
33
 
34
#include <acpi/acpi_bus.h>
35
#include <acpi/acpi_drivers.h>
36
 
37
#define ACPI_FAN_COMPONENT              0x00200000
38
#define ACPI_FAN_CLASS                  "fan"
39
#define ACPI_FAN_FILE_STATE             "state"
40
 
41
#define _COMPONENT              ACPI_FAN_COMPONENT
42
ACPI_MODULE_NAME("fan");
43
 
44
MODULE_AUTHOR("Paul Diefenbaugh");
45
MODULE_DESCRIPTION("ACPI Fan Driver");
46
MODULE_LICENSE("GPL");
47
 
48
static int acpi_fan_add(struct acpi_device *device);
49
static int acpi_fan_remove(struct acpi_device *device, int type);
50
static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
51
static int acpi_fan_resume(struct acpi_device *device);
52
 
53
static const struct acpi_device_id fan_device_ids[] = {
54
        {"PNP0C0B", 0},
55
        {"", 0},
56
};
57
MODULE_DEVICE_TABLE(acpi, fan_device_ids);
58
 
59
static struct acpi_driver acpi_fan_driver = {
60
        .name = "fan",
61
        .class = ACPI_FAN_CLASS,
62
        .ids = fan_device_ids,
63
        .ops = {
64
                .add = acpi_fan_add,
65
                .remove = acpi_fan_remove,
66
                .suspend = acpi_fan_suspend,
67
                .resume = acpi_fan_resume,
68
                },
69
};
70
 
71
/* --------------------------------------------------------------------------
72
                              FS Interface (/proc)
73
   -------------------------------------------------------------------------- */
74
 
75
static struct proc_dir_entry *acpi_fan_dir;
76
 
77
static int acpi_fan_read_state(struct seq_file *seq, void *offset)
78
{
79
        struct acpi_device *device = seq->private;
80
        int state = 0;
81
 
82
 
83
        if (device) {
84
                if (acpi_bus_get_power(device->handle, &state))
85
                        seq_printf(seq, "status:                  ERROR\n");
86
                else
87
                        seq_printf(seq, "status:                  %s\n",
88
                                   !state ? "on" : "off");
89
        }
90
        return 0;
91
}
92
 
93
static int acpi_fan_state_open_fs(struct inode *inode, struct file *file)
94
{
95
        return single_open(file, acpi_fan_read_state, PDE(inode)->data);
96
}
97
 
98
static ssize_t
99
acpi_fan_write_state(struct file *file, const char __user * buffer,
100
                     size_t count, loff_t * ppos)
101
{
102
        int result = 0;
103
        struct seq_file *m = file->private_data;
104
        struct acpi_device *device = m->private;
105
        char state_string[12] = { '\0' };
106
 
107
        if (count > sizeof(state_string) - 1)
108
                return -EINVAL;
109
 
110
        if (copy_from_user(state_string, buffer, count))
111
                return -EFAULT;
112
 
113
        state_string[count] = '\0';
114
 
115
        result = acpi_bus_set_power(device->handle,
116
                                    simple_strtoul(state_string, NULL, 0));
117
        if (result)
118
                return result;
119
 
120
        return count;
121
}
122
 
123
static const struct file_operations acpi_fan_state_ops = {
124
        .open = acpi_fan_state_open_fs,
125
        .read = seq_read,
126
        .write = acpi_fan_write_state,
127
        .llseek = seq_lseek,
128
        .release = single_release,
129
        .owner = THIS_MODULE,
130
};
131
 
132
static int acpi_fan_add_fs(struct acpi_device *device)
133
{
134
        struct proc_dir_entry *entry = NULL;
135
 
136
 
137
        if (!device)
138
                return -EINVAL;
139
 
140
        if (!acpi_device_dir(device)) {
141
                acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
142
                                                     acpi_fan_dir);
143
                if (!acpi_device_dir(device))
144
                        return -ENODEV;
145
                acpi_device_dir(device)->owner = THIS_MODULE;
146
        }
147
 
148
        /* 'status' [R/W] */
149
        entry = create_proc_entry(ACPI_FAN_FILE_STATE,
150
                                  S_IFREG | S_IRUGO | S_IWUSR,
151
                                  acpi_device_dir(device));
152
        if (!entry)
153
                return -ENODEV;
154
        else {
155
                entry->proc_fops = &acpi_fan_state_ops;
156
                entry->data = device;
157
                entry->owner = THIS_MODULE;
158
        }
159
 
160
        return 0;
161
}
162
 
163
static int acpi_fan_remove_fs(struct acpi_device *device)
164
{
165
 
166
        if (acpi_device_dir(device)) {
167
                remove_proc_entry(ACPI_FAN_FILE_STATE, acpi_device_dir(device));
168
                remove_proc_entry(acpi_device_bid(device), acpi_fan_dir);
169
                acpi_device_dir(device) = NULL;
170
        }
171
 
172
        return 0;
173
}
174
 
175
/* --------------------------------------------------------------------------
176
                                 Driver Interface
177
   -------------------------------------------------------------------------- */
178
 
179
static int acpi_fan_add(struct acpi_device *device)
180
{
181
        int result = 0;
182
        struct acpi_fan *fan = NULL;
183
        int state = 0;
184
 
185
 
186
        if (!device)
187
                return -EINVAL;
188
 
189
        strcpy(acpi_device_name(device), "Fan");
190
        strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
191
 
192
        result = acpi_bus_get_power(device->handle, &state);
193
        if (result) {
194
                printk(KERN_ERR PREFIX "Reading power state\n");
195
                goto end;
196
        }
197
 
198
        device->flags.force_power_state = 1;
199
        acpi_bus_set_power(device->handle, state);
200
        device->flags.force_power_state = 0;
201
 
202
        result = acpi_fan_add_fs(device);
203
        if (result)
204
                goto end;
205
 
206
        printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
207
               acpi_device_name(device), acpi_device_bid(device),
208
               !device->power.state ? "on" : "off");
209
 
210
      end:
211
        if (result)
212
                kfree(fan);
213
 
214
        return result;
215
}
216
 
217
static int acpi_fan_remove(struct acpi_device *device, int type)
218
{
219
        if (!device || !acpi_driver_data(device))
220
                return -EINVAL;
221
 
222
        acpi_fan_remove_fs(device);
223
 
224
        return 0;
225
}
226
 
227
static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
228
{
229
        if (!device)
230
                return -EINVAL;
231
 
232
        acpi_bus_set_power(device->handle, ACPI_STATE_D0);
233
 
234
        return AE_OK;
235
}
236
 
237
static int acpi_fan_resume(struct acpi_device *device)
238
{
239
        int result = 0;
240
        int power_state = 0;
241
 
242
        if (!device)
243
                return -EINVAL;
244
 
245
        result = acpi_bus_get_power(device->handle, &power_state);
246
        if (result) {
247
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
248
                                  "Error reading fan power state\n"));
249
                return result;
250
        }
251
 
252
        device->flags.force_power_state = 1;
253
        acpi_bus_set_power(device->handle, power_state);
254
        device->flags.force_power_state = 0;
255
 
256
        return result;
257
}
258
 
259
static int __init acpi_fan_init(void)
260
{
261
        int result = 0;
262
 
263
 
264
        acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir);
265
        if (!acpi_fan_dir)
266
                return -ENODEV;
267
        acpi_fan_dir->owner = THIS_MODULE;
268
 
269
        result = acpi_bus_register_driver(&acpi_fan_driver);
270
        if (result < 0) {
271
                remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
272
                return -ENODEV;
273
        }
274
 
275
        return 0;
276
}
277
 
278
static void __exit acpi_fan_exit(void)
279
{
280
 
281
        acpi_bus_unregister_driver(&acpi_fan_driver);
282
 
283
        remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
284
 
285
        return;
286
}
287
 
288
module_init(acpi_fan_init);
289
module_exit(acpi_fan_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.