File: /usr/src/linux/drivers/acpi/ospm/thermal/tz_osl.c

1     /******************************************************************************
2      *
3      * Module Name: tz_osl.c
4      *   $Revision: 21 $
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 "tz.h"
34     
35     
36     MODULE_AUTHOR("Andrew Grover");
37     MODULE_DESCRIPTION("ACPI Component Architecture (CA) - Thermal Zone Driver");
38     MODULE_LICENSE("GPL");
39     
40     int TZP = 0;
41     MODULE_PARM(TZP, "i");
42     MODULE_PARM_DESC(TZP, "Thermal zone polling frequency, in 1/10 seconds.\n");
43     
44     
45     #define TZ_PROC_ROOT		"thermal"
46     #define TZ_PROC_STATUS		"status"
47     #define TZ_PROC_INFO		"info"
48     
49     extern struct proc_dir_entry	*bm_proc_root;
50     static struct proc_dir_entry	*tz_proc_root = NULL;
51     
52     
53     /****************************************************************************
54      *
55      * FUNCTION:	tz_osl_proc_read_info
56      *
57      ****************************************************************************/
58     
59     static int
60     tz_osl_proc_read_info (
61     	char			*page,
62     	char			**start,
63     	off_t			off,
64     	int 			count,
65     	int 			*eof,
66     	void			*context)
67     {
68     	TZ_CONTEXT		*thermal_zone = NULL;
69     	char			*p = page;
70     	int 			len = 0;
71     
72     	if (!context || (off != 0)) {
73     		goto end;
74     	}
75     
76     	thermal_zone = (TZ_CONTEXT*)context;
77     
78     	p += sprintf(p, "<TBD>\n");
79     
80     end:
81     	len = (p - page);
82     	if (len <= off+count) *eof = 1;
83     	*start = page + off;
84     	len -= off;
85     	if (len>count) len = count;
86     	if (len<0) len = 0;
87     
88     	return(len);
89     }
90     
91     
92     /****************************************************************************
93      *
94      * FUNCTION:	tz_osl_proc_read_status
95      *
96      ****************************************************************************/
97     
98     static int
99     tz_osl_proc_read_status (
100     	char			*page,
101     	char			**start,
102     	off_t			off,
103     	int 			count,
104     	int 			*eof,
105     	void			*context)
106     {
107     	TZ_CONTEXT		*thermal_zone = NULL;
108     	char			*p = page;
109     	int 			len = 0;
110     
111     	if (!context || (off != 0)) {
112     		goto end;
113     	}
114     
115     	thermal_zone = (TZ_CONTEXT*)context;
116     
117     	p += sprintf(p, "Temperature:             %d (1/10th degrees Kelvin)\n",
118     		thermal_zone->policy.temperature);
119     
120     	p += sprintf(p, "State:                   ");
121     	if (thermal_zone->policy.state & TZ_STATE_ACTIVE) {
122     		p += sprintf(p, "active[%d] ", thermal_zone->policy.state & 0x07);
123     	}
124     	if (thermal_zone->policy.state & TZ_STATE_PASSIVE) {
125     		p += sprintf(p, "passive ");
126     	}
127     	if (thermal_zone->policy.state & TZ_STATE_CRITICAL) {
128     		p += sprintf(p, "critical ");
129     	}
130     	if (thermal_zone->policy.state == 0) {
131     		p += sprintf(p, "ok ");
132     	}
133     	p += sprintf(p, "\n");
134     
135     	p += sprintf(p, "Cooling Mode:            ");
136     	switch (thermal_zone->policy.cooling_mode) {
137     	case TZ_COOLING_MODE_ACTIVE:
138     		p += sprintf(p, "active (noisy)\n");
139     		break;
140     	case TZ_COOLING_MODE_PASSIVE:
141     		p += sprintf(p, "passive (quiet)\n");
142     		break;
143     	default:
144     		p += sprintf(p, "unknown\n");
145     		break;
146     	}
147     
148     	p += sprintf(p, "Polling Frequency:       ");
149     	switch (thermal_zone->policy.polling_freq) {
150     	case 0:
151     		p += sprintf(p, "n/a\n");
152     		break;
153     	default:
154     		p += sprintf(p, "%d (1/10th seconds)\n", thermal_zone->policy.polling_freq);
155     		break;
156     	}
157     
158     end:
159     	len = (p - page);
160     	if (len <= off+count) *eof = 1;
161     	*start = page + off;
162     	len -= off;
163     	if (len>count) len = count;
164     	if (len<0) len = 0;
165     
166     	return(len);
167     }
168     
169     
170     /****************************************************************************
171      *
172      * FUNCTION:	tz_osl_add_device
173      *
174      ****************************************************************************/
175     
176     acpi_status
177     tz_osl_add_device(
178     	TZ_CONTEXT		*thermal_zone)
179     {
180     	struct proc_dir_entry	*proc_entry = NULL;
181     
182     	if (!thermal_zone) {
183     		return(AE_BAD_PARAMETER);
184     	}
185     
186     	printk("Thermal Zone: found\n");
187     
188     	proc_entry = proc_mkdir(thermal_zone->uid, tz_proc_root);
189     	if (!proc_entry) {
190     		return(AE_ERROR);
191     	}
192     
193     	create_proc_read_entry(TZ_PROC_STATUS, S_IFREG | S_IRUGO,
194     		proc_entry, tz_osl_proc_read_status, (void*)thermal_zone);
195     
196     	create_proc_read_entry(TZ_PROC_INFO, S_IFREG | S_IRUGO,
197     		proc_entry, tz_osl_proc_read_info, (void*)thermal_zone);
198     
199     	return(AE_OK);
200     }
201     
202     
203     /****************************************************************************
204      *
205      * FUNCTION:	tz_osl_remove_device
206      *
207      ****************************************************************************/
208     
209     acpi_status
210     tz_osl_remove_device (
211     	TZ_CONTEXT		*thermal_zone)
212     {
213     	char			proc_entry[64];
214     
215     	if (!thermal_zone) {
216     		return(AE_BAD_PARAMETER);
217     	}
218     
219     	sprintf(proc_entry, "%s/%s", thermal_zone->uid, TZ_PROC_INFO);
220     	remove_proc_entry(proc_entry, tz_proc_root);
221     
222     	sprintf(proc_entry, "%s/%s", thermal_zone->uid, TZ_PROC_STATUS);
223     	remove_proc_entry(proc_entry, tz_proc_root);
224     
225     	sprintf(proc_entry, "%s", thermal_zone->uid);
226     	remove_proc_entry(proc_entry, tz_proc_root);
227     
228     	return(AE_OK);
229     }
230     
231     
232     /****************************************************************************
233      *
234      * FUNCTION:	tz_osl_generate_event
235      *
236      ****************************************************************************/
237     
238     acpi_status
239     tz_osl_generate_event (
240     	u32			event,
241     	TZ_CONTEXT		*thermal_zone)
242     {
243     	acpi_status		status = AE_OK;
244     
245     	if (!thermal_zone) {
246     		return(AE_BAD_PARAMETER);
247     	}
248     
249     	switch (event) {
250     
251     	case TZ_NOTIFY_TEMPERATURE_CHANGE:
252     		status = bm_osl_generate_event(thermal_zone->device_handle,
253     			TZ_PROC_ROOT, thermal_zone->uid, event,
254     			thermal_zone->policy.temperature);
255     		break;
256     
257     	case TZ_NOTIFY_THRESHOLD_CHANGE:
258     	case TZ_NOTIFY_DEVICE_LISTS_CHANGE:
259     		status = bm_osl_generate_event(thermal_zone->device_handle,
260     			TZ_PROC_ROOT, thermal_zone->uid, event, 0);
261     		break;
262     
263     	default:
264     		return(AE_BAD_PARAMETER);
265     		break;
266     	}
267     
268     	return(status);
269     }
270     
271     
272     /****************************************************************************
273      *
274      * FUNCTION:	tz_osl_init
275      *
276      * PARAMETERS:	<none>
277      *
278      * RETURN:	0: Success
279      *
280      * DESCRIPTION: Module initialization.
281      *
282      ****************************************************************************/
283     
284     static int __init
285     tz_osl_init (void)
286     {
287     	acpi_status		status = AE_OK;
288     
289     	/* abort if no busmgr */
290     	if (!bm_proc_root)
291     		return -ENODEV;
292     
293     	tz_proc_root = proc_mkdir(TZ_PROC_ROOT, bm_proc_root);
294     	if (!tz_proc_root) {
295     		status = AE_ERROR;
296     	}
297     	else {
298     		status = tz_initialize();
299     		if (ACPI_FAILURE(status)) {
300     			remove_proc_entry(TZ_PROC_ROOT, bm_proc_root);
301     		}
302     
303     	}
304     
305     	return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
306     }
307     
308     
309     /****************************************************************************
310      *
311      * FUNCTION:	tz_osl_cleanup
312      *
313      * PARAMETERS:	<none>
314      *
315      * RETURN:	<none>
316      *
317      * DESCRIPTION: Module cleanup.
318      *
319      ****************************************************************************/
320     
321     static void __exit
322     tz_osl_cleanup (void)
323     {
324     	tz_terminate();
325     
326     	if (tz_proc_root) {
327     		remove_proc_entry(TZ_PROC_ROOT, bm_proc_root);
328     	}
329     
330     	return;
331     }
332     
333     
334     module_init(tz_osl_init);
335     module_exit(tz_osl_cleanup);
336