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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [ac.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  acpi_ac.c - ACPI AC Adapter Driver ($Revision: 1.1.1.1 $)
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/compatmac.h>
31
#include <linux/proc_fs.h>
32
#include <acpi/acpi_bus.h>
33
#include <acpi/acpi_drivers.h>
34
 
35
 
36
#define _COMPONENT              ACPI_AC_COMPONENT
37
ACPI_MODULE_NAME                ("acpi_ac")
38
 
39
MODULE_AUTHOR("Paul Diefenbaugh");
40
MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME);
41
MODULE_LICENSE("GPL");
42
 
43
#define PREFIX                  "ACPI: "
44
 
45
 
46
int acpi_ac_add (struct acpi_device *device);
47
int acpi_ac_remove (struct acpi_device *device, int type);
48
 
49
static struct acpi_driver acpi_ac_driver = {
50
        .name =         ACPI_AC_DRIVER_NAME,
51
        .class =        ACPI_AC_CLASS,
52
        .ids =          ACPI_AC_HID,
53
        .ops =          {
54
                                .add =          acpi_ac_add,
55
                                .remove =       acpi_ac_remove,
56
                        },
57
};
58
 
59
struct acpi_ac {
60
        acpi_handle             handle;
61
        unsigned long           state;
62
};
63
 
64
 
65
/* --------------------------------------------------------------------------
66
                               AC Adapter Management
67
   -------------------------------------------------------------------------- */
68
 
69
static int
70
acpi_ac_get_state (
71
        struct acpi_ac          *ac)
72
{
73
        acpi_status             status = AE_OK;
74
 
75
        ACPI_FUNCTION_TRACE("acpi_ac_get_state");
76
 
77
        if (!ac)
78
                return_VALUE(-EINVAL);
79
 
80
        status = acpi_evaluate_integer(ac->handle, "_PSR", NULL, &ac->state);
81
        if (ACPI_FAILURE(status)) {
82
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
83
                        "Error reading AC Adapter state\n"));
84
                ac->state = ACPI_AC_STATUS_UNKNOWN;
85
                return_VALUE(-ENODEV);
86
        }
87
 
88
        return_VALUE(0);
89
}
90
 
91
 
92
/* --------------------------------------------------------------------------
93
                              FS Interface (/proc)
94
   -------------------------------------------------------------------------- */
95
 
96
struct proc_dir_entry           *acpi_ac_dir;
97
 
98
static int
99
acpi_ac_read_state (
100
        char                    *page,
101
        char                    **start,
102
        off_t                   off,
103
        int                     count,
104
        int                     *eof,
105
        void                    *data)
106
{
107
        struct acpi_ac          *ac = (struct acpi_ac *) data;
108
        char                    *p = page;
109
        int                     len = 0;
110
 
111
        ACPI_FUNCTION_TRACE("acpi_ac_read_state");
112
 
113
        if (!ac || (off != 0))
114
                goto end;
115
 
116
        if (acpi_ac_get_state(ac)) {
117
                p += sprintf(p, "ERROR: Unable to read AC Adapter state\n");
118
                goto end;
119
        }
120
 
121
        p += sprintf(p, "state:                   ");
122
        switch (ac->state) {
123
        case ACPI_AC_STATUS_OFFLINE:
124
                p += sprintf(p, "off-line\n");
125
                break;
126
        case ACPI_AC_STATUS_ONLINE:
127
                p += sprintf(p, "on-line\n");
128
                break;
129
        default:
130
                p += sprintf(p, "unknown\n");
131
                break;
132
        }
133
 
134
end:
135
        len = (p - page);
136
        if (len <= off+count) *eof = 1;
137
        *start = page + off;
138
        len -= off;
139
        if (len>count) len = count;
140
        if (len<0) len = 0;
141
 
142
        return_VALUE(len);
143
}
144
 
145
 
146
static int
147
acpi_ac_add_fs (
148
        struct acpi_device      *device)
149
{
150
        struct proc_dir_entry   *entry = NULL;
151
 
152
        ACPI_FUNCTION_TRACE("acpi_ac_add_fs");
153
 
154
        if (!acpi_device_dir(device)) {
155
                acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
156
                        acpi_ac_dir);
157
                if (!acpi_device_dir(device))
158
                        return_VALUE(-ENODEV);
159
        }
160
 
161
        /* 'state' [R] */
162
        entry = create_proc_entry(ACPI_AC_FILE_STATE,
163
                S_IRUGO, acpi_device_dir(device));
164
        if (!entry)
165
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
166
                        "Unable to create '%s' fs entry\n",
167
                        ACPI_AC_FILE_STATE));
168
        else {
169
                entry->read_proc = acpi_ac_read_state;
170
                entry->data = acpi_driver_data(device);
171
        }
172
 
173
        return_VALUE(0);
174
}
175
 
176
 
177
static int
178
acpi_ac_remove_fs (
179
        struct acpi_device      *device)
180
{
181
        ACPI_FUNCTION_TRACE("acpi_ac_remove_fs");
182
 
183
        if (acpi_device_dir(device)) {
184
                remove_proc_entry(acpi_device_bid(device), acpi_ac_dir);
185
                acpi_device_dir(device) = NULL;
186
        }
187
 
188
        return_VALUE(0);
189
}
190
 
191
 
192
/* --------------------------------------------------------------------------
193
                                   Driver Model
194
   -------------------------------------------------------------------------- */
195
 
196
void
197
acpi_ac_notify (
198
        acpi_handle             handle,
199
        u32                     event,
200
        void                    *data)
201
{
202
        struct acpi_ac          *ac = (struct acpi_ac *) data;
203
        struct acpi_device      *device = NULL;
204
 
205
        ACPI_FUNCTION_TRACE("acpi_ac_notify");
206
 
207
        if (!ac)
208
                return;
209
 
210
        if (acpi_bus_get_device(ac->handle, &device))
211
                return_VOID;
212
 
213
        switch (event) {
214
        case ACPI_AC_NOTIFY_STATUS:
215
                acpi_ac_get_state(ac);
216
                acpi_bus_generate_event(device, event, (u32) ac->state);
217
                break;
218
        default:
219
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
220
                        "Unsupported event [0x%x]\n", event));
221
                break;
222
        }
223
 
224
        return_VOID;
225
}
226
 
227
 
228
int
229
acpi_ac_add (
230
        struct acpi_device      *device)
231
{
232
        int                     result = 0;
233
        acpi_status             status = AE_OK;
234
        struct acpi_ac          *ac = NULL;
235
 
236
        ACPI_FUNCTION_TRACE("acpi_ac_add");
237
 
238
        if (!device)
239
                return_VALUE(-EINVAL);
240
 
241
        ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL);
242
        if (!ac)
243
                return_VALUE(-ENOMEM);
244
        memset(ac, 0, sizeof(struct acpi_ac));
245
 
246
        ac->handle = device->handle;
247
        sprintf(acpi_device_name(device), "%s", ACPI_AC_DEVICE_NAME);
248
        sprintf(acpi_device_class(device), "%s", ACPI_AC_CLASS);
249
        acpi_driver_data(device) = ac;
250
 
251
        result = acpi_ac_get_state(ac);
252
        if (result)
253
                goto end;
254
 
255
        result = acpi_ac_add_fs(device);
256
        if (result)
257
                goto end;
258
 
259
        status = acpi_install_notify_handler(ac->handle,
260
                ACPI_DEVICE_NOTIFY, acpi_ac_notify, ac);
261
        if (ACPI_FAILURE(status)) {
262
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
263
                        "Error installing notify handler\n"));
264
                result = -ENODEV;
265
                goto end;
266
        }
267
 
268
        printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
269
                acpi_device_name(device), acpi_device_bid(device),
270
                ac->state?"on-line":"off-line");
271
 
272
end:
273
        if (result) {
274
                acpi_ac_remove_fs(device);
275
                kfree(ac);
276
        }
277
 
278
        return_VALUE(result);
279
}
280
 
281
 
282
int
283
acpi_ac_remove (
284
        struct acpi_device      *device,
285
        int                     type)
286
{
287
        acpi_status             status = AE_OK;
288
        struct acpi_ac          *ac = NULL;
289
 
290
        ACPI_FUNCTION_TRACE("acpi_ac_remove");
291
 
292
        if (!device || !acpi_driver_data(device))
293
                return_VALUE(-EINVAL);
294
 
295
        ac = (struct acpi_ac *) acpi_driver_data(device);
296
 
297
        status = acpi_remove_notify_handler(ac->handle,
298
                ACPI_DEVICE_NOTIFY, acpi_ac_notify);
299
        if (ACPI_FAILURE(status))
300
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
301
                        "Error removing notify handler\n"));
302
 
303
        acpi_ac_remove_fs(device);
304
 
305
        kfree(ac);
306
 
307
        return_VALUE(0);
308
}
309
 
310
 
311
int __init
312
acpi_ac_init (void)
313
{
314
        int                     result = 0;
315
 
316
        ACPI_FUNCTION_TRACE("acpi_ac_init");
317
 
318
        acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir);
319
        if (!acpi_ac_dir)
320
                return_VALUE(-ENODEV);
321
 
322
        result = acpi_bus_register_driver(&acpi_ac_driver);
323
        if (result < 0) {
324
                remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
325
                return_VALUE(-ENODEV);
326
        }
327
 
328
        return_VALUE(0);
329
}
330
 
331
 
332
void __exit
333
acpi_ac_exit (void)
334
{
335
        ACPI_FUNCTION_TRACE("acpi_ac_exit");
336
 
337
        acpi_bus_unregister_driver(&acpi_ac_driver);
338
 
339
        remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
340
 
341
        return_VOID;
342
}
343
 
344
 
345
module_init(acpi_ac_init);
346
module_exit(acpi_ac_exit);

powered by: WebSVN 2.1.0

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