File: /usr/src/linux/drivers/acpi/ospm/ac_adapter/ac_osl.c

1     /*****************************************************************************
2      *
3      * Module Name: ac_osl.c
4      *   $Revision: 9 $
5      *
6      *****************************************************************************/
7     
8     /*
9      *  Copyright (C) 2000, 2001 Andrew Grover
10      *
11      *  This program is free software; you can redistribute it and/or modify
12      *  it under the terms of the GNU General Public License as published by
13      *  the Free Software Foundation; either version 2 of the License, or
14      *  (at your option) any later version.
15      *
16      *  This program is distributed in the hope that it will be useful,
17      *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18      *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19      *  GNU General Public License for more details.
20      *
21      *  You should have received a copy of the GNU General Public License
22      *  along with this program; if not, write to the Free Software
23      *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24      */
25     
26     
27     #include <linux/kernel.h>
28     #include <linux/module.h>
29     #include <linux/init.h>
30     #include <linux/types.h>
31     #include <linux/proc_fs.h>
32     #include <acpi.h>
33     #include "ac.h"
34     
35     
36     MODULE_AUTHOR("Andrew Grover");
37     MODULE_DESCRIPTION("ACPI Component Architecture (CA) - AC Adapter Driver");
38     MODULE_LICENSE("GPL");
39     
40     
41     #define AC_PROC_ROOT		"ac_adapter"
42     #define AC_PROC_STATUS		"status"
43     #define AC_ON_LINE		"on-line"
44     #define AC_OFF_LINE		"off-line"
45     
46     extern struct proc_dir_entry	*bm_proc_root;
47     static struct proc_dir_entry	*ac_proc_root = NULL;
48     
49     
50     /****************************************************************************
51      *
52      * FUNCTION:	ac_osl_proc_read_status
53      *
54      ****************************************************************************/
55     
56     static int
57     ac_osl_proc_read_status (
58     	char			*page,
59     	char			**start,
60     	off_t			off,
61     	int 			count,
62     	int 			*eof,
63     	void			*context)
64     {
65     	acpi_status 		status = AE_OK;
66     	AC_CONTEXT		*ac_adapter = NULL;
67     	char			*p = page;
68     	int			len;
69     
70     	if (!context) {
71     		goto end;
72     	}
73     
74     	ac_adapter = (AC_CONTEXT*)context;
75     
76     	/* don't get status more than once for a single proc read */
77     	if (off != 0) {
78     		goto end;
79     	}
80     
81     	status = bm_evaluate_simple_integer(ac_adapter->acpi_handle,
82     		"_PSR", &(ac_adapter->is_online));
83     	if (ACPI_FAILURE(status)) {
84     		p += sprintf(p, "Error reading AC Adapter status\n");
85     		goto end;
86     	}
87     
88     	if (ac_adapter->is_online) {
89     		p += sprintf(p, "Status:                  %s\n",
90     			AC_ON_LINE);
91     	}
92     	else {
93     		p += sprintf(p, "Status:                  %s\n",
94     			AC_OFF_LINE);
95     	}
96     
97     end:
98     	len = (p - page);
99     	if (len <= off+count) *eof = 1;
100     	*start = page + off;
101     	len -= off;
102     	if (len>count) len = count;
103     	if (len<0) len = 0;
104     
105     	return(len);
106     }
107     
108     
109     /****************************************************************************
110      *
111      * FUNCTION:	ac_osl_add_device
112      *
113      ****************************************************************************/
114     
115     acpi_status
116     ac_osl_add_device(
117     	AC_CONTEXT		*ac_adapter)
118     {
119     	struct proc_dir_entry	*proc_entry = NULL;
120     
121     	if (!ac_adapter) {
122     		return(AE_BAD_PARAMETER);
123     	}
124     
125     	printk(KERN_INFO "AC Adapter: found\n");
126     
127     	proc_entry = proc_mkdir(ac_adapter->uid, ac_proc_root);
128     	if (!proc_entry) {
129     		return(AE_ERROR);
130     	}
131     
132     	create_proc_read_entry(AC_PROC_STATUS, S_IFREG | S_IRUGO,
133     		proc_entry, ac_osl_proc_read_status, (void*)ac_adapter);
134     
135     	return(AE_OK);
136     }
137     
138     
139     /****************************************************************************
140      *
141      * FUNCTION:	ac_osl_remove_device
142      *
143      ****************************************************************************/
144     
145     acpi_status
146     ac_osl_remove_device (
147     	AC_CONTEXT		*ac_adapter)
148     {
149     	char			proc_entry[64];
150     
151     	if (!ac_adapter) {
152     		return(AE_BAD_PARAMETER);
153     	}
154     
155     	sprintf(proc_entry, "%s/%s", ac_adapter->uid, AC_PROC_STATUS);
156     	remove_proc_entry(proc_entry, ac_proc_root);
157     
158     	sprintf(proc_entry, "%s", ac_adapter->uid);
159     	remove_proc_entry(proc_entry, ac_proc_root);
160     
161     	return(AE_OK);
162     }
163     
164     
165     /****************************************************************************
166      *
167      * FUNCTION:	ac_osl_generate_event
168      *
169      ****************************************************************************/
170     
171     acpi_status
172     ac_osl_generate_event (
173     	u32			event,
174     	AC_CONTEXT		*ac_adapter)
175     {
176     	acpi_status		status = AE_OK;
177     
178     	if (!ac_adapter) {
179     		return(AE_BAD_PARAMETER);
180     	}
181     
182     	switch (event) {
183     
184     	case AC_NOTIFY_STATUS_CHANGE:
185     		status = bm_osl_generate_event(ac_adapter->device_handle,
186     			AC_PROC_ROOT, ac_adapter->uid, event, 0);
187     		break;
188     
189     	default:
190     		return(AE_BAD_PARAMETER);
191     		break;
192     	}
193     
194     	return(status);
195     }
196     
197     
198     /****************************************************************************
199      *
200      * FUNCTION:	ac_osl_init
201      *
202      * PARAMETERS:	<none>
203      *
204      * RETURN:	0: Success
205      *
206      * DESCRIPTION: Module initialization.
207      *
208      ****************************************************************************/
209     
210     static int __init
211     ac_osl_init (void)
212     {
213     	acpi_status		status = AE_OK;
214     
215     	ac_proc_root = proc_mkdir(AC_PROC_ROOT, bm_proc_root);
216     	if (!ac_proc_root) {
217     		status = AE_ERROR;
218     	}
219     	else {
220     		status = ac_initialize();
221     		if (ACPI_FAILURE(status)) {
222     			remove_proc_entry(AC_PROC_ROOT, bm_proc_root);
223     		}
224     
225     	}
226     
227     	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
228     }
229     
230     
231     /****************************************************************************
232      *
233      * FUNCTION:	ac_osl_cleanup
234      *
235      * PARAMETERS:	<none>
236      *
237      * RETURN:	<none>
238      *
239      * DESCRIPTION: Module cleanup.
240      *
241      ****************************************************************************/
242     
243     static void __exit
244     ac_osl_cleanup (void)
245     {
246     	ac_terminate();
247     
248     	if (ac_proc_root) {
249     		remove_proc_entry(AC_PROC_ROOT, bm_proc_root);
250     	}
251     
252     	return;
253     }
254     
255     
256     module_init(ac_osl_init);
257     module_exit(ac_osl_cleanup);
258