From f16783ec2c91198d2b82f8a6ffed77907dbaa8e4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 19 Dec 2005 16:27:59 -0500 Subject: [PATCH] --- yaml --- r: 20093 b: refs/heads/master c: 034d2f5af1b97664381c00b827b274c95e22c397 h: refs/heads/master i: 20091: 2b723ec07addc4a6fe5b43dcefcd7a27b46b0608 v: v3 --- [refs] | 2 +- trunk/arch/alpha/kernel/smp.c | 25 +- trunk/arch/arm/Kconfig | 5 + trunk/block/elevator.c | 70 +- trunk/block/ll_rw_blk.c | 4 +- trunk/block/scsi_ioctl.c | 3 - trunk/drivers/macintosh/Kconfig | 8 - trunk/drivers/macintosh/Makefile | 5 - trunk/drivers/macintosh/windfarm.h | 3 - trunk/drivers/macintosh/windfarm_core.c | 69 +- .../macintosh/windfarm_max6690_sensor.c | 169 ----- trunk/drivers/macintosh/windfarm_pid.c | 8 +- trunk/drivers/macintosh/windfarm_pid.h | 1 - trunk/drivers/macintosh/windfarm_pm112.c | 698 ------------------ trunk/drivers/macintosh/windfarm_pm81.c | 87 ++- trunk/drivers/macintosh/windfarm_pm91.c | 95 ++- .../drivers/macintosh/windfarm_smu_controls.c | 69 +- trunk/drivers/macintosh/windfarm_smu_sat.c | 418 ----------- .../drivers/macintosh/windfarm_smu_sensors.c | 43 +- trunk/drivers/mtd/chips/Kconfig | 2 +- trunk/include/asm-powerpc/smu.h | 5 - trunk/include/linux/elevator.h | 1 - trunk/mm/slob.c | 2 +- 23 files changed, 262 insertions(+), 1530 deletions(-) delete mode 100644 trunk/drivers/macintosh/windfarm_max6690_sensor.c delete mode 100644 trunk/drivers/macintosh/windfarm_pm112.c delete mode 100644 trunk/drivers/macintosh/windfarm_smu_sat.c diff --git a/[refs] b/[refs] index d83e71fb2180..eb04360d3213 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b7ed1de0ae4edb3fd2c53fa3dd7e6f104beb6d00 +refs/heads/master: 034d2f5af1b97664381c00b827b274c95e22c397 diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c index 02c2db08114a..4b873527ce1c 100644 --- a/trunk/arch/alpha/kernel/smp.c +++ b/trunk/arch/alpha/kernel/smp.c @@ -73,6 +73,9 @@ cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); +/* cpus reported in the hwrpb */ +static unsigned long hwrpb_cpu_present_mask __initdata = 0; + int smp_num_probed; /* Internal processor count */ int smp_num_cpus = 1; /* Number that came online. */ @@ -439,7 +442,7 @@ setup_smp(void) if ((cpu->flags & 0x1cc) == 0x1cc) { smp_num_probed++; /* Assume here that "whami" == index */ - cpu_set(i, cpu_possible_map); + hwrpb_cpu_present_mask |= (1UL << i); cpu->pal_revision = boot_cpu_palrev; } @@ -450,12 +453,12 @@ setup_smp(void) } } else { smp_num_probed = 1; - cpu_set(boot_cpuid, cpu_possible_map); + hwrpb_cpu_present_mask = (1UL << boot_cpuid); } cpu_present_mask = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", - smp_num_probed, cpu_possible_map.bits[0]); + smp_num_probed, hwrpb_cpu_present_mask); } /* @@ -464,6 +467,8 @@ setup_smp(void) void __init smp_prepare_cpus(unsigned int max_cpus) { + int cpu_count, i; + /* Take care of some initial bookkeeping. */ memset(ipi_data, 0, sizeof(ipi_data)); @@ -481,7 +486,19 @@ smp_prepare_cpus(unsigned int max_cpus) printk(KERN_INFO "SMP starting up secondaries.\n"); - smp_num_cpus = smp_num_probed; + cpu_count = 1; + for (i = 0; (i < NR_CPUS) && (cpu_count < max_cpus); i++) { + if (i == boot_cpuid) + continue; + + if (((hwrpb_cpu_present_mask >> i) & 1) == 0) + continue; + + cpu_set(i, cpu_possible_map); + cpu_count++; + } + + smp_num_cpus = cpu_count; } void __devinit diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 5959e36c3b4c..4a63a8e2e452 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -69,6 +69,9 @@ config GENERIC_ISA_DMA config FIQ bool +config ARCH_MTD_XIP + bool + source "init/Kconfig" menu "System Type" @@ -136,6 +139,7 @@ config ARCH_L7200 config ARCH_PXA bool "PXA2xx-based" + select ARCH_MTD_XIP config ARCH_RPC bool "RiscPC" @@ -152,6 +156,7 @@ config ARCH_SA1100 bool "SA1100-based" select ISA select ARCH_DISCONTIGMEM_ENABLE + select ARCH_MTD_XIP config ARCH_S3C2410 bool "Samsung S3C2410" diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 24b702d649a9..2fc269f69726 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -293,7 +293,7 @@ void elv_requeue_request(request_queue_t *q, struct request *rq) rq->flags &= ~REQ_STARTED; - elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); + __elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE, 0); } static void elv_drain_elevator(request_queue_t *q) @@ -310,11 +310,41 @@ static void elv_drain_elevator(request_queue_t *q) } } -void elv_insert(request_queue_t *q, struct request *rq, int where) +void __elv_add_request(request_queue_t *q, struct request *rq, int where, + int plug) { struct list_head *pos; unsigned ordseq; + if (q->ordcolor) + rq->flags |= REQ_ORDERED_COLOR; + + if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { + /* + * toggle ordered color + */ + if (blk_barrier_rq(rq)) + q->ordcolor ^= 1; + + /* + * barriers implicitly indicate back insertion + */ + if (where == ELEVATOR_INSERT_SORT) + where = ELEVATOR_INSERT_BACK; + + /* + * this request is scheduling boundary, update end_sector + */ + if (blk_fs_request(rq)) { + q->end_sector = rq_end_sector(rq); + q->boundary_rq = rq; + } + } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) + where = ELEVATOR_INSERT_BACK; + + if (plug) + blk_plug_device(q); + rq->q = q; switch (where) { @@ -395,42 +425,6 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) } } -void __elv_add_request(request_queue_t *q, struct request *rq, int where, - int plug) -{ - if (q->ordcolor) - rq->flags |= REQ_ORDERED_COLOR; - - if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { - /* - * toggle ordered color - */ - if (blk_barrier_rq(rq)) - q->ordcolor ^= 1; - - /* - * barriers implicitly indicate back insertion - */ - if (where == ELEVATOR_INSERT_SORT) - where = ELEVATOR_INSERT_BACK; - - /* - * this request is scheduling boundary, update - * end_sector - */ - if (blk_fs_request(rq)) { - q->end_sector = rq_end_sector(rq); - q->boundary_rq = rq; - } - } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) - where = ELEVATOR_INSERT_BACK; - - if (plug) - blk_plug_device(q); - - elv_insert(q, rq, where); -} - void elv_add_request(request_queue_t *q, struct request *rq, int where, int plug) { diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 03d9c82b0fe7..ee5ed98db4cd 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -454,7 +454,7 @@ static void queue_flush(request_queue_t *q, unsigned which) rq->end_io = end_io; q->prepare_flush_fn(q, rq); - elv_insert(q, rq, ELEVATOR_INSERT_FRONT); + __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); } static inline struct request *start_ordered(request_queue_t *q, @@ -490,7 +490,7 @@ static inline struct request *start_ordered(request_queue_t *q, else q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH; - elv_insert(q, rq, ELEVATOR_INSERT_FRONT); + __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); if (q->ordered & QUEUE_ORDERED_PREFLUSH) { queue_flush(q, QUEUE_ORDERED_PREFLUSH); diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 24f7af9d0abc..cc72210687eb 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -310,8 +310,6 @@ static int sg_io(struct file *file, request_queue_t *q, if (!rq->timeout) rq->timeout = BLK_DEFAULT_TIMEOUT; - rq->retries = 0; - start_time = jiffies; /* ignore return value. All information is passed back to caller @@ -429,7 +427,6 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q, rq->data = buffer; rq->data_len = bytes; rq->flags |= REQ_BLOCK_PC; - rq->retries = 0; blk_execute_rq(q, bd_disk, rq, 0); err = rq->errors & 0xff; /* only 8 bit SCSI status */ diff --git a/trunk/drivers/macintosh/Kconfig b/trunk/drivers/macintosh/Kconfig index 12ad462737ba..7d4a0ac28c06 100644 --- a/trunk/drivers/macintosh/Kconfig +++ b/trunk/drivers/macintosh/Kconfig @@ -187,14 +187,6 @@ config WINDFARM_PM91 This driver provides thermal control for the PowerMac9,1 which is the recent (SMU based) single CPU desktop G5 -config WINDFARM_PM112 - tristate "Support for thermal management on PowerMac11,2" - depends on WINDFARM && I2C && PMAC_SMU - select I2C_POWERMAC - help - This driver provides thermal control for the PowerMac11,2 - which are the recent dual and quad G5 machines using the - 970MP dual-core processor. config ANSLCD tristate "Support for ANS LCD display" diff --git a/trunk/drivers/macintosh/Makefile b/trunk/drivers/macintosh/Makefile index 6081acdea404..f4657aa81fb0 100644 --- a/trunk/drivers/macintosh/Makefile +++ b/trunk/drivers/macintosh/Makefile @@ -35,8 +35,3 @@ obj-$(CONFIG_WINDFARM_PM91) += windfarm_smu_controls.o \ windfarm_smu_sensors.o \ windfarm_lm75_sensor.o windfarm_pid.o \ windfarm_cpufreq_clamp.o windfarm_pm91.o -obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \ - windfarm_smu_controls.o \ - windfarm_smu_sensors.o \ - windfarm_max6690_sensor.o \ - windfarm_lm75_sensor.o windfarm_pid.o diff --git a/trunk/drivers/macintosh/windfarm.h b/trunk/drivers/macintosh/windfarm.h index 7a2482cc26a7..3f0cb0312ea3 100644 --- a/trunk/drivers/macintosh/windfarm.h +++ b/trunk/drivers/macintosh/windfarm.h @@ -14,7 +14,6 @@ #include #include #include -#include /* Display a 16.16 fixed point value */ #define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) @@ -40,7 +39,6 @@ struct wf_control { char *name; int type; struct kref ref; - struct device_attribute attr; }; #define WF_CONTROL_TYPE_GENERIC 0 @@ -89,7 +87,6 @@ struct wf_sensor { struct wf_sensor_ops *ops; char *name; struct kref ref; - struct device_attribute attr; }; /* Same lifetime rules as controls */ diff --git a/trunk/drivers/macintosh/windfarm_core.c b/trunk/drivers/macintosh/windfarm_core.c index bb8d5efe19bf..32d466441ac2 100644 --- a/trunk/drivers/macintosh/windfarm_core.c +++ b/trunk/drivers/macintosh/windfarm_core.c @@ -56,10 +56,6 @@ static unsigned int wf_overtemp; static unsigned int wf_overtemp_counter; struct task_struct *wf_thread; -static struct platform_device wf_platform_device = { - .name = "windfarm", -}; - /* * Utilities & tick thread */ @@ -161,40 +157,6 @@ static void wf_control_release(struct kref *kref) kfree(ct); } -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); - s32 val = 0; - int err; - - err = ctrl->ops->get_value(ctrl, &val); - if (err < 0) - return err; - return sprintf(buf, "%d\n", val); -} - -/* This is really only for debugging... */ -static ssize_t wf_store_control(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct wf_control *ctrl = container_of(attr, struct wf_control, attr); - int val; - int err; - char *endp; - - val = simple_strtoul(buf, &endp, 0); - while (endp < buf + count && (*endp == ' ' || *endp == '\n')) - ++endp; - if (endp - buf < count) - return -EINVAL; - err = ctrl->ops->set_value(ctrl, val); - if (err < 0) - return err; - return count; -} - int wf_register_control(struct wf_control *new_ct) { struct wf_control *ct; @@ -211,13 +173,6 @@ int wf_register_control(struct wf_control *new_ct) kref_init(&new_ct->ref); list_add(&new_ct->link, &wf_controls); - 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); - DBG("wf: Registered control %s\n", new_ct->name); wf_notify(WF_EVENT_NEW_CONTROL, new_ct); @@ -292,19 +247,6 @@ static void wf_sensor_release(struct kref *kref) kfree(sr); } -static ssize_t wf_show_sensor(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct wf_sensor *sens = container_of(attr, struct wf_sensor, attr); - s32 val = 0; - int err; - - err = sens->ops->get_value(sens, &val); - if (err < 0) - return err; - return sprintf(buf, "%d.%03d\n", FIX32TOPRINT(val)); -} - int wf_register_sensor(struct wf_sensor *new_sr) { struct wf_sensor *sr; @@ -321,13 +263,6 @@ int wf_register_sensor(struct wf_sensor *new_sr) kref_init(&new_sr->ref); list_add(&new_sr->link, &wf_sensors); - 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); - DBG("wf: Registered sensor %s\n", new_sr->name); wf_notify(WF_EVENT_NEW_SENSOR, new_sr); @@ -461,6 +396,10 @@ int wf_is_overtemp(void) } EXPORT_SYMBOL_GPL(wf_is_overtemp); +static struct platform_device wf_platform_device = { + .name = "windfarm", +}; + static int __init windfarm_core_init(void) { DBG("wf: core loaded\n"); diff --git a/trunk/drivers/macintosh/windfarm_max6690_sensor.c b/trunk/drivers/macintosh/windfarm_max6690_sensor.c deleted file mode 100644 index 5b9ad6ca7cba..000000000000 --- a/trunk/drivers/macintosh/windfarm_max6690_sensor.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Windfarm PowerMac thermal control. MAX6690 sensor. - * - * Copyright (C) 2005 Paul Mackerras, IBM Corp. - * - * Use and redistribute under the terms of the GNU GPL v2. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "windfarm.h" - -#define VERSION "0.1" - -/* This currently only exports the external temperature sensor, - since that's all the control loops need. */ - -/* Some MAX6690 register numbers */ -#define MAX6690_INTERNAL_TEMP 0 -#define MAX6690_EXTERNAL_TEMP 1 - -struct wf_6690_sensor { - struct i2c_client i2c; - struct wf_sensor sens; -}; - -#define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) -#define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c) - -static int wf_max6690_attach(struct i2c_adapter *adapter); -static int wf_max6690_detach(struct i2c_client *client); - -static struct i2c_driver wf_max6690_driver = { - .driver = { - .name = "wf_max6690", - }, - .attach_adapter = wf_max6690_attach, - .detach_client = wf_max6690_detach, -}; - -static int wf_max6690_get(struct wf_sensor *sr, s32 *value) -{ - struct wf_6690_sensor *max = wf_to_6690(sr); - s32 data; - - if (max->i2c.adapter == NULL) - return -ENODEV; - - /* chip gets initialized by firmware */ - data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP); - if (data < 0) - return data; - *value = data << 16; - return 0; -} - -static void wf_max6690_release(struct wf_sensor *sr) -{ - struct wf_6690_sensor *max = wf_to_6690(sr); - - if (max->i2c.adapter) { - i2c_detach_client(&max->i2c); - max->i2c.adapter = NULL; - } - kfree(max); -} - -static struct wf_sensor_ops wf_max6690_ops = { - .get_value = wf_max6690_get, - .release = wf_max6690_release, - .owner = THIS_MODULE, -}; - -static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr) -{ - struct wf_6690_sensor *max; - char *name = "u4-temp"; - - max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); - if (max == NULL) { - printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " - "no memory\n", name); - return; - } - - max->sens.ops = &wf_max6690_ops; - max->sens.name = name; - max->i2c.addr = addr >> 1; - max->i2c.adapter = adapter; - max->i2c.driver = &wf_max6690_driver; - strncpy(max->i2c.name, name, I2C_NAME_SIZE-1); - - if (i2c_attach_client(&max->i2c)) { - printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); - goto fail; - } - - if (wf_register_sensor(&max->sens)) { - i2c_detach_client(&max->i2c); - goto fail; - } - - return; - - fail: - kfree(max); -} - -static int wf_max6690_attach(struct i2c_adapter *adapter) -{ - struct device_node *busnode, *dev = NULL; - struct pmac_i2c_bus *bus; - const char *loc; - u32 *reg; - - bus = pmac_i2c_adapter_to_bus(adapter); - if (bus == NULL) - return -ENODEV; - busnode = pmac_i2c_get_bus_node(bus); - - while ((dev = of_get_next_child(busnode, dev)) != NULL) { - if (!device_is_compatible(dev, "max6690")) - continue; - loc = get_property(dev, "hwsensor-location", NULL); - reg = (u32 *) get_property(dev, "reg", NULL); - if (!loc || !reg) - continue; - printk("found max6690, loc=%s reg=%x\n", loc, *reg); - if (strcmp(loc, "BACKSIDE")) - continue; - wf_max6690_create(adapter, *reg); - } - - return 0; -} - -static int wf_max6690_detach(struct i2c_client *client) -{ - struct wf_6690_sensor *max = i2c_to_6690(client); - - max->i2c.adapter = NULL; - wf_unregister_sensor(&max->sens); - - return 0; -} - -static int __init wf_max6690_sensor_init(void) -{ - return i2c_add_driver(&wf_max6690_driver); -} - -static void __exit wf_max6690_sensor_exit(void) -{ - i2c_del_driver(&wf_max6690_driver); -} - -module_init(wf_max6690_sensor_init); -module_exit(wf_max6690_sensor_exit); - -MODULE_AUTHOR("Paul Mackerras "); -MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/macintosh/windfarm_pid.c b/trunk/drivers/macintosh/windfarm_pid.c index 0842432e27ad..2e803b368757 100644 --- a/trunk/drivers/macintosh/windfarm_pid.c +++ b/trunk/drivers/macintosh/windfarm_pid.c @@ -88,8 +88,8 @@ EXPORT_SYMBOL_GPL(wf_cpu_pid_init); s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) { - s64 integ, deriv, prop; - s32 error, target, sval, adj; + s64 error, integ, deriv, prop; + s32 target, sval, adj; int i, hlen = st->param.history_len; /* Calculate error term */ @@ -117,7 +117,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) integ += st->errors[(st->index + hlen - i) % hlen]; integ *= st->param.interval; integ *= st->param.gr; - sval = st->param.tmax - (s32)(integ >> 20); + sval = st->param.tmax - ((integ >> 20) & 0xffffffff); adj = min(st->param.ttarget, sval); DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj); @@ -129,7 +129,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) deriv *= st->param.gd; /* Calculate proportional term */ - prop = st->last_delta = (new_temp - adj); + prop = (new_temp - adj); prop *= st->param.gp; DBG("deriv: %lx, prop: %lx\n", deriv, prop); diff --git a/trunk/drivers/macintosh/windfarm_pid.h b/trunk/drivers/macintosh/windfarm_pid.h index bbccc22d42b8..a364c2a2499c 100644 --- a/trunk/drivers/macintosh/windfarm_pid.h +++ b/trunk/drivers/macintosh/windfarm_pid.h @@ -72,7 +72,6 @@ struct wf_cpu_pid_state { int index; /* index of current power */ int tindex; /* index of current temp */ s32 target; /* current target value */ - s32 last_delta; /* last Tactual - Ttarget */ s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ s32 temps[2]; /* temp. history buffer */ diff --git a/trunk/drivers/macintosh/windfarm_pm112.c b/trunk/drivers/macintosh/windfarm_pm112.c deleted file mode 100644 index c2a4e689c784..000000000000 --- a/trunk/drivers/macintosh/windfarm_pm112.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - * Windfarm PowerMac thermal control. - * Control loops for machines with SMU and PPC970MP processors. - * - * Copyright (C) 2005 Paul Mackerras, IBM Corp. - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * Use and redistribute under the terms of the GNU GPL v2. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "windfarm.h" -#include "windfarm_pid.h" - -#define VERSION "0.2" - -#define DEBUG -#undef LOTSA_DEBUG - -#ifdef DEBUG -#define DBG(args...) printk(args) -#else -#define DBG(args...) do { } while(0) -#endif - -#ifdef LOTSA_DEBUG -#define DBG_LOTS(args...) printk(args) -#else -#define DBG_LOTS(args...) do { } while(0) -#endif - -/* define this to force CPU overtemp to 60 degree, useful for testing - * the overtemp code - */ -#undef HACKED_OVERTEMP - -/* We currently only handle 2 chips, 4 cores... */ -#define NR_CHIPS 2 -#define NR_CORES 4 -#define NR_CPU_FANS 3 * NR_CHIPS - -/* Controls and sensors */ -static struct wf_sensor *sens_cpu_temp[NR_CORES]; -static struct wf_sensor *sens_cpu_power[NR_CORES]; -static struct wf_sensor *hd_temp; -static struct wf_sensor *slots_power; -static struct wf_sensor *u4_temp; - -static struct wf_control *cpu_fans[NR_CPU_FANS]; -static char *cpu_fan_names[NR_CPU_FANS] = { - "cpu-rear-fan-0", - "cpu-rear-fan-1", - "cpu-front-fan-0", - "cpu-front-fan-1", - "cpu-pump-0", - "cpu-pump-1", -}; -static struct wf_control *cpufreq_clamp; - -/* Second pump isn't required (and isn't actually present) */ -#define CPU_FANS_REQD (NR_CPU_FANS - 2) -#define FIRST_PUMP 4 -#define LAST_PUMP 5 - -/* We keep a temperature history for average calculation of 180s */ -#define CPU_TEMP_HIST_SIZE 180 - -/* Scale factor for fan speed, *100 */ -static int cpu_fan_scale[NR_CPU_FANS] = { - 100, - 100, - 97, /* inlet fans run at 97% of exhaust fan */ - 97, - 100, /* updated later */ - 100, /* updated later */ -}; - -static struct wf_control *backside_fan; -static struct wf_control *slots_fan; -static struct wf_control *drive_bay_fan; - -/* PID loop state */ -static struct wf_cpu_pid_state cpu_pid[NR_CORES]; -static u32 cpu_thist[CPU_TEMP_HIST_SIZE]; -static int cpu_thist_pt; -static s64 cpu_thist_total; -static s32 cpu_all_tmax = 100 << 16; -static int cpu_last_target; -static struct wf_pid_state backside_pid; -static int backside_tick; -static struct wf_pid_state slots_pid; -static int slots_started; -static struct wf_pid_state drive_bay_pid; -static int drive_bay_tick; - -static int nr_cores; -static int have_all_controls; -static int have_all_sensors; -static int started; - -static int failure_state; -#define FAILURE_SENSOR 1 -#define FAILURE_FAN 2 -#define FAILURE_PERM 4 -#define FAILURE_LOW_OVERTEMP 8 -#define FAILURE_HIGH_OVERTEMP 16 - -/* Overtemp values */ -#define LOW_OVER_AVERAGE 0 -#define LOW_OVER_IMMEDIATE (10 << 16) -#define LOW_OVER_CLEAR ((-10) << 16) -#define HIGH_OVER_IMMEDIATE (14 << 16) -#define HIGH_OVER_AVERAGE (10 << 16) -#define HIGH_OVER_IMMEDIATE (14 << 16) - - -/* Implementation... */ -static int create_cpu_loop(int cpu) -{ - int chip = cpu / 2; - int core = cpu & 1; - struct smu_sdbp_header *hdr; - struct smu_sdbp_cpupiddata *piddata; - struct wf_cpu_pid_param pid; - struct wf_control *main_fan = cpu_fans[0]; - s32 tmax; - int fmin; - - /* Get PID params from the appropriate SAT */ - hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL); - if (hdr == NULL) { - printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n"); - return -EINVAL; - } - piddata = (struct smu_sdbp_cpupiddata *)&hdr[1]; - - /* Get FVT params to get Tmax; if not found, assume default */ - hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL); - if (hdr) { - struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1]; - tmax = fvt->maxtemp << 16; - } else - tmax = 95 << 16; /* default to 95 degrees C */ - - /* We keep a global tmax for overtemp calculations */ - if (tmax < cpu_all_tmax) - cpu_all_tmax = tmax; - - /* - * Darwin has a minimum fan speed of 1000 rpm for the 4-way and - * 515 for the 2-way. That appears to be overkill, so for now, - * impose a minimum of 750 or 515. - */ - fmin = (nr_cores > 2) ? 750 : 515; - - /* Initialize PID loop */ - pid.interval = 1; /* seconds */ - pid.history_len = piddata->history_len; - pid.gd = piddata->gd; - pid.gp = piddata->gp; - pid.gr = piddata->gr / piddata->history_len; - pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8); - pid.ttarget = tmax - (piddata->target_temp_delta << 16); - pid.tmax = tmax; - pid.min = main_fan->ops->get_min(main_fan); - pid.max = main_fan->ops->get_max(main_fan); - if (pid.min < fmin) - pid.min = fmin; - - wf_cpu_pid_init(&cpu_pid[cpu], &pid); - return 0; -} - -static void cpu_max_all_fans(void) -{ - int i; - - /* We max all CPU fans in case of a sensor error. We also do the - * cpufreq clamping now, even if it's supposedly done later by the - * generic code anyway, we do it earlier here to react faster - */ - if (cpufreq_clamp) - wf_control_set_max(cpufreq_clamp); - for (i = 0; i < NR_CPU_FANS; ++i) - if (cpu_fans[i]) - wf_control_set_max(cpu_fans[i]); -} - -static int cpu_check_overtemp(s32 temp) -{ - int new_state = 0; - s32 t_avg, t_old; - - /* First check for immediate overtemps */ - if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) { - new_state |= FAILURE_LOW_OVERTEMP; - if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) - printk(KERN_ERR "windfarm: Overtemp due to immediate CPU" - " temperature !\n"); - } - if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) { - new_state |= FAILURE_HIGH_OVERTEMP; - if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) - printk(KERN_ERR "windfarm: Critical overtemp due to" - " immediate CPU temperature !\n"); - } - - /* We calculate a history of max temperatures and use that for the - * overtemp management - */ - t_old = cpu_thist[cpu_thist_pt]; - cpu_thist[cpu_thist_pt] = temp; - cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE; - cpu_thist_total -= t_old; - cpu_thist_total += temp; - t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE; - - DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n", - FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp)); - - /* Now check for average overtemps */ - if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) { - new_state |= FAILURE_LOW_OVERTEMP; - if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) - printk(KERN_ERR "windfarm: Overtemp due to average CPU" - " temperature !\n"); - } - if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) { - new_state |= FAILURE_HIGH_OVERTEMP; - if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) - printk(KERN_ERR "windfarm: Critical overtemp due to" - " average CPU temperature !\n"); - } - - /* Now handle overtemp conditions. We don't currently use the windfarm - * overtemp handling core as it's not fully suited to the needs of those - * new machine. This will be fixed later. - */ - if (new_state) { - /* High overtemp -> immediate shutdown */ - if (new_state & FAILURE_HIGH_OVERTEMP) - machine_power_off(); - if ((failure_state & new_state) != new_state) - cpu_max_all_fans(); - failure_state |= new_state; - } else if ((failure_state & FAILURE_LOW_OVERTEMP) && - (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) { - printk(KERN_ERR "windfarm: Overtemp condition cleared !\n"); - failure_state &= ~FAILURE_LOW_OVERTEMP; - } - - return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP); -} - -static void cpu_fans_tick(void) -{ - int err, cpu; - s32 greatest_delta = 0; - s32 temp, power, t_max = 0; - int i, t, target = 0; - struct wf_sensor *sr; - struct wf_control *ct; - struct wf_cpu_pid_state *sp; - - DBG_LOTS(KERN_DEBUG); - for (cpu = 0; cpu < nr_cores; ++cpu) { - /* Get CPU core temperature */ - sr = sens_cpu_temp[cpu]; - err = sr->ops->get_value(sr, &temp); - if (err) { - DBG("\n"); - printk(KERN_WARNING "windfarm: CPU %d temperature " - "sensor error %d\n", cpu, err); - failure_state |= FAILURE_SENSOR; - cpu_max_all_fans(); - return; - } - - /* Keep track of highest temp */ - t_max = max(t_max, temp); - - /* Get CPU power */ - sr = sens_cpu_power[cpu]; - err = sr->ops->get_value(sr, &power); - if (err) { - DBG("\n"); - printk(KERN_WARNING "windfarm: CPU %d power " - "sensor error %d\n", cpu, err); - failure_state |= FAILURE_SENSOR; - cpu_max_all_fans(); - return; - } - - /* Run PID */ - sp = &cpu_pid[cpu]; - t = wf_cpu_pid_run(sp, power, temp); - - if (cpu == 0 || sp->last_delta > greatest_delta) { - greatest_delta = sp->last_delta; - target = t; - } - DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ", - cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp)); - } - DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max)); - - /* Darwin limits decrease to 20 per iteration */ - if (target < (cpu_last_target - 20)) - target = cpu_last_target - 20; - cpu_last_target = target; - for (cpu = 0; cpu < nr_cores; ++cpu) - cpu_pid[cpu].target = target; - - /* Handle possible overtemps */ - if (cpu_check_overtemp(t_max)) - return; - - /* Set fans */ - for (i = 0; i < NR_CPU_FANS; ++i) { - ct = cpu_fans[i]; - if (ct == NULL) - continue; - err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100); - if (err) { - printk(KERN_WARNING "windfarm: fan %s reports " - "error %d\n", ct->name, err); - failure_state |= FAILURE_FAN; - break; - } - } -} - -/* Backside/U4 fan */ -static struct wf_pid_param backside_param = { - .interval = 5, - .history_len = 2, - .gd = 48 << 20, - .gp = 5 << 20, - .gr = 0, - .itarget = 64 << 16, - .additive = 1, -}; - -static void backside_fan_tick(void) -{ - s32 temp; - int speed; - int err; - - if (!backside_fan || !u4_temp) - return; - if (!backside_tick) { - /* first time; initialize things */ - backside_param.min = backside_fan->ops->get_min(backside_fan); - backside_param.max = backside_fan->ops->get_max(backside_fan); - wf_pid_init(&backside_pid, &backside_param); - backside_tick = 1; - } - if (--backside_tick > 0) - return; - backside_tick = backside_pid.param.interval; - - err = u4_temp->ops->get_value(u4_temp, &temp); - if (err) { - printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n", - err); - failure_state |= FAILURE_SENSOR; - wf_control_set_max(backside_fan); - return; - } - speed = wf_pid_run(&backside_pid, temp); - DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n", - FIX32TOPRINT(temp), speed); - - err = backside_fan->ops->set_value(backside_fan, speed); - if (err) { - printk(KERN_WARNING "windfarm: backside fan error %d\n", err); - failure_state |= FAILURE_FAN; - } -} - -/* Drive bay fan */ -static struct wf_pid_param drive_bay_prm = { - .interval = 5, - .history_len = 2, - .gd = 30 << 20, - .gp = 5 << 20, - .gr = 0, - .itarget = 40 << 16, - .additive = 1, -}; - -static void drive_bay_fan_tick(void) -{ - s32 temp; - int speed; - int err; - - if (!drive_bay_fan || !hd_temp) - return; - if (!drive_bay_tick) { - /* first time; initialize things */ - drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan); - drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan); - wf_pid_init(&drive_bay_pid, &drive_bay_prm); - drive_bay_tick = 1; - } - if (--drive_bay_tick > 0) - return; - drive_bay_tick = drive_bay_pid.param.interval; - - err = hd_temp->ops->get_value(hd_temp, &temp); - if (err) { - printk(KERN_WARNING "windfarm: drive bay temp sensor " - "error %d\n", err); - failure_state |= FAILURE_SENSOR; - wf_control_set_max(drive_bay_fan); - return; - } - speed = wf_pid_run(&drive_bay_pid, temp); - DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n", - FIX32TOPRINT(temp), speed); - - err = drive_bay_fan->ops->set_value(drive_bay_fan, speed); - if (err) { - printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err); - failure_state |= FAILURE_FAN; - } -} - -/* PCI slots area fan */ -/* This makes the fan speed proportional to the power consumed */ -static struct wf_pid_param slots_param = { - .interval = 1, - .history_len = 2, - .gd = 0, - .gp = 0, - .gr = 0x1277952, - .itarget = 0, - .min = 1560, - .max = 3510, -}; - -static void slots_fan_tick(void) -{ - s32 power; - int speed; - int err; - - if (!slots_fan || !slots_power) - return; - if (!slots_started) { - /* first time; initialize things */ - wf_pid_init(&slots_pid, &slots_param); - slots_started = 1; - } - - err = slots_power->ops->get_value(slots_power, &power); - if (err) { - printk(KERN_WARNING "windfarm: slots power sensor error %d\n", - err); - failure_state |= FAILURE_SENSOR; - wf_control_set_max(slots_fan); - return; - } - speed = wf_pid_run(&slots_pid, power); - DBG_LOTS("slots PID power=%d.%.3d speed=%d\n", - FIX32TOPRINT(power), speed); - - err = slots_fan->ops->set_value(slots_fan, speed); - if (err) { - printk(KERN_WARNING "windfarm: slots fan error %d\n", err); - failure_state |= FAILURE_FAN; - } -} - -static void set_fail_state(void) -{ - int i; - - if (cpufreq_clamp) - wf_control_set_max(cpufreq_clamp); - for (i = 0; i < NR_CPU_FANS; ++i) - if (cpu_fans[i]) - wf_control_set_max(cpu_fans[i]); - if (backside_fan) - wf_control_set_max(backside_fan); - if (slots_fan) - wf_control_set_max(slots_fan); - if (drive_bay_fan) - wf_control_set_max(drive_bay_fan); -} - -static void pm112_tick(void) -{ - int i, last_failure; - - if (!started) { - started = 1; - for (i = 0; i < nr_cores; ++i) { - if (create_cpu_loop(i) < 0) { - failure_state = FAILURE_PERM; - set_fail_state(); - break; - } - } - DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax)); - -#ifdef HACKED_OVERTEMP - cpu_all_tmax = 60 << 16; -#endif - } - - /* Permanent failure, bail out */ - if (failure_state & FAILURE_PERM) - return; - /* Clear all failure bits except low overtemp which will be eventually - * cleared by the control loop itself - */ - last_failure = failure_state; - failure_state &= FAILURE_LOW_OVERTEMP; - cpu_fans_tick(); - backside_fan_tick(); - slots_fan_tick(); - drive_bay_fan_tick(); - - DBG_LOTS("last_failure: 0x%x, failure_state: %x\n", - last_failure, failure_state); - - /* Check for failures. Any failure causes cpufreq clamping */ - if (failure_state && last_failure == 0 && cpufreq_clamp) - wf_control_set_max(cpufreq_clamp); - if (failure_state == 0 && last_failure && cpufreq_clamp) - wf_control_set_min(cpufreq_clamp); - - /* That's it for now, we might want to deal with other failures - * differently in the future though - */ -} - -static void pm112_new_control(struct wf_control *ct) -{ - int i, max_exhaust; - - if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { - if (wf_get_control(ct) == 0) - cpufreq_clamp = ct; - } - - for (i = 0; i < NR_CPU_FANS; ++i) { - if (!strcmp(ct->name, cpu_fan_names[i])) { - if (cpu_fans[i] == NULL && wf_get_control(ct) == 0) - cpu_fans[i] = ct; - break; - } - } - if (i >= NR_CPU_FANS) { - /* not a CPU fan, try the others */ - if (!strcmp(ct->name, "backside-fan")) { - if (backside_fan == NULL && wf_get_control(ct) == 0) - backside_fan = ct; - } else if (!strcmp(ct->name, "slots-fan")) { - if (slots_fan == NULL && wf_get_control(ct) == 0) - slots_fan = ct; - } else if (!strcmp(ct->name, "drive-bay-fan")) { - if (drive_bay_fan == NULL && wf_get_control(ct) == 0) - drive_bay_fan = ct; - } - return; - } - - for (i = 0; i < CPU_FANS_REQD; ++i) - if (cpu_fans[i] == NULL) - return; - - /* work out pump scaling factors */ - max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]); - for (i = FIRST_PUMP; i <= LAST_PUMP; ++i) - if ((ct = cpu_fans[i]) != NULL) - cpu_fan_scale[i] = - ct->ops->get_max(ct) * 100 / max_exhaust; - - have_all_controls = 1; -} - -static void pm112_new_sensor(struct wf_sensor *sr) -{ - unsigned int i; - - if (have_all_sensors) - return; - if (!strncmp(sr->name, "cpu-temp-", 9)) { - i = sr->name[9] - '0'; - if (sr->name[10] == 0 && i < NR_CORES && - sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0) - sens_cpu_temp[i] = sr; - - } else if (!strncmp(sr->name, "cpu-power-", 10)) { - i = sr->name[10] - '0'; - if (sr->name[11] == 0 && i < NR_CORES && - sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0) - sens_cpu_power[i] = sr; - } else if (!strcmp(sr->name, "hd-temp")) { - if (hd_temp == NULL && wf_get_sensor(sr) == 0) - hd_temp = sr; - } else if (!strcmp(sr->name, "slots-power")) { - if (slots_power == NULL && wf_get_sensor(sr) == 0) - slots_power = sr; - } else if (!strcmp(sr->name, "u4-temp")) { - if (u4_temp == NULL && wf_get_sensor(sr) == 0) - u4_temp = sr; - } else - return; - - /* check if we have all the sensors we need */ - for (i = 0; i < nr_cores; ++i) - if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL) - return; - - have_all_sensors = 1; -} - -static int pm112_wf_notify(struct notifier_block *self, - unsigned long event, void *data) -{ - switch (event) { - case WF_EVENT_NEW_SENSOR: - pm112_new_sensor(data); - break; - case WF_EVENT_NEW_CONTROL: - pm112_new_control(data); - break; - case WF_EVENT_TICK: - if (have_all_controls && have_all_sensors) - pm112_tick(); - } - return 0; -} - -static struct notifier_block pm112_events = { - .notifier_call = pm112_wf_notify, -}; - -static int wf_pm112_probe(struct device *dev) -{ - wf_register_client(&pm112_events); - return 0; -} - -static int wf_pm112_remove(struct device *dev) -{ - wf_unregister_client(&pm112_events); - /* should release all sensors and controls */ - return 0; -} - -static struct device_driver wf_pm112_driver = { - .name = "windfarm", - .bus = &platform_bus_type, - .probe = wf_pm112_probe, - .remove = wf_pm112_remove, -}; - -static int __init wf_pm112_init(void) -{ - struct device_node *cpu; - - if (!machine_is_compatible("PowerMac11,2")) - return -ENODEV; - - /* Count the number of CPU cores */ - nr_cores = 0; - for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; ) - ++nr_cores; - - printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); - driver_register(&wf_pm112_driver); - return 0; -} - -static void __exit wf_pm112_exit(void) -{ - driver_unregister(&wf_pm112_driver); -} - -module_init(wf_pm112_init); -module_exit(wf_pm112_exit); - -MODULE_AUTHOR("Paul Mackerras "); -MODULE_DESCRIPTION("Thermal control for PowerMac11,2"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/macintosh/windfarm_pm81.c b/trunk/drivers/macintosh/windfarm_pm81.c index f1df6efcbe68..eb69a601e765 100644 --- a/trunk/drivers/macintosh/windfarm_pm81.c +++ b/trunk/drivers/macintosh/windfarm_pm81.c @@ -538,6 +538,45 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st) } } + +/* + * ****** Attributes ****** + * + */ + +#define BUILD_SHOW_FUNC_FIX(name, data) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + ssize_t r; \ + s32 val = 0; \ + data->ops->get_value(data, &val); \ + r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ + return r; \ +} \ +static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); + + +#define BUILD_SHOW_FUNC_INT(name, data) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + s32 val = 0; \ + data->ops->get_value(data, &val); \ + return sprintf(buf, "%d", val); \ +} \ +static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); + +BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); +BUILD_SHOW_FUNC_INT(sys_fan, fan_system); +BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); + +BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); +BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); +BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); + /* * ****** Setup / Init / Misc ... ****** * @@ -615,13 +654,17 @@ static void wf_smu_new_control(struct wf_control *ct) return; if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) { - if (wf_get_control(ct) == 0) + if (wf_get_control(ct) == 0) { fan_cpu_main = ct; + device_create_file(wf_smu_dev, &dev_attr_cpu_fan); + } } if (fan_system == NULL && !strcmp(ct->name, "system-fan")) { - if (wf_get_control(ct) == 0) + if (wf_get_control(ct) == 0) { fan_system = ct; + device_create_file(wf_smu_dev, &dev_attr_sys_fan); + } } if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { @@ -640,8 +683,10 @@ static void wf_smu_new_control(struct wf_control *ct) } if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { - if (wf_get_control(ct) == 0) + if (wf_get_control(ct) == 0) { fan_hd = ct; + device_create_file(wf_smu_dev, &dev_attr_hd_fan); + } } if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp) @@ -654,18 +699,24 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) return; if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { - if (wf_get_sensor(sr) == 0) + if (wf_get_sensor(sr) == 0) { sensor_cpu_power = sr; + device_create_file(wf_smu_dev, &dev_attr_cpu_power); + } } if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { - if (wf_get_sensor(sr) == 0) + if (wf_get_sensor(sr) == 0) { sensor_cpu_temp = sr; + device_create_file(wf_smu_dev, &dev_attr_cpu_temp); + } } if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { - if (wf_get_sensor(sr) == 0) + if (wf_get_sensor(sr) == 0) { sensor_hd_temp = sr; + device_create_file(wf_smu_dev, &dev_attr_hd_temp); + } } if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp) @@ -743,20 +794,32 @@ static int wf_smu_remove(struct device *ddev) * with that except by adding locks all over... I'll do that * eventually but heh, who ever rmmod this module anyway ? */ - if (sensor_cpu_power) + if (sensor_cpu_power) { + device_remove_file(wf_smu_dev, &dev_attr_cpu_power); wf_put_sensor(sensor_cpu_power); - if (sensor_cpu_temp) + } + if (sensor_cpu_temp) { + device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); wf_put_sensor(sensor_cpu_temp); - if (sensor_hd_temp) + } + if (sensor_hd_temp) { + device_remove_file(wf_smu_dev, &dev_attr_hd_temp); wf_put_sensor(sensor_hd_temp); + } /* Release all controls */ - if (fan_cpu_main) + if (fan_cpu_main) { + device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); wf_put_control(fan_cpu_main); - if (fan_hd) + } + if (fan_hd) { + device_remove_file(wf_smu_dev, &dev_attr_hd_fan); wf_put_control(fan_hd); - if (fan_system) + } + if (fan_system) { + device_remove_file(wf_smu_dev, &dev_attr_sys_fan); wf_put_control(fan_system); + } if (cpufreq_clamp) wf_put_control(cpufreq_clamp); diff --git a/trunk/drivers/macintosh/windfarm_pm91.c b/trunk/drivers/macintosh/windfarm_pm91.c index 0d6372e96d32..43243cf7410b 100644 --- a/trunk/drivers/macintosh/windfarm_pm91.c +++ b/trunk/drivers/macintosh/windfarm_pm91.c @@ -457,6 +457,45 @@ static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st) } +/* + * ****** Attributes ****** + * + */ + +#define BUILD_SHOW_FUNC_FIX(name, data) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + ssize_t r; \ + s32 val = 0; \ + data->ops->get_value(data, &val); \ + r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ + return r; \ +} \ +static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); + + +#define BUILD_SHOW_FUNC_INT(name, data) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + s32 val = 0; \ + data->ops->get_value(data, &val); \ + return sprintf(buf, "%d", val); \ +} \ +static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); + +BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); +BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); +BUILD_SHOW_FUNC_INT(slots_fan, fan_slots); + +BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); +BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); +BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); +BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power); + /* * ****** Setup / Init / Misc ... ****** * @@ -542,8 +581,10 @@ static void wf_smu_new_control(struct wf_control *ct) return; if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) { - if (wf_get_control(ct) == 0) + if (wf_get_control(ct) == 0) { fan_cpu_main = ct; + device_create_file(wf_smu_dev, &dev_attr_cpu_fan); + } } if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) { @@ -562,13 +603,17 @@ static void wf_smu_new_control(struct wf_control *ct) } if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { - if (wf_get_control(ct) == 0) + if (wf_get_control(ct) == 0) { fan_hd = ct; + device_create_file(wf_smu_dev, &dev_attr_hd_fan); + } } if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) { - if (wf_get_control(ct) == 0) + if (wf_get_control(ct) == 0) { fan_slots = ct; + device_create_file(wf_smu_dev, &dev_attr_slots_fan); + } } if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd && @@ -582,23 +627,31 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) return; if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { - if (wf_get_sensor(sr) == 0) + if (wf_get_sensor(sr) == 0) { sensor_cpu_power = sr; + device_create_file(wf_smu_dev, &dev_attr_cpu_power); + } } if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { - if (wf_get_sensor(sr) == 0) + if (wf_get_sensor(sr) == 0) { sensor_cpu_temp = sr; + device_create_file(wf_smu_dev, &dev_attr_cpu_temp); + } } if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { - if (wf_get_sensor(sr) == 0) + if (wf_get_sensor(sr) == 0) { sensor_hd_temp = sr; + device_create_file(wf_smu_dev, &dev_attr_hd_temp); + } } if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) { - if (wf_get_sensor(sr) == 0) + if (wf_get_sensor(sr) == 0) { sensor_slots_power = sr; + device_create_file(wf_smu_dev, &dev_attr_slots_power); + } } if (sensor_cpu_power && sensor_cpu_temp && @@ -667,26 +720,40 @@ static int wf_smu_remove(struct device *ddev) * with that except by adding locks all over... I'll do that * eventually but heh, who ever rmmod this module anyway ? */ - if (sensor_cpu_power) + if (sensor_cpu_power) { + device_remove_file(wf_smu_dev, &dev_attr_cpu_power); wf_put_sensor(sensor_cpu_power); - if (sensor_cpu_temp) + } + if (sensor_cpu_temp) { + device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); wf_put_sensor(sensor_cpu_temp); - if (sensor_hd_temp) + } + if (sensor_hd_temp) { + device_remove_file(wf_smu_dev, &dev_attr_hd_temp); wf_put_sensor(sensor_hd_temp); - if (sensor_slots_power) + } + if (sensor_slots_power) { + device_remove_file(wf_smu_dev, &dev_attr_slots_power); wf_put_sensor(sensor_slots_power); + } /* Release all controls */ - if (fan_cpu_main) + if (fan_cpu_main) { + device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); wf_put_control(fan_cpu_main); + } if (fan_cpu_second) wf_put_control(fan_cpu_second); if (fan_cpu_third) wf_put_control(fan_cpu_third); - if (fan_hd) + if (fan_hd) { + device_remove_file(wf_smu_dev, &dev_attr_hd_fan); wf_put_control(fan_hd); - if (fan_slots) + } + if (fan_slots) { + device_remove_file(wf_smu_dev, &dev_attr_slots_fan); wf_put_control(fan_slots); + } if (cpufreq_clamp) wf_put_control(cpufreq_clamp); diff --git a/trunk/drivers/macintosh/windfarm_smu_controls.c b/trunk/drivers/macintosh/windfarm_smu_controls.c index a9e88edc0c72..4d811600bdab 100644 --- a/trunk/drivers/macintosh/windfarm_smu_controls.c +++ b/trunk/drivers/macintosh/windfarm_smu_controls.c @@ -24,7 +24,7 @@ #include "windfarm.h" -#define VERSION "0.4" +#define VERSION "0.3" #undef DEBUG @@ -34,8 +34,6 @@ #define DBG(args...) do { } while(0) #endif -static int smu_supports_new_fans_ops = 1; - /* * SMU fans control object */ @@ -61,49 +59,23 @@ static int smu_set_fan(int pwm, u8 id, u16 value) /* Fill SMU command structure */ cmd.cmd = SMU_CMD_FAN_COMMAND; - - /* The SMU has an "old" and a "new" way of setting the fan speed - * Unfortunately, I found no reliable way to know which one works - * on a given machine model. After some investigations it appears - * that MacOS X just tries the new one, and if it fails fallbacks - * to the old ones ... Ugh. - */ - retry: - if (smu_supports_new_fans_ops) { - buffer[0] = 0x30; - buffer[1] = id; - *((u16 *)(&buffer[2])) = value; - cmd.data_len = 4; - } else { - if (id > 7) - return -EINVAL; - /* Fill argument buffer */ - memset(buffer, 0, 16); - buffer[0] = pwm ? 0x10 : 0x00; - buffer[1] = 0x01 << id; - *((u16 *)&buffer[2 + id * 2]) = value; - cmd.data_len = 14; - } - + cmd.data_len = 14; cmd.reply_len = 16; cmd.data_buf = cmd.reply_buf = buffer; cmd.status = 0; cmd.done = smu_done_complete; cmd.misc = ∁ + /* Fill argument buffer */ + memset(buffer, 0, 16); + buffer[0] = pwm ? 0x10 : 0x00; + buffer[1] = 0x01 << id; + *((u16 *)&buffer[2 + id * 2]) = value; + rc = smu_queue_cmd(&cmd); if (rc) return rc; wait_for_completion(&comp); - - /* Handle fallback (see coment above) */ - if (cmd.status != 0 && smu_supports_new_fans_ops) { - printk(KERN_WARNING "windfarm: SMU failed new fan command " - "falling back to old method\n"); - smu_supports_new_fans_ops = 0; - goto retry; - } - return cmd.status; } @@ -186,29 +158,19 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, /* Names used on desktop models */ if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") || - !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan") || - !strcmp(l, "CPU A EXHAUST")) + !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan")) fct->ctrl.name = "cpu-rear-fan-0"; - else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1") || - !strcmp(l, "CPU B EXHAUST")) + else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1")) fct->ctrl.name = "cpu-rear-fan-1"; else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") || - !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan") || - !strcmp(l, "CPU A INTAKE")) + !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan")) fct->ctrl.name = "cpu-front-fan-0"; - else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1") || - !strcmp(l, "CPU B INTAKE")) + else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1")) fct->ctrl.name = "cpu-front-fan-1"; - else if (!strcmp(l, "CPU A PUMP")) - fct->ctrl.name = "cpu-pump-0"; - else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") || - !strcmp(l, "EXPANSION SLOTS INTAKE")) + else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan")) fct->ctrl.name = "slots-fan"; - else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay") || - !strcmp(l, "DRIVE BAY A INTAKE")) + else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay")) fct->ctrl.name = "drive-bay-fan"; - else if (!strcmp(l, "BACKSIDE")) - fct->ctrl.name = "backside-fan"; /* Names used on iMac models */ if (!strcmp(l, "System Fan") || !strcmp(l, "System fan")) @@ -261,8 +223,7 @@ static int __init smu_controls_init(void) /* Look for RPM fans */ for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) - if (!strcmp(fans->name, "rpm-fans") || - device_is_compatible(fans, "smu-rpm-fans")) + if (!strcmp(fans->name, "rpm-fans")) break; for (fan = NULL; fans && (fan = of_get_next_child(fans, fan)) != NULL;) { diff --git a/trunk/drivers/macintosh/windfarm_smu_sat.c b/trunk/drivers/macintosh/windfarm_smu_sat.c deleted file mode 100644 index 3a32c59494f2..000000000000 --- a/trunk/drivers/macintosh/windfarm_smu_sat.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Windfarm PowerMac thermal control. SMU "satellite" controller sensors. - * - * Copyright (C) 2005 Paul Mackerras, IBM Corp. - * - * Released under the terms of the GNU GPL v2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "windfarm.h" - -#define VERSION "0.2" - -#define DEBUG - -#ifdef DEBUG -#define DBG(args...) printk(args) -#else -#define DBG(args...) do { } while(0) -#endif - -/* If the cache is older than 800ms we'll refetch it */ -#define MAX_AGE msecs_to_jiffies(800) - -struct wf_sat { - int nr; - atomic_t refcnt; - struct semaphore mutex; - unsigned long last_read; /* jiffies when cache last updated */ - u8 cache[16]; - struct i2c_client i2c; - struct device_node *node; -}; - -static struct wf_sat *sats[2]; - -struct wf_sat_sensor { - int index; - int index2; /* used for power sensors */ - int shift; - struct wf_sat *sat; - struct wf_sensor sens; -}; - -#define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) -#define i2c_to_sat(c) container_of(c, struct wf_sat, i2c) - -static int wf_sat_attach(struct i2c_adapter *adapter); -static int wf_sat_detach(struct i2c_client *client); - -static struct i2c_driver wf_sat_driver = { - .driver = { - .name = "wf_smu_sat", - }, - .attach_adapter = wf_sat_attach, - .detach_client = wf_sat_detach, -}; - -/* - * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested - * length down to the low-level driver, so we use this, which - * works well enough with the SMU i2c driver code... - */ -static int sat_read_block(struct i2c_client *client, u8 command, - u8 *values, int len) -{ - union i2c_smbus_data data; - int err; - - data.block[0] = len; - err = i2c_smbus_xfer(client->adapter, client->addr, client->flags, - I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA, - &data); - if (!err) - memcpy(values, data.block, len); - return err; -} - -struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, - unsigned int *size) -{ - struct wf_sat *sat; - int err; - unsigned int i, len; - u8 *buf; - u8 data[4]; - - /* TODO: Add the resulting partition to the device-tree */ - - if (sat_id > 1 || (sat = sats[sat_id]) == NULL) - return NULL; - - err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8); - if (err) { - printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); - return NULL; - } - - len = i2c_smbus_read_word_data(&sat->i2c, 9); - if (len < 0) { - printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); - return NULL; - } - if (len == 0) { - printk(KERN_ERR "smu_sat_get_sdb_part no partition %x\n", id); - return NULL; - } - - len = le16_to_cpu(len); - len = (len + 3) & ~3; - buf = kmalloc(len, GFP_KERNEL); - if (buf == NULL) - return NULL; - - for (i = 0; i < len; i += 4) { - err = sat_read_block(&sat->i2c, 0xa, data, 4); - if (err) { - printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", - err); - goto fail; - } - buf[i] = data[1]; - buf[i+1] = data[0]; - buf[i+2] = data[3]; - buf[i+3] = data[2]; - } -#ifdef DEBUG - DBG(KERN_DEBUG "sat %d partition %x:", sat_id, id); - for (i = 0; i < len; ++i) - DBG(" %x", buf[i]); - DBG("\n"); -#endif - - if (size) - *size = len; - return (struct smu_sdbp_header *) buf; - - fail: - kfree(buf); - return NULL; -} - -/* refresh the cache */ -static int wf_sat_read_cache(struct wf_sat *sat) -{ - int err; - - err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16); - if (err) - return err; - sat->last_read = jiffies; -#ifdef LOTSA_DEBUG - { - int i; - DBG(KERN_DEBUG "wf_sat_get: data is"); - for (i = 0; i < 16; ++i) - DBG(" %.2x", sat->cache[i]); - DBG("\n"); - } -#endif - return 0; -} - -static int wf_sat_get(struct wf_sensor *sr, s32 *value) -{ - struct wf_sat_sensor *sens = wf_to_sat(sr); - struct wf_sat *sat = sens->sat; - int i, err; - s32 val; - - if (sat->i2c.adapter == NULL) - return -ENODEV; - - down(&sat->mutex); - if (time_after(jiffies, (sat->last_read + MAX_AGE))) { - err = wf_sat_read_cache(sat); - if (err) - goto fail; - } - - i = sens->index * 2; - val = ((sat->cache[i] << 8) + sat->cache[i+1]) << sens->shift; - if (sens->index2 >= 0) { - i = sens->index2 * 2; - /* 4.12 * 8.8 -> 12.20; shift right 4 to get 16.16 */ - val = (val * ((sat->cache[i] << 8) + sat->cache[i+1])) >> 4; - } - - *value = val; - err = 0; - - fail: - up(&sat->mutex); - return err; -} - -static void wf_sat_release(struct wf_sensor *sr) -{ - struct wf_sat_sensor *sens = wf_to_sat(sr); - struct wf_sat *sat = sens->sat; - - if (atomic_dec_and_test(&sat->refcnt)) { - if (sat->i2c.adapter) { - i2c_detach_client(&sat->i2c); - sat->i2c.adapter = NULL; - } - if (sat->nr >= 0) - sats[sat->nr] = NULL; - kfree(sat); - } - kfree(sens); -} - -static struct wf_sensor_ops wf_sat_ops = { - .get_value = wf_sat_get, - .release = wf_sat_release, - .owner = THIS_MODULE, -}; - -static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) -{ - struct wf_sat *sat; - struct wf_sat_sensor *sens; - u32 *reg; - char *loc, *type; - u8 addr, chip, core; - struct device_node *child; - int shift, cpu, index; - char *name; - int vsens[2], isens[2]; - - reg = (u32 *) get_property(dev, "reg", NULL); - if (reg == NULL) - return; - addr = *reg; - DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr); - - sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); - if (sat == NULL) - return; - sat->nr = -1; - sat->node = of_node_get(dev); - atomic_set(&sat->refcnt, 0); - init_MUTEX(&sat->mutex); - sat->i2c.addr = (addr >> 1) & 0x7f; - sat->i2c.adapter = adapter; - sat->i2c.driver = &wf_sat_driver; - strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1); - - if (i2c_attach_client(&sat->i2c)) { - printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n"); - goto fail; - } - - vsens[0] = vsens[1] = -1; - isens[0] = isens[1] = -1; - child = NULL; - while ((child = of_get_next_child(dev, child)) != NULL) { - reg = (u32 *) get_property(child, "reg", NULL); - type = get_property(child, "device_type", NULL); - loc = get_property(child, "location", NULL); - if (reg == NULL || loc == NULL) - continue; - - /* the cooked sensors are between 0x30 and 0x37 */ - if (*reg < 0x30 || *reg > 0x37) - continue; - index = *reg - 0x30; - - /* expect location to be CPU [AB][01] ... */ - if (strncmp(loc, "CPU ", 4) != 0) - continue; - chip = loc[4] - 'A'; - core = loc[5] - '0'; - if (chip > 1 || core > 1) { - printk(KERN_ERR "wf_sat_create: don't understand " - "location %s for %s\n", loc, child->full_name); - continue; - } - cpu = 2 * chip + core; - if (sat->nr < 0) - sat->nr = chip; - else if (sat->nr != chip) { - printk(KERN_ERR "wf_sat_create: can't cope with " - "multiple CPU chips on one SAT (%s)\n", loc); - continue; - } - - if (strcmp(type, "voltage-sensor") == 0) { - name = "cpu-voltage"; - shift = 4; - vsens[core] = index; - } else if (strcmp(type, "current-sensor") == 0) { - name = "cpu-current"; - shift = 8; - isens[core] = index; - } else if (strcmp(type, "temp-sensor") == 0) { - name = "cpu-temp"; - shift = 10; - } else - continue; /* hmmm shouldn't happen */ - - /* the +16 is enough for "cpu-voltage-n" */ - sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); - if (sens == NULL) { - printk(KERN_ERR "wf_sat_create: couldn't create " - "%s sensor %d (no memory)\n", name, cpu); - continue; - } - sens->index = index; - sens->index2 = -1; - sens->shift = shift; - sens->sat = sat; - atomic_inc(&sat->refcnt); - sens->sens.ops = &wf_sat_ops; - sens->sens.name = (char *) (sens + 1); - snprintf(sens->sens.name, 16, "%s-%d", name, cpu); - - if (wf_register_sensor(&sens->sens)) { - atomic_dec(&sat->refcnt); - kfree(sens); - } - } - - /* make the power sensors */ - for (core = 0; core < 2; ++core) { - if (vsens[core] < 0 || isens[core] < 0) - continue; - cpu = 2 * sat->nr + core; - sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); - if (sens == NULL) { - printk(KERN_ERR "wf_sat_create: couldn't create power " - "sensor %d (no memory)\n", cpu); - continue; - } - sens->index = vsens[core]; - sens->index2 = isens[core]; - sens->shift = 0; - sens->sat = sat; - atomic_inc(&sat->refcnt); - sens->sens.ops = &wf_sat_ops; - sens->sens.name = (char *) (sens + 1); - snprintf(sens->sens.name, 16, "cpu-power-%d", cpu); - - if (wf_register_sensor(&sens->sens)) { - atomic_dec(&sat->refcnt); - kfree(sens); - } - } - - if (sat->nr >= 0) - sats[sat->nr] = sat; - - return; - - fail: - kfree(sat); -} - -static int wf_sat_attach(struct i2c_adapter *adapter) -{ - struct device_node *busnode, *dev = NULL; - struct pmac_i2c_bus *bus; - - bus = pmac_i2c_adapter_to_bus(adapter); - if (bus == NULL) - return -ENODEV; - busnode = pmac_i2c_get_bus_node(bus); - - while ((dev = of_get_next_child(busnode, dev)) != NULL) - if (device_is_compatible(dev, "smu-sat")) - wf_sat_create(adapter, dev); - return 0; -} - -static int wf_sat_detach(struct i2c_client *client) -{ - struct wf_sat *sat = i2c_to_sat(client); - - /* XXX TODO */ - - sat->i2c.adapter = NULL; - return 0; -} - -static int __init sat_sensors_init(void) -{ - int err; - - err = i2c_add_driver(&wf_sat_driver); - if (err < 0) - return err; - return 0; -} - -static void __exit sat_sensors_exit(void) -{ - i2c_del_driver(&wf_sat_driver); -} - -module_init(sat_sensors_init); -/*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */ - -MODULE_AUTHOR("Paul Mackerras "); -MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/macintosh/windfarm_smu_sensors.c b/trunk/drivers/macintosh/windfarm_smu_sensors.c index bed25dcf8a1e..1a00d9c75a23 100644 --- a/trunk/drivers/macintosh/windfarm_smu_sensors.c +++ b/trunk/drivers/macintosh/windfarm_smu_sensors.c @@ -220,29 +220,14 @@ static struct smu_ad_sensor *smu_ads_create(struct device_node *node) !strcmp(l, "CPU T-Diode")) { ads->sens.ops = &smu_cputemp_ops; ads->sens.name = "cpu-temp"; - if (cpudiode == NULL) { - DBG("wf: cpudiode partition (%02x) not found\n", - SMU_SDB_CPUDIODE_ID); - goto fail; - } } else if (!strcmp(c, "current-sensor") && !strcmp(l, "CPU Current")) { ads->sens.ops = &smu_cpuamp_ops; ads->sens.name = "cpu-current"; - if (cpuvcp == NULL) { - DBG("wf: cpuvcp partition (%02x) not found\n", - SMU_SDB_CPUVCP_ID); - goto fail; - } } else if (!strcmp(c, "voltage-sensor") && !strcmp(l, "CPU Voltage")) { ads->sens.ops = &smu_cpuvolt_ops; ads->sens.name = "cpu-voltage"; - if (cpuvcp == NULL) { - DBG("wf: cpuvcp partition (%02x) not found\n", - SMU_SDB_CPUVCP_ID); - goto fail; - } } else if (!strcmp(c, "power-sensor") && !strcmp(l, "Slots Power")) { ads->sens.ops = &smu_slotspow_ops; @@ -380,22 +365,29 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps) return NULL; } -static void smu_fetch_param_partitions(void) +static int smu_fetch_param_partitions(void) { struct smu_sdbp_header *hdr; /* Get CPU voltage/current/power calibration data */ hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL); - if (hdr != NULL) { - cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; - /* Keep version around */ - cpuvcp_version = hdr->version; + if (hdr == NULL) { + DBG("wf: cpuvcp partition (%02x) not found\n", + SMU_SDB_CPUVCP_ID); + return -ENODEV; } + cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; + /* Keep version around */ + cpuvcp_version = hdr->version; /* Get CPU diode calibration data */ hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL); - if (hdr != NULL) - cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; + if (hdr == NULL) { + DBG("wf: cpudiode partition (%02x) not found\n", + SMU_SDB_CPUDIODE_ID); + return -ENODEV; + } + cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; /* Get slots power calibration data if any */ hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL); @@ -406,18 +398,23 @@ static void smu_fetch_param_partitions(void) hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL); if (hdr != NULL) debugswitches = (u8 *)&hdr[1]; + + return 0; } static int __init smu_sensors_init(void) { struct device_node *smu, *sensors, *s; struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL; + int rc; if (!smu_present()) return -ENODEV; /* Get parameters partitions */ - smu_fetch_param_partitions(); + rc = smu_fetch_param_partitions(); + if (rc) + return rc; smu = of_find_node_by_type(NULL, "smu"); if (smu == NULL) diff --git a/trunk/drivers/mtd/chips/Kconfig b/trunk/drivers/mtd/chips/Kconfig index effa0d7a73ac..205bb7083335 100644 --- a/trunk/drivers/mtd/chips/Kconfig +++ b/trunk/drivers/mtd/chips/Kconfig @@ -301,7 +301,7 @@ config MTD_JEDEC config MTD_XIP bool "XIP aware MTD support" - depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM + depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP default y if XIP_KERNEL help This allows MTD support to work with flash memory which is also diff --git a/trunk/include/asm-powerpc/smu.h b/trunk/include/asm-powerpc/smu.h index 2dc93632f210..82ce47607774 100644 --- a/trunk/include/asm-powerpc/smu.h +++ b/trunk/include/asm-powerpc/smu.h @@ -521,11 +521,6 @@ struct smu_sdbp_cpupiddata { extern struct smu_sdbp_header *smu_get_sdb_partition(int id, unsigned int *size); -/* Get "sdb" partition data from an SMU satellite */ -extern struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, - int id, unsigned int *size); - - #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/elevator.h b/trunk/include/linux/elevator.h index 18cf1f3e1184..23fe746a1d51 100644 --- a/trunk/include/linux/elevator.h +++ b/trunk/include/linux/elevator.h @@ -82,7 +82,6 @@ struct elevator_queue extern void elv_dispatch_sort(request_queue_t *, struct request *); extern void elv_add_request(request_queue_t *, struct request *, int, int); extern void __elv_add_request(request_queue_t *, struct request *, int, int); -extern void elv_insert(request_queue_t *, struct request *, int); extern int elv_merge(request_queue_t *, struct request **, struct bio *); extern void elv_merge_requests(request_queue_t *, struct request *, struct request *); diff --git a/trunk/mm/slob.c b/trunk/mm/slob.c index a1f42bdc0245..1c240c4b71d9 100644 --- a/trunk/mm/slob.c +++ b/trunk/mm/slob.c @@ -336,7 +336,7 @@ EXPORT_SYMBOL(slab_reclaim_pages); #ifdef CONFIG_SMP -void *__alloc_percpu(size_t size) +void *__alloc_percpu(size_t size, size_t align) { int i; struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL);