X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fsbus%2Fchar%2Fbbc_envctrl.c;h=15dab96d05e31328108b89dabc53ee4b2b5aa573;hb=f1b2a5ace996de339292d4035f9f5b294aecd11e;hp=d27e4f6d7045a3a5f21e38d6bab32455d83c3d8a;hpb=7ff3e52cf2947ebd38c84159af68e5a29d228f6c;p=linux-2.6-omap-h63xx.git diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index d27e4f6d704..15dab96d05e 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c @@ -1,16 +1,15 @@ -/* $Id: bbc_envctrl.c,v 1.4 2001/04/06 16:48:08 davem Exp $ - * bbc_envctrl.c: UltraSPARC-III environment control driver. +/* bbc_envctrl.c: UltraSPARC-III environment control driver. * - * Copyright (C) 2001 David S. Miller (davem@redhat.com) + * Copyright (C) 2001, 2008 David S. Miller (davem@davemloft.net) */ -#include #include -#include -#include #include +#include +#include +#include +#include #include -#include #include "bbc_i2c.h" #include "max1617.h" @@ -76,43 +75,8 @@ static struct temp_limits amb_temp_limits[2] = { { 65, 55, 40, 5, -5, -10 }, }; -enum fan_action { FAN_SLOWER, FAN_SAME, FAN_FASTER, FAN_FULLBLAST, FAN_STATE_MAX }; - -struct bbc_cpu_temperature { - struct bbc_cpu_temperature *next; - - struct bbc_i2c_client *client; - int index; - - /* Current readings, and history. */ - s8 curr_cpu_temp; - s8 curr_amb_temp; - s8 prev_cpu_temp; - s8 prev_amb_temp; - s8 avg_cpu_temp; - s8 avg_amb_temp; - - int sample_tick; - - enum fan_action fan_todo[2]; -#define FAN_AMBIENT 0 -#define FAN_CPU 1 -}; - -struct bbc_cpu_temperature *all_bbc_temps; - -struct bbc_fan_control { - struct bbc_fan_control *next; - - struct bbc_i2c_client *client; - int index; - - int psupply_fan_on; - int cpu_fan_speed; - int system_fan_speed; -}; - -struct bbc_fan_control *all_bbc_fans; +static LIST_HEAD(all_temps); +static LIST_HEAD(all_fans); #define CPU_FAN_REG 0xf0 #define SYS_FAN_REG 0xf2 @@ -172,8 +136,6 @@ static void get_current_temps(struct bbc_cpu_temperature *tp) static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp) { static int shutting_down = 0; - static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; - char *argv[] = { "/sbin/shutdown", "-h", "now", NULL }; char *type = "???"; s8 val = -1; @@ -197,7 +159,7 @@ static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp) printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n"); shutting_down = 1; - if (kernel_execve("/sbin/shutdown", argv, envp) < 0) + if (orderly_poweroff(true) < 0) printk(KERN_CRIT "envctrl: shutdown execution failed\n"); } @@ -333,7 +295,7 @@ static enum fan_action prioritize_fan_action(int which_fan) * recommend we do, and perform that action on all the * fans. */ - for (tp = all_bbc_temps; tp; tp = tp->next) { + list_for_each_entry(tp, &all_temps, glob_list) { if (tp->fan_todo[which_fan] == FAN_FULLBLAST) { decision = FAN_FULLBLAST; break; @@ -442,7 +404,7 @@ static void fans_full_blast(void) /* Since we will not be monitoring things anymore, put * the fans on full blast. */ - for (fp = all_bbc_fans; fp; fp = fp->next) { + list_for_each_entry(fp, &all_fans, glob_list) { fp->cpu_fan_speed = FAN_SPEED_MAX; fp->system_fan_speed = FAN_SPEED_MAX; fp->psupply_fan_on = 1; @@ -466,11 +428,11 @@ static int kenvctrld(void *__unused) if (kthread_should_stop()) break; - for (tp = all_bbc_temps; tp; tp = tp->next) { + list_for_each_entry(tp, &all_temps, glob_list) { get_current_temps(tp); analyze_temps(tp, &last_warning_jiffies); } - for (fp = all_bbc_fans; fp; fp = fp->next) + list_for_each_entry(fp, &all_fans, glob_list) maybe_new_fan_speeds(fp); } printk(KERN_INFO "bbc_envctrl: kenvctrld exiting...\n"); @@ -480,27 +442,26 @@ static int kenvctrld(void *__unused) return 0; } -static void attach_one_temp(struct linux_ebus_child *echild, int temp_idx) +static void attach_one_temp(struct bbc_i2c_bus *bp, struct of_device *op, + int temp_idx) { - struct bbc_cpu_temperature *tp = kmalloc(sizeof(*tp), GFP_KERNEL); + struct bbc_cpu_temperature *tp; + tp = kzalloc(sizeof(*tp), GFP_KERNEL); if (!tp) return; - memset(tp, 0, sizeof(*tp)); - tp->client = bbc_i2c_attach(echild); + + tp->client = bbc_i2c_attach(bp, op); if (!tp->client) { kfree(tp); return; } + tp->index = temp_idx; - { - struct bbc_cpu_temperature **tpp = &all_bbc_temps; - while (*tpp) - tpp = &((*tpp)->next); - tp->next = NULL; - *tpp = tp; - } + + list_add(&tp->glob_list, &all_temps); + list_add(&tp->bp_list, &bp->temps); /* Tell it to convert once every 5 seconds, clear all cfg * bits. @@ -526,14 +487,16 @@ static void attach_one_temp(struct linux_ebus_child *echild, int temp_idx) tp->fan_todo[FAN_CPU] = FAN_SAME; } -static void attach_one_fan(struct linux_ebus_child *echild, int fan_idx) +static void attach_one_fan(struct bbc_i2c_bus *bp, struct of_device *op, + int fan_idx) { - struct bbc_fan_control *fp = kmalloc(sizeof(*fp), GFP_KERNEL); + struct bbc_fan_control *fp; + fp = kzalloc(sizeof(*fp), GFP_KERNEL); if (!fp) return; - memset(fp, 0, sizeof(*fp)); - fp->client = bbc_i2c_attach(echild); + + fp->client = bbc_i2c_attach(bp, op); if (!fp->client) { kfree(fp); return; @@ -541,13 +504,8 @@ static void attach_one_fan(struct linux_ebus_child *echild, int fan_idx) fp->index = fan_idx; - { - struct bbc_fan_control **fpp = &all_bbc_fans; - while (*fpp) - fpp = &((*fpp)->next); - fp->next = NULL; - *fpp = fp; - } + list_add(&fp->glob_list, &all_fans); + list_add(&fp->bp_list, &bp->fans); /* The i2c device controlling the fans is write-only. * So the only way to keep track of the current power @@ -564,18 +522,18 @@ static void attach_one_fan(struct linux_ebus_child *echild, int fan_idx) set_fan_speeds(fp); } -int bbc_envctrl_init(void) +int bbc_envctrl_init(struct bbc_i2c_bus *bp) { - struct linux_ebus_child *echild; + struct of_device *op; int temp_index = 0; int fan_index = 0; int devidx = 0; - while ((echild = bbc_i2c_getdev(devidx++)) != NULL) { - if (!strcmp(echild->prom_node->name, "temperature")) - attach_one_temp(echild, temp_index++); - if (!strcmp(echild->prom_node->name, "fan-control")) - attach_one_fan(echild, fan_index++); + while ((op = bbc_i2c_getdev(bp, devidx++)) != NULL) { + if (!strcmp(op->node->name, "temperature")) + attach_one_temp(bp, op, temp_index++); + if (!strcmp(op->node->name, "fan-control")) + attach_one_fan(bp, op, fan_index++); } if (temp_index != 0 && fan_index != 0) { kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld"); @@ -598,26 +556,22 @@ static void destroy_one_fan(struct bbc_fan_control *fp) kfree(fp); } -void bbc_envctrl_cleanup(void) +void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp) { - struct bbc_cpu_temperature *tp; - struct bbc_fan_control *fp; + struct bbc_cpu_temperature *tp, *tpos; + struct bbc_fan_control *fp, *fpos; kthread_stop(kenvctrld_task); - tp = all_bbc_temps; - while (tp != NULL) { - struct bbc_cpu_temperature *next = tp->next; + list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) { + list_del(&tp->bp_list); + list_del(&tp->glob_list); destroy_one_temp(tp); - tp = next; } - all_bbc_temps = NULL; - fp = all_bbc_fans; - while (fp != NULL) { - struct bbc_fan_control *next = fp->next; + list_for_each_entry_safe(fp, fpos, &bp->fans, bp_list) { + list_del(&fp->bp_list); + list_del(&fp->glob_list); destroy_one_fan(fp); - fp = next; } - all_bbc_fans = NULL; }