aboutsummaryrefslogtreecommitdiff
path: root/drivers/macintosh/windfarm_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/macintosh/windfarm_core.c')
-rw-r--r--drivers/macintosh/windfarm_core.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index bb8d5efe19b..3ee198b6584 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -25,15 +25,18 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include <linux/jiffies.h>
#include <linux/reboot.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
+#include <linux/freezer.h>
+
+#include <asm/prom.h>
#include "windfarm.h"
@@ -50,7 +53,7 @@
static LIST_HEAD(wf_controls);
static LIST_HEAD(wf_sensors);
static DEFINE_MUTEX(wf_lock);
-static struct notifier_block *wf_client_list;
+static BLOCKING_NOTIFIER_HEAD(wf_client_list);
static int wf_client_count;
static unsigned int wf_overtemp;
static unsigned int wf_overtemp_counter;
@@ -66,7 +69,7 @@ static struct platform_device wf_platform_device = {
static inline void wf_notify(int event, void *param)
{
- notifier_call_chain(&wf_client_list, event, param);
+ blocking_notifier_call_chain(&wf_client_list, event, param);
}
int wf_critical_overtemp(void)
@@ -78,7 +81,8 @@ int wf_critical_overtemp(void)
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
NULL };
- return call_usermodehelper(critical_overtemp_path, argv, envp, 0);
+ return call_usermodehelper(critical_overtemp_path,
+ argv, envp, UMH_WAIT_EXEC);
}
EXPORT_SYMBOL_GPL(wf_critical_overtemp);
@@ -90,7 +94,8 @@ static int wf_thread_func(void *data)
DBG("wf: thread started\n");
- while(!kthread_should_stop()) {
+ set_freezable();
+ while (!kthread_should_stop()) {
try_to_freeze();
if (time_after_eq(jiffies, next)) {
@@ -114,12 +119,6 @@ static int wf_thread_func(void *data)
delay = next - jiffies;
if (delay <= HZ)
schedule_timeout_interruptible(delay);
-
- /* there should be no signal, but oh well */
- if (signal_pending(current)) {
- printk(KERN_WARNING "windfarm: thread got sigl !\n");
- break;
- }
}
DBG("wf: thread stopped\n");
@@ -165,13 +164,27 @@ static ssize_t wf_show_control(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
+ const char *typestr;
s32 val = 0;
int err;
err = ctrl->ops->get_value(ctrl, &val);
- if (err < 0)
+ if (err < 0) {
+ if (err == -EFAULT)
+ return sprintf(buf, "<HW FAULT>\n");
return err;
- return sprintf(buf, "%d\n", val);
+ }
+ switch(ctrl->type) {
+ case WF_CONTROL_RPM_FAN:
+ typestr = " RPM";
+ break;
+ case WF_CONTROL_PWM_FAN:
+ typestr = " %";
+ break;
+ default:
+ typestr = "";
+ }
+ return sprintf(buf, "%d%s\n", val, typestr);
}
/* This is really only for debugging... */
@@ -211,12 +224,15 @@ int wf_register_control(struct wf_control *new_ct)
kref_init(&new_ct->ref);
list_add(&new_ct->link, &wf_controls);
+ sysfs_attr_init(&new_ct->attr.attr);
new_ct->attr.attr.name = new_ct->name;
- new_ct->attr.attr.owner = THIS_MODULE;
new_ct->attr.attr.mode = 0644;
new_ct->attr.show = wf_show_control;
new_ct->attr.store = wf_store_control;
- device_create_file(&wf_platform_device.dev, &new_ct->attr);
+ if (device_create_file(&wf_platform_device.dev, &new_ct->attr))
+ printk(KERN_WARNING "windfarm: device_create_file failed"
+ " for %s\n", new_ct->name);
+ /* the subsystem still does useful work without the file */
DBG("wf: Registered control %s\n", new_ct->name);
@@ -321,12 +337,15 @@ int wf_register_sensor(struct wf_sensor *new_sr)
kref_init(&new_sr->ref);
list_add(&new_sr->link, &wf_sensors);
+ sysfs_attr_init(&new_sr->attr.attr);
new_sr->attr.attr.name = new_sr->name;
- new_sr->attr.attr.owner = THIS_MODULE;
new_sr->attr.attr.mode = 0444;
new_sr->attr.show = wf_show_sensor;
new_sr->attr.store = NULL;
- device_create_file(&wf_platform_device.dev, &new_sr->attr);
+ if (device_create_file(&wf_platform_device.dev, &new_sr->attr))
+ printk(KERN_WARNING "windfarm: device_create_file failed"
+ " for %s\n", new_sr->name);
+ /* the subsystem still does useful work without the file */
DBG("wf: Registered sensor %s\n", new_sr->name);
@@ -396,7 +415,7 @@ int wf_register_client(struct notifier_block *nb)
struct wf_sensor *sr;
mutex_lock(&wf_lock);
- rc = notifier_chain_register(&wf_client_list, nb);
+ rc = blocking_notifier_chain_register(&wf_client_list, nb);
if (rc != 0)
goto bail;
wf_client_count++;
@@ -415,7 +434,7 @@ EXPORT_SYMBOL_GPL(wf_register_client);
int wf_unregister_client(struct notifier_block *nb)
{
mutex_lock(&wf_lock);
- notifier_chain_unregister(&wf_client_list, nb);
+ blocking_notifier_chain_unregister(&wf_client_list, nb);
wf_client_count++;
if (wf_client_count == 0)
wf_stop_thread();