2005-11-07 08:08:17 +03:00
/*
* Windfarm PowerMac thermal control .
*
* ( c ) Copyright 2005 Benjamin Herrenschmidt , IBM Corp .
* < benh @ kernel . crashing . org >
*
* Released under the term of the GNU GPL v2 .
*/
# ifndef __WINDFARM_H__
# define __WINDFARM_H__
# include <linux/kref.h>
# include <linux/list.h>
# include <linux/module.h>
# include <linux/notifier.h>
2006-02-08 08:42:51 +03:00
# include <linux/device.h>
2005-11-07 08:08:17 +03:00
/* Display a 16.16 fixed point value */
2012-04-29 19:42:27 +04:00
# define FIX32TOPRINT(f) (((s32)(f)) >> 16),(((((s32)(f)) & 0xffff) * 1000) >> 16)
2005-11-07 08:08:17 +03:00
/*
* Control objects
*/
struct wf_control ;
struct wf_control_ops {
int ( * set_value ) ( struct wf_control * ct , s32 val ) ;
int ( * get_value ) ( struct wf_control * ct , s32 * val ) ;
s32 ( * get_min ) ( struct wf_control * ct ) ;
s32 ( * get_max ) ( struct wf_control * ct ) ;
void ( * release ) ( struct wf_control * ct ) ;
struct module * owner ;
} ;
struct wf_control {
2012-04-19 02:16:47 +04:00
struct list_head link ;
const struct wf_control_ops * ops ;
const char * name ;
int type ;
struct kref ref ;
struct device_attribute attr ;
2012-04-29 19:42:27 +04:00
void * priv ;
2005-11-07 08:08:17 +03:00
} ;
# define WF_CONTROL_TYPE_GENERIC 0
# define WF_CONTROL_RPM_FAN 1
# define WF_CONTROL_PWM_FAN 2
/* Note about lifetime rules: wf_register_control() will initialize
* the kref and wf_unregister_control will decrement it , thus the
* object creating / disposing a given control shouldn ' t assume it
* still exists after wf_unregister_control has been called .
* wf_find_control will inc the refcount for you
*/
extern int wf_register_control ( struct wf_control * ct ) ;
extern void wf_unregister_control ( struct wf_control * ct ) ;
extern struct wf_control * wf_find_control ( const char * name ) ;
extern int wf_get_control ( struct wf_control * ct ) ;
extern void wf_put_control ( struct wf_control * ct ) ;
static inline int wf_control_set_max ( struct wf_control * ct )
{
s32 vmax = ct - > ops - > get_max ( ct ) ;
return ct - > ops - > set_value ( ct , vmax ) ;
}
static inline int wf_control_set_min ( struct wf_control * ct )
{
s32 vmin = ct - > ops - > get_min ( ct ) ;
return ct - > ops - > set_value ( ct , vmin ) ;
}
2012-04-19 02:16:51 +04:00
static inline int wf_control_set ( struct wf_control * ct , s32 val )
{
return ct - > ops - > set_value ( ct , val ) ;
}
static inline int wf_control_get ( struct wf_control * ct , s32 * val )
{
return ct - > ops - > get_value ( ct , val ) ;
}
static inline s32 wf_control_get_min ( struct wf_control * ct )
{
return ct - > ops - > get_min ( ct ) ;
}
static inline s32 wf_control_get_max ( struct wf_control * ct )
{
return ct - > ops - > get_max ( ct ) ;
}
2005-11-07 08:08:17 +03:00
/*
* Sensor objects
*/
struct wf_sensor ;
struct wf_sensor_ops {
int ( * get_value ) ( struct wf_sensor * sr , s32 * val ) ;
void ( * release ) ( struct wf_sensor * sr ) ;
struct module * owner ;
} ;
struct wf_sensor {
2012-04-19 02:16:47 +04:00
struct list_head link ;
const struct wf_sensor_ops * ops ;
const char * name ;
struct kref ref ;
struct device_attribute attr ;
void * priv ;
2005-11-07 08:08:17 +03:00
} ;
/* Same lifetime rules as controls */
extern int wf_register_sensor ( struct wf_sensor * sr ) ;
extern void wf_unregister_sensor ( struct wf_sensor * sr ) ;
extern struct wf_sensor * wf_find_sensor ( const char * name ) ;
extern int wf_get_sensor ( struct wf_sensor * sr ) ;
extern void wf_put_sensor ( struct wf_sensor * sr ) ;
2012-04-19 02:16:51 +04:00
static inline int wf_sensor_get ( struct wf_sensor * sr , s32 * val )
{
return sr - > ops - > get_value ( sr , val ) ;
}
2005-11-07 08:08:17 +03:00
/* For use by clients. Note that we are a bit racy here since
* notifier_block doesn ' t have a module owner field . I may fix
* it one day . . .
*
* LOCKING NOTE !
*
* All " events " except WF_EVENT_TICK are called with an internal mutex
* held which will deadlock if you call basically any core routine .
* So don ' t ! Just take note of the event and do your actual operations
* from the ticker .
*
*/
extern int wf_register_client ( struct notifier_block * nb ) ;
extern int wf_unregister_client ( struct notifier_block * nb ) ;
/* Overtemp conditions. Those are refcounted */
extern void wf_set_overtemp ( void ) ;
extern void wf_clear_overtemp ( void ) ;
extern int wf_is_overtemp ( void ) ;
# define WF_EVENT_NEW_CONTROL 0 /* param is wf_control * */
# define WF_EVENT_NEW_SENSOR 1 /* param is wf_sensor * */
# define WF_EVENT_OVERTEMP 2 /* no param */
# define WF_EVENT_NORMALTEMP 3 /* overtemp condition cleared */
# define WF_EVENT_TICK 4 /* 1 second tick */
/* Note: If that driver gets more broad use, we could replace the
* simplistic overtemp bits with " environmental conditions " . That
* could then be used to also notify of things like fan failure ,
* case open , battery conditions , . . .
*/
# endif /* __WINDFARM_H__ */