diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-11-07 00:08:17 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-11-07 19:17:56 -0500 |
commit | 75722d3992f57375c0cc029dcceb2334a45ceff1 (patch) | |
tree | d3f63b3ea80790c2f29ea435781c1331f17d269e /drivers/macintosh/windfarm.h | |
parent | 7d49697ef92bd2cf84ab53bd4cea82fefb197fb9 (diff) |
[PATCH] ppc64: Thermal control for SMU based machines
This adds a new thermal control framework for PowerMac, along with the
implementation for PowerMac8,1, PowerMac8,2 (iMac G5 rev 1 and 2), and
PowerMac9,1 (latest single CPU desktop). In the future, I expect to move
the older G5 thermal control to the new framework as well.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/macintosh/windfarm.h')
-rw-r--r-- | drivers/macintosh/windfarm.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h new file mode 100644 index 000000000000..3f0cb0312ea3 --- /dev/null +++ b/drivers/macintosh/windfarm.h | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * Windfarm PowerMac thermal control. | ||
3 | * | ||
4 | * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp. | ||
5 | * <benh@kernel.crashing.org> | ||
6 | * | ||
7 | * Released under the term of the GNU GPL v2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __WINDFARM_H__ | ||
11 | #define __WINDFARM_H__ | ||
12 | |||
13 | #include <linux/kref.h> | ||
14 | #include <linux/list.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/notifier.h> | ||
17 | |||
18 | /* Display a 16.16 fixed point value */ | ||
19 | #define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) | ||
20 | |||
21 | /* | ||
22 | * Control objects | ||
23 | */ | ||
24 | |||
25 | struct wf_control; | ||
26 | |||
27 | struct wf_control_ops { | ||
28 | int (*set_value)(struct wf_control *ct, s32 val); | ||
29 | int (*get_value)(struct wf_control *ct, s32 *val); | ||
30 | s32 (*get_min)(struct wf_control *ct); | ||
31 | s32 (*get_max)(struct wf_control *ct); | ||
32 | void (*release)(struct wf_control *ct); | ||
33 | struct module *owner; | ||
34 | }; | ||
35 | |||
36 | struct wf_control { | ||
37 | struct list_head link; | ||
38 | struct wf_control_ops *ops; | ||
39 | char *name; | ||
40 | int type; | ||
41 | struct kref ref; | ||
42 | }; | ||
43 | |||
44 | #define WF_CONTROL_TYPE_GENERIC 0 | ||
45 | #define WF_CONTROL_RPM_FAN 1 | ||
46 | #define WF_CONTROL_PWM_FAN 2 | ||
47 | |||
48 | |||
49 | /* Note about lifetime rules: wf_register_control() will initialize | ||
50 | * the kref and wf_unregister_control will decrement it, thus the | ||
51 | * object creating/disposing a given control shouldn't assume it | ||
52 | * still exists after wf_unregister_control has been called. | ||
53 | * wf_find_control will inc the refcount for you | ||
54 | */ | ||
55 | extern int wf_register_control(struct wf_control *ct); | ||
56 | extern void wf_unregister_control(struct wf_control *ct); | ||
57 | extern struct wf_control * wf_find_control(const char *name); | ||
58 | extern int wf_get_control(struct wf_control *ct); | ||
59 | extern void wf_put_control(struct wf_control *ct); | ||
60 | |||
61 | static inline int wf_control_set_max(struct wf_control *ct) | ||
62 | { | ||
63 | s32 vmax = ct->ops->get_max(ct); | ||
64 | return ct->ops->set_value(ct, vmax); | ||
65 | } | ||
66 | |||
67 | static inline int wf_control_set_min(struct wf_control *ct) | ||
68 | { | ||
69 | s32 vmin = ct->ops->get_min(ct); | ||
70 | return ct->ops->set_value(ct, vmin); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Sensor objects | ||
75 | */ | ||
76 | |||
77 | struct wf_sensor; | ||
78 | |||
79 | struct wf_sensor_ops { | ||
80 | int (*get_value)(struct wf_sensor *sr, s32 *val); | ||
81 | void (*release)(struct wf_sensor *sr); | ||
82 | struct module *owner; | ||
83 | }; | ||
84 | |||
85 | struct wf_sensor { | ||
86 | struct list_head link; | ||
87 | struct wf_sensor_ops *ops; | ||
88 | char *name; | ||
89 | struct kref ref; | ||
90 | }; | ||
91 | |||
92 | /* Same lifetime rules as controls */ | ||
93 | extern int wf_register_sensor(struct wf_sensor *sr); | ||
94 | extern void wf_unregister_sensor(struct wf_sensor *sr); | ||
95 | extern struct wf_sensor * wf_find_sensor(const char *name); | ||
96 | extern int wf_get_sensor(struct wf_sensor *sr); | ||
97 | extern void wf_put_sensor(struct wf_sensor *sr); | ||
98 | |||
99 | /* For use by clients. Note that we are a bit racy here since | ||
100 | * notifier_block doesn't have a module owner field. I may fix | ||
101 | * it one day ... | ||
102 | * | ||
103 | * LOCKING NOTE ! | ||
104 | * | ||
105 | * All "events" except WF_EVENT_TICK are called with an internal mutex | ||
106 | * held which will deadlock if you call basically any core routine. | ||
107 | * So don't ! Just take note of the event and do your actual operations | ||
108 | * from the ticker. | ||
109 | * | ||
110 | */ | ||
111 | extern int wf_register_client(struct notifier_block *nb); | ||
112 | extern int wf_unregister_client(struct notifier_block *nb); | ||
113 | |||
114 | /* Overtemp conditions. Those are refcounted */ | ||
115 | extern void wf_set_overtemp(void); | ||
116 | extern void wf_clear_overtemp(void); | ||
117 | extern int wf_is_overtemp(void); | ||
118 | |||
119 | #define WF_EVENT_NEW_CONTROL 0 /* param is wf_control * */ | ||
120 | #define WF_EVENT_NEW_SENSOR 1 /* param is wf_sensor * */ | ||
121 | #define WF_EVENT_OVERTEMP 2 /* no param */ | ||
122 | #define WF_EVENT_NORMALTEMP 3 /* overtemp condition cleared */ | ||
123 | #define WF_EVENT_TICK 4 /* 1 second tick */ | ||
124 | |||
125 | /* Note: If that driver gets more broad use, we could replace the | ||
126 | * simplistic overtemp bits with "environmental conditions". That | ||
127 | * could then be used to also notify of things like fan failure, | ||
128 | * case open, battery conditions, ... | ||
129 | */ | ||
130 | |||
131 | #endif /* __WINDFARM_H__ */ | ||