diff options
Diffstat (limited to 'drivers/macintosh')
26 files changed, 792 insertions, 153 deletions
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index d5d649f5ccd..a9e747c3979 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -162,7 +162,6 @@ config INPUT_ADBHID config MAC_EMUMOUSEBTN bool "Support for mouse button 2+3 emulation" - depends on INPUT_ADBHID help This provides generic support for emulating the 2nd and 3rd mouse button with keypresses. If you say Y here, the emulation is still @@ -186,7 +185,7 @@ config THERM_ADT746X depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64 help This driver provides some thermostat and fan control for the - iBook G4, and the ATI based aluminium PowerBooks, allowing slighlty + iBook G4, and the ATI based aluminium PowerBooks, allowing slightly better fan behaviour by default, and some manual control. config THERM_PM72 @@ -228,4 +227,11 @@ config ANSLCD tristate "Support for ANS LCD display" depends on ADB_CUDA && PPC_PMAC +config PMAC_RACKMETER + tristate "Support for Apple XServe front panel LEDs" + depends on PPC_PMAC + help + This driver procides some support to control the front panel + blue LEDs "vu-meter" of the XServer macs. + endmenu diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index b53d45f87b0..2dfc3f4eaf4 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -42,3 +42,4 @@ obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \ windfarm_smu_sensors.o \ windfarm_max6690_sensor.o \ windfarm_lm75_sensor.o windfarm_pid.o +obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c index d56d400b6aa..17ef5d3c01b 100644 --- a/drivers/macintosh/adb-iop.c +++ b/drivers/macintosh/adb-iop.c @@ -30,7 +30,7 @@ /*#define DEBUG_ADB_IOP*/ -extern void iop_ism_irq(int, void *, struct pt_regs *); +extern void iop_ism_irq(int, void *); static struct adb_request *current_req; static struct adb_request *last_req; @@ -78,7 +78,7 @@ static void adb_iop_end_req(struct adb_request *req, int state) * This will be called when a packet has been successfully sent. */ -static void adb_iop_complete(struct iop_msg *msg, struct pt_regs *regs) +static void adb_iop_complete(struct iop_msg *msg) { struct adb_request *req; uint flags; @@ -100,7 +100,7 @@ static void adb_iop_complete(struct iop_msg *msg, struct pt_regs *regs) * commands or autopoll packets) are received. */ -static void adb_iop_listen(struct iop_msg *msg, struct pt_regs *regs) +static void adb_iop_listen(struct iop_msg *msg) { struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; struct adb_request *req; @@ -143,7 +143,7 @@ static void adb_iop_listen(struct iop_msg *msg, struct pt_regs *regs) req->reply_len = amsg->count + 1; memcpy(req->reply, &amsg->cmd, req->reply_len); } else { - adb_input(&amsg->cmd, amsg->count + 1, regs, + adb_input(&amsg->cmd, amsg->count + 1, amsg->flags & ADB_IOP_AUTOPOLL); } memcpy(msg->reply, msg->message, IOP_MSG_LEN); @@ -266,7 +266,7 @@ int adb_iop_autopoll(int devs) void adb_iop_poll(void) { if (adb_iop_state == idle) adb_iop_start(); - iop_ism_irq(0, (void *) ADB_IOP, NULL); + iop_ism_irq(0, (void *) ADB_IOP); } int adb_iop_reset_bus(void) diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 360f93f6fcd..d43ea81d6df 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -103,7 +103,7 @@ static void adbdev_init(void); static int try_handler_change(int, int); static struct adb_handler { - void (*handler)(unsigned char *, int, struct pt_regs *, int); + void (*handler)(unsigned char *, int, int); int original_address; int handler_id; int busy; @@ -267,12 +267,12 @@ adb_probe_task(void *x) } static void -__adb_probe_task(void *data) +__adb_probe_task(struct work_struct *bullshit) { adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL); } -static DECLARE_WORK(adb_reset_work, __adb_probe_task, NULL); +static DECLARE_WORK(adb_reset_work, __adb_probe_task); int adb_reset_bus(void) @@ -522,7 +522,7 @@ bail: the handler_id id it doesn't match. */ int adb_register(int default_id, int handler_id, struct adb_ids *ids, - void (*handler)(unsigned char *, int, struct pt_regs *, int)) + void (*handler)(unsigned char *, int, int)) { int i; @@ -570,13 +570,13 @@ adb_unregister(int index) } void -adb_input(unsigned char *buf, int nb, struct pt_regs *regs, int autopoll) +adb_input(unsigned char *buf, int nb, int autopoll) { int i, id; static int dump_adb_input = 0; unsigned long flags; - void (*handler)(unsigned char *, int, struct pt_regs *, int); + void (*handler)(unsigned char *, int, int); /* We skip keystrokes and mouse moves when the sleep process * has been started. We stop autopoll, but this is another security @@ -597,7 +597,7 @@ adb_input(unsigned char *buf, int nb, struct pt_regs *regs, int autopoll) adb_handler[id].busy = 1; write_unlock_irqrestore(&adb_handler_lock, flags); if (handler != NULL) { - (*handler)(buf, nb, regs, autopoll); + (*handler)(buf, nb, autopoll); wmb(); adb_handler[id].busy = 0; } diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index efd51e01c06..1c7d6f221b5 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -1,5 +1,5 @@ /* - * drivers/input/adbhid.c + * drivers/macintosh/adbhid.c * * ADB HID driver for Power Macintosh computers. * @@ -222,7 +222,7 @@ static struct adbhid *adbhid[16]; static void adbhid_probe(void); -static void adbhid_input_keycode(int, int, int, struct pt_regs *); +static void adbhid_input_keycode(int, int, int); static void init_trackpad(int id); static void init_trackball(int id); @@ -253,7 +253,7 @@ static struct adb_ids buttons_ids; #define ADBMOUSE_MACALLY2 9 /* MacAlly 2-button mouse */ static void -adbhid_keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apoll) +adbhid_keyboard_input(unsigned char *data, int nb, int apoll) { int id = (data[0] >> 4) & 0x0f; @@ -266,13 +266,13 @@ adbhid_keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apo /* first check this is from register 0 */ if (nb != 3 || (data[0] & 3) != KEYB_KEYREG) return; /* ignore it */ - adbhid_input_keycode(id, data[1], 0, regs); + adbhid_input_keycode(id, data[1], 0); if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f))) - adbhid_input_keycode(id, data[2], 0, regs); + adbhid_input_keycode(id, data[2], 0); } static void -adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs) +adbhid_input_keycode(int id, int keycode, int repeat) { struct adbhid *ahid = adbhid[id]; int up_flag; @@ -282,7 +282,6 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs) switch (keycode) { case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */ - input_regs(ahid->input, regs); input_report_key(ahid->input, KEY_CAPSLOCK, 1); input_report_key(ahid->input, KEY_CAPSLOCK, 0); input_sync(ahid->input); @@ -338,7 +337,6 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs) } if (adbhid[id]->keycode[keycode]) { - input_regs(adbhid[id]->input, regs); input_report_key(adbhid[id]->input, adbhid[id]->keycode[keycode], !up_flag); input_sync(adbhid[id]->input); @@ -349,7 +347,7 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs) } static void -adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) +adbhid_mouse_input(unsigned char *data, int nb, int autopoll) { int id = (data[0] >> 4) & 0x0f; @@ -432,8 +430,6 @@ adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopo break; } - input_regs(adbhid[id]->input, regs); - input_report_key(adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1)); input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1)); @@ -449,7 +445,7 @@ adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopo } static void -adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) +adbhid_buttons_input(unsigned char *data, int nb, int autopoll) { int id = (data[0] >> 4) & 0x0f; @@ -458,8 +454,6 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto return; } - input_regs(adbhid[id]->input, regs); - switch (adbhid[id]->original_handler_id) { default: case 0x02: /* Adjustable keyboard button device */ @@ -695,7 +689,6 @@ adbhid_input_register(int id, int default_id, int original_handler_id, if (!hid || !input_dev) { err = -ENOMEM; goto fail; - } sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id); @@ -813,7 +806,9 @@ adbhid_input_register(int id, int default_id, int original_handler_id, input_dev->keycode = hid->keycode; - input_register_device(input_dev); + err = input_register_device(input_dev); + if (err) + goto fail; if (default_id == ADB_KEYBOARD) { /* HACK WARNING!! This should go away as soon there is an utility @@ -826,7 +821,10 @@ adbhid_input_register(int id, int default_id, int original_handler_id, return 0; fail: input_free_device(input_dev); - kfree(hid); + if (hid) { + kfree(hid->keycode); + kfree(hid); + } adbhid[id] = NULL; return err; } diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c index 1293876a2eb..8862a83b8d8 100644 --- a/drivers/macintosh/apm_emu.c +++ b/drivers/macintosh/apm_emu.c @@ -529,7 +529,8 @@ static int __init apm_emu_init(void) if (apm_proc) apm_proc->owner = THIS_MODULE; - misc_register(&apm_device); + if (misc_register(&apm_device) != 0) + printk(KERN_INFO "Could not create misc. device for apm\n"); pmu_register_sleep_notifier(&apm_sleep_notifier); diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 6b129eef798..ee6b4ca6913 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -106,6 +106,8 @@ EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons); static int emumousebtn_input_register(void) { + int ret; + emumousebtn = input_allocate_device(); if (!emumousebtn) return -ENOMEM; @@ -120,9 +122,11 @@ static int emumousebtn_input_register(void) emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y); - input_register_device(emumousebtn); + ret = input_register_device(emumousebtn); + if (ret) + input_free_device(emumousebtn); - return 0; + return ret; } int __init mac_hid_init(void) diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c index 4b08852c35e..797cef72258 100644 --- a/drivers/macintosh/macio-adb.c +++ b/drivers/macintosh/macio-adb.c @@ -64,7 +64,7 @@ static DEFINE_SPINLOCK(macio_lock); static int macio_probe(void); static int macio_init(void); -static irqreturn_t macio_adb_interrupt(int irq, void *arg, struct pt_regs *regs); +static irqreturn_t macio_adb_interrupt(int irq, void *arg); static int macio_send_request(struct adb_request *req, int sync); static int macio_adb_autopoll(int devs); static void macio_adb_poll(void); @@ -189,8 +189,7 @@ static int macio_send_request(struct adb_request *req, int sync) return 0; } -static irqreturn_t macio_adb_interrupt(int irq, void *arg, - struct pt_regs *regs) +static irqreturn_t macio_adb_interrupt(int irq, void *arg) { int i, n, err; struct adb_request *req = NULL; @@ -260,7 +259,7 @@ static irqreturn_t macio_adb_interrupt(int irq, void *arg, (*done)(req); } if (ibuf_len) - adb_input(ibuf, ibuf_len, regs, autopoll); + adb_input(ibuf, ibuf_len, autopoll); return IRQ_RETVAL(handled); } @@ -271,6 +270,6 @@ static void macio_adb_poll(void) local_irq_save(flags); if (in_8(&adb->intr.r) != 0) - macio_adb_interrupt(0, NULL, NULL); + macio_adb_interrupt(0, NULL); local_irq_restore(flags); } diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c new file mode 100644 index 00000000000..5ed41fe84e5 --- /dev/null +++ b/drivers/macintosh/rack-meter.c @@ -0,0 +1,616 @@ +/* + * RackMac vu-meter driver + * + * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. + * <benh@kernel.crashing.org> + * + * Released under the term of the GNU GPL v2. + * + * Support the CPU-meter LEDs of the Xserve G5 + * + * TODO: Implement PWM to do variable intensity and provide userland + * interface for fun. Also, the CPU-meter could be made nicer by being + * a bit less "immediate" but giving instead a more average load over + * time. Patches welcome :-) + * + */ +#undef DEBUG + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/dma-mapping.h> +#include <linux/kernel_stat.h> + +#include <asm/io.h> +#include <asm/prom.h> +#include <asm/machdep.h> +#include <asm/pmac_feature.h> +#include <asm/dbdma.h> +#include <asm/dbdma.h> +#include <asm/macio.h> +#include <asm/keylargo.h> + +/* Number of samples in a sample buffer */ +#define SAMPLE_COUNT 256 + +/* CPU meter sampling rate in ms */ +#define CPU_SAMPLING_RATE 250 + +struct rackmeter_dma { + struct dbdma_cmd cmd[4] ____cacheline_aligned; + u32 mark ____cacheline_aligned; + u32 buf1[SAMPLE_COUNT] ____cacheline_aligned; + u32 buf2[SAMPLE_COUNT] ____cacheline_aligned; +} ____cacheline_aligned; + +struct rackmeter_cpu { + struct delayed_work sniffer; + struct rackmeter *rm; + cputime64_t prev_wall; + cputime64_t prev_idle; + int zero; +} ____cacheline_aligned; + +struct rackmeter { + struct macio_dev *mdev; + unsigned int irq; + struct device_node *i2s; + u8 *ubuf; + struct dbdma_regs __iomem *dma_regs; + void __iomem *i2s_regs; + dma_addr_t dma_buf_p; + struct rackmeter_dma *dma_buf_v; + int stale_irq; + struct rackmeter_cpu cpu[2]; + int paused; + struct mutex sem; +}; + +/* To be set as a tunable */ +static int rackmeter_ignore_nice; + +/* This GPIO is whacked by the OS X driver when initializing */ +#define RACKMETER_MAGIC_GPIO 0x78 + +/* This is copied from cpufreq_ondemand, maybe we should put it in + * a common header somewhere + */ +static inline cputime64_t get_cpu_idle_time(unsigned int cpu) +{ + cputime64_t retval; + + retval = cputime64_add(kstat_cpu(cpu).cpustat.idle, + kstat_cpu(cpu).cpustat.iowait); + + if (rackmeter_ignore_nice) + retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice); + + return retval; +} + +static void rackmeter_setup_i2s(struct rackmeter *rm) +{ + struct macio_chip *macio = rm->mdev->bus->chip; + + /* First whack magic GPIO */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, RACKMETER_MAGIC_GPIO, 5); + + + /* Call feature code to enable the sound channel and the proper + * clock sources + */ + pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, rm->i2s, 0, 1); + + /* Power i2s and stop i2s clock. We whack MacIO FCRs directly for now. + * This is a bit racy, thus we should add new platform functions to + * handle that. snd-aoa needs that too + */ + MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE); + MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT); + (void)MACIO_IN32(KEYLARGO_FCR1); + udelay(10); + + /* Then setup i2s. For now, we use the same magic value that + * the OS X driver seems to use. We might want to play around + * with the clock divisors later + */ + out_le32(rm->i2s_regs + 0x10, 0x01fa0000); + (void)in_le32(rm->i2s_regs + 0x10); + udelay(10); + + /* Fully restart i2s*/ + MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE | + KL1_I2S0_CLK_ENABLE_BIT); + (void)MACIO_IN32(KEYLARGO_FCR1); + udelay(10); +} + +static void rackmeter_set_default_pattern(struct rackmeter *rm) +{ + int i; + + for (i = 0; i < 16; i++) { + if (i < 8) + rm->ubuf[i] = (i & 1) * 255; + else + rm->ubuf[i] = ((~i) & 1) * 255; + } +} + +static void rackmeter_do_pause(struct rackmeter *rm, int pause) +{ + struct rackmeter_dma *rdma = rm->dma_buf_v; + + pr_debug("rackmeter: %s\n", pause ? "paused" : "started"); + + rm->paused = pause; + if (pause) { + DBDMA_DO_STOP(rm->dma_regs); + return; + } + memset(rdma->buf1, 0, SAMPLE_COUNT & sizeof(u32)); + memset(rdma->buf2, 0, SAMPLE_COUNT & sizeof(u32)); + + rm->dma_buf_v->mark = 0; + + mb(); + out_le32(&rm->dma_regs->cmdptr_hi, 0); + out_le32(&rm->dma_regs->cmdptr, rm->dma_buf_p); + out_le32(&rm->dma_regs->control, (RUN << 16) | RUN); +} + +static void rackmeter_setup_dbdma(struct rackmeter *rm) +{ + struct rackmeter_dma *db = rm->dma_buf_v; + struct dbdma_cmd *cmd = db->cmd; + + /* Make sure dbdma is reset */ + DBDMA_DO_RESET(rm->dma_regs); + + pr_debug("rackmeter: mark offset=0x%lx\n", + offsetof(struct rackmeter_dma, mark)); + pr_debug("rackmeter: buf1 offset=0x%lx\n", + offsetof(struct rackmeter_dma, buf1)); + pr_debug("rackmeter: buf2 offset=0x%lx\n", + offsetof(struct rackmeter_dma, buf2)); + + /* Prepare 4 dbdma commands for the 2 buffers */ + memset(cmd, 0, 4 * sizeof(struct dbdma_cmd)); + st_le16(&cmd->req_count, 4); + st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM); + st_le32(&cmd->phy_addr, rm->dma_buf_p + + offsetof(struct rackmeter_dma, mark)); + st_le32(&cmd->cmd_dep, 0x02000000); + cmd++; + + st_le16(&cmd->req_count, SAMPLE_COUNT * 4); + st_le16(&cmd->command, OUTPUT_MORE); + st_le32(&cmd->phy_addr, rm->dma_buf_p + + offsetof(struct rackmeter_dma, buf1)); + cmd++; + + st_le16(&cmd->req_count, 4); + st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM); + st_le32(&cmd->phy_addr, rm->dma_buf_p + + offsetof(struct rackmeter_dma, mark)); + st_le32(&cmd->cmd_dep, 0x01000000); + cmd++; + + st_le16(&cmd->req_count, SAMPLE_COUNT * 4); + st_le16(&cmd->command, OUTPUT_MORE | BR_ALWAYS); + st_le32(&cmd->phy_addr, rm->dma_buf_p + + offsetof(struct rackmeter_dma, buf2)); + st_le32(&cmd->cmd_dep, rm->dma_buf_p); + + rackmeter_do_pause(rm, 0); +} + +static void rackmeter_do_timer(struct work_struct *work) +{ + struct rackmeter_cpu *rcpu = + container_of(work, struct rackmeter_cpu, sniffer.work); + struct rackmeter *rm = rcpu->rm; + unsigned int cpu = smp_processor_id(); + cputime64_t cur_jiffies, total_idle_ticks; + unsigned int total_ticks, idle_ticks; + int i, offset, load, cumm, pause; + + cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); + total_ticks = (unsigned int)cputime64_sub(cur_jiffies, + rcpu->prev_wall); + rcpu->prev_wall = cur_jiffies; + + total_idle_ticks = get_cpu_idle_time(cpu); + idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks, + rcpu->prev_idle); + rcpu->prev_idle = total_idle_ticks; + + /* We do a very dumb calculation to update the LEDs for now, + * we'll do better once we have actual PWM implemented + */ + load = (9 * (total_ticks - idle_ticks)) / total_ticks; + + offset = cpu << 3; + cumm = 0; + for (i = 0; i < 8; i++) { + u8 ub = (load > i) ? 0xff : 0; + rm->ubuf[i + offset] = ub; + cumm |= ub; + } + rcpu->zero = (cumm == 0); + + /* Now check if LEDs are all 0, we can stop DMA */ + pause = (rm->cpu[0].zero && rm->cpu[1].zero); + if (pause != rm->paused) { + mutex_lock(&rm->sem); + pause = (rm->cpu[0].zero && rm->cpu[1].zero); + rackmeter_do_pause(rm, pause); + mutex_unlock(&rm->sem); + } + schedule_delayed_work_on(cpu, &rcpu->sniffer, + msecs_to_jiffies(CPU_SAMPLING_RATE)); +} + +static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm) +{ + unsigned int cpu; + + /* This driver works only with 1 or 2 CPUs numbered 0 and 1, + * but that's really all we have on Apple Xserve. It doesn't + * play very nice with CPU hotplug neither but we don't do that + * on those machines yet + */ + + rm->cpu[0].rm = rm; + INIT_DELAYED_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer); + rm->cpu[1].rm = rm; + INIT_DELAYED_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer); + + for_each_online_cpu(cpu) { + struct rackmeter_cpu *rcpu; + + if (cpu > 1) + continue; + rcpu = &rm->cpu[cpu];; + rcpu->prev_idle = get_cpu_idle_time(cpu); + rcpu->prev_wall = jiffies64_to_cputime64(get_jiffies_64()); + schedule_delayed_work_on(cpu, &rm->cpu[cpu].sniffer, + msecs_to_jiffies(CPU_SAMPLING_RATE)); + } +} + +static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm) +{ + cancel_rearming_delayed_work(&rm->cpu[0].sniffer); + cancel_rearming_delayed_work(&rm->cpu[1].sniffer); +} + +static int rackmeter_setup(struct rackmeter *rm) +{ + pr_debug("rackmeter: setting up i2s..\n"); + rackmeter_setup_i2s(rm); + + pr_debug("rackmeter: setting up default pattern..\n"); + rackmeter_set_default_pattern(rm); + + pr_debug("rackmeter: setting up dbdma..\n"); + rackmeter_setup_dbdma(rm); + + pr_debug("rackmeter: start CPU measurements..\n"); + rackmeter_init_cpu_sniffer(rm); + + printk(KERN_INFO "RackMeter initialized\n"); + + return 0; +} + +/* XXX FIXME: No PWM yet, this is 0/1 */ +static u32 rackmeter_calc_sample(struct rackmeter *rm, unsigned int index) +{ + int led; + u32 sample = 0; + + for (led = 0; led < 16; led++) { + sample >>= 1; + sample |= ((rm->ubuf[led] >= 0x80) << 15); + } + return (sample << 17) | (sample >> 15); +} + +static irqreturn_t rackmeter_irq(int irq, void *arg) +{ + struct rackmeter *rm = arg; + struct rackmeter_dma *db = rm->dma_buf_v; + unsigned int mark, i; + u32 *buf; + + /* Flush PCI buffers with an MMIO read. Maybe we could actually + * check the status one day ... in case things go wrong, though + * this never happened to me + */ + (void)in_le32(&rm->dma_regs->status); + + /* Make sure the CPU gets us in order */ + rmb(); + + /* Read mark */ + mark = db->mark; + if (mark != 1 && mark != 2) { + printk(KERN_WARNING "rackmeter: Incorrect DMA mark 0x%08x\n", + mark); + /* We allow for 3 errors like that (stale DBDMA irqs) */ + if (++rm->stale_irq > 3) { + printk(KERN_ERR "rackmeter: Too many errors," + " stopping DMA\n"); + DBDMA_DO_RESET(rm->dma_regs); + } + return IRQ_HANDLED; + } + + /* Next buffer we need to fill is mark value */ + buf = mark == 1 ? db->buf1 : db->buf2; + + /* Fill it now. This routine converts the 8 bits depth sample array + * into the PWM bitmap for each LED. + */ + for (i = 0; i < SAMPLE_COUNT; i++) + buf[i] = rackmeter_calc_sample(rm, i); + + + return IRQ_HANDLED; +} + +static int __devinit rackmeter_probe(struct macio_dev* mdev, + const struct of_device_id *match) +{ + struct device_node *i2s = NULL, *np = NULL; + struct rackmeter *rm = NULL; + struct resource ri2s, rdma; + int rc = -ENODEV; + + pr_debug("rackmeter_probe()\n"); + + /* Get i2s-a node */ + while ((i2s = of_get_next_child(mdev->ofdev.node, i2s)) != NULL) + if (strcmp(i2s->name, "i2s-a") == 0) + break; + if (i2s == NULL) { + pr_debug(" i2s-a child not found\n"); + goto bail; + } + /* Get lightshow or virtual sound */ + while ((np = of_get_next_child(i2s, np)) != NULL) { + if (strcmp(np->name, "lightshow") == 0) + break; + if ((strcmp(np->name, "sound") == 0) && + get_property(np, "virtual", NULL) != NULL) + break; + } + if (np == NULL) { + pr_debug(" lightshow or sound+virtual child not found\n"); + goto bail; + } + + /* Create and initialize our instance data */ + rm = kzalloc(sizeof(struct rackmeter), GFP_KERNEL); + if (rm == NULL) { + printk(KERN_ERR "rackmeter: failed to allocate memory !\n"); + rc = -ENOMEM; + goto bail_release; + } + rm->mdev = mdev; + rm->i2s = i2s; + mutex_init(&rm->sem); + dev_set_drvdata(&mdev->ofdev.dev, rm); + /* Check resources availability. We need at least resource 0 and 1 */ +#if 0 /* Use that when i2s-a is finally an mdev per-se */ + if (macio_resource_count(mdev) < 2 || macio_irq_count(mdev) < 2) { + printk(KERN_ERR + "rackmeter: found match but lacks resources: %s" + " (%d resources, %d interrupts)\n", + mdev->ofdev.node->full_name); + rc = -ENXIO; + goto bail_free; + } + if (macio_request_resources(mdev, "rackmeter")) { + printk(KERN_ERR + "rackmeter: failed to request resources: %s\n", + mdev->ofdev.node->full_name); + rc = -EBUSY; + goto bail_free; + } + rm->irq = macio_irq(mdev, 1); +#else + rm->irq = irq_of_parse_and_map(i2s, 1); + if (rm->irq == NO_IRQ || + of_address_to_resource(i2s, 0, &ri2s) || + of_address_to_resource(i2s, 1, &rdma)) { + printk(KERN_ERR + "rackmeter: found match but lacks resources: %s", + mdev->ofdev.node->full_name); + rc = -ENXIO; + goto bail_free; + } +#endif + + pr_debug(" i2s @0x%08x\n", (unsigned int)ri2s.start); + pr_debug(" dma @0x%08x\n", (unsigned int)rdma.start); + pr_debug(" irq %d\n", rm->irq); + + rm->ubuf = (u8 *)__get_free_page(GFP_KERNEL); + if (rm->ubuf == NULL) { + printk(KERN_ERR + "rackmeter: failed to allocate samples page !\n"); + rc = -ENOMEM; + goto bail_release; + } + + rm->dma_buf_v = dma_alloc_coherent(&macio_get_pci_dev(mdev)->dev, + sizeof(struct rackmeter_dma), + &rm->dma_buf_p, GFP_KERNEL); + if (rm->dma_buf_v == NULL) { + printk(KERN_ERR + "rackmeter: failed to allocate dma buffer !\n"); + rc = -ENOMEM; + goto bail_free_samples; + } +#if 0 + rm->i2s_regs = ioremap(macio_resource_start(mdev, 0), 0x1000); +#else + rm->i2s_regs = ioremap(ri2s.start, 0x1000); +#endif + if (rm->i2s_regs == NULL) { + printk(KERN_ERR + "rackmeter: failed to map i2s registers !\n"); + rc = -ENXIO; + goto bail_free_dma; + } +#if 0 + rm->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x100); +#else + rm->dma_regs = ioremap(rdma.start, 0x100); +#endif + if (rm->dma_regs == NULL) { + printk(KERN_ERR + "rackmeter: failed to map dma registers !\n"); + rc = -ENXIO; + goto bail_unmap_i2s; + } + + rc = rackmeter_setup(rm); + if (rc) { + printk(KERN_ERR + "rackmeter: failed to initialize !\n"); + rc = -ENXIO; + goto bail_unmap_dma; + } + + rc = request_irq(rm->irq, rackmeter_irq, 0, "rackmeter", rm); + if (rc != 0) { + printk(KERN_ERR + "rackmeter: failed to request interrupt !\n"); + goto bail_stop_dma; + } + of_node_put(np); + return 0; + + bail_stop_dma: + DBDMA_DO_RESET(rm->dma_regs); + bail_unmap_dma: + iounmap(rm->dma_regs); + bail_unmap_i2s: + iounmap(rm->i2s_regs); + bail_free_dma: + dma_free_coherent(&macio_get_pci_dev(mdev)->dev, + sizeof(struct rackmeter_dma), + rm->dma_buf_v, rm->dma_buf_p); + bail_free_samples: + free_page((unsigned long)rm->ubuf); + bail_release: +#if 0 + macio_release_resources(mdev); +#endif + bail_free: + kfree(rm); + bail: + of_node_put(i2s); + of_node_put(np); + dev_set_drvdata(&mdev->ofdev.dev, NULL); + return rc; +} + +static int __devexit rackmeter_remove(struct macio_dev* mdev) +{ + struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev); + + /* Stop CPU sniffer timer & work queues */ + rackmeter_stop_cpu_sniffer(rm); + + /* Clear reference to private data */ + dev_set_drvdata(&mdev->ofdev.dev, NULL); + + /* Stop/reset dbdma */ + DBDMA_DO_RESET(rm->dma_regs); + + /* Release the IRQ */ + free_irq(rm->irq, rm); + + /* Unmap registers */ + iounmap(rm->dma_regs); + iounmap(rm->i2s_regs); + + /* Free DMA */ + dma_free_coherent(&macio_get_pci_dev(mdev)->dev, + sizeof(struct rackmeter_dma), + rm->dma_buf_v, rm->dma_buf_p); + + /* Free samples */ + free_page((unsigned long)rm->ubuf); + +#if 0 + /* Release resources */ + macio_release_resources(mdev); +#endif + + /* Get rid of me */ + kfree(rm); + + return 0; +} + +static int rackmeter_shutdown(struct macio_dev* mdev) +{ + struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev); + + if (rm == NULL) + return -ENODEV; + + /* Stop CPU sniffer timer & work queues */ + rackmeter_stop_cpu_sniffer(rm); + + /* Stop/reset dbdma */ + DBDMA_DO_RESET(rm->dma_regs); + + return 0; +} + +static struct of_device_id rackmeter_match[] = { + { .name = "i2s" }, + { } +}; + +static struct macio_driver rackmeter_drv = { + .name = "rackmeter", + .owner = THIS_MODULE, + .match_table = rackmeter_match, + .probe = rackmeter_probe, + .remove = rackmeter_remove, + .shutdown = rackmeter_shutdown, +}; + + +static int __init rackmeter_init(void) +{ + pr_debug("rackmeter_init()\n"); + + return macio_register_driver(&rackmeter_drv); +} + +static void __exit rackmeter_exit(void) +{ + pr_debug("rackmeter_exit()\n"); + + macio_unregister_driver(&rackmeter_drv); +} + +module_init(rackmeter_init); +module_exit(rackmeter_exit); + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); +MODULE_DESCRIPTION("RackMeter: Support vu-meter on XServe front panel"); diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 090e40fc501..6dde27ab79a 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -46,6 +46,7 @@ #include <asm/abs_addr.h> #include <asm/uaccess.h> #include <asm/of_device.h> +#include <asm/of_platform.h> #define VERSION "0.7" #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." @@ -145,7 +146,7 @@ static void smu_start_cmd(void) } -static irqreturn_t smu_db_intr(int irq, void *arg, struct pt_regs *regs) +static irqreturn_t smu_db_intr(int irq, void *arg) { unsigned long flags; struct smu_cmd *cmd; @@ -224,7 +225,7 @@ static irqreturn_t smu_db_intr(int irq, void *arg, struct pt_regs *regs) } -static irqreturn_t smu_msg_intr(int irq, void *arg, struct pt_regs *regs) +static irqreturn_t smu_msg_intr(int irq, void *arg) { /* I don't quite know what to do with this one, we seem to never * receive it, so I suspect we have to arm it someway in the SMU @@ -309,7 +310,7 @@ void smu_poll(void) gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell); if ((gpio & 7) == 7) - smu_db_intr(smu->db_irq, smu, NULL); + smu_db_intr(smu->db_irq, smu); } EXPORT_SYMBOL(smu_poll); @@ -600,7 +601,7 @@ core_initcall(smu_late_init); * sysfs visibility */ -static void smu_expose_childs(void *unused) +static void smu_expose_childs(struct work_struct *unused) { struct device_node *np; @@ -610,7 +611,7 @@ static void smu_expose_childs(void *unused) &smu->of_dev->dev); } -static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); +static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs); static int smu_platform_probe(struct of_device* dev, const struct of_device_id *match) @@ -653,7 +654,7 @@ static int __init smu_init_sysfs(void) * I'm a bit too far from figuring out how that works with those * new chipsets, but that will come back and bite us */ - of_register_driver(&smu_of_platform_driver); + of_register_platform_driver(&smu_of_platform_driver); return 0; } @@ -870,7 +871,7 @@ int smu_queue_i2c(struct smu_i2c_cmd *cmd) static int smu_read_datablock(u8 *dest, unsigned int addr, unsigned int len) { - DECLARE_COMPLETION(comp); + DECLARE_COMPLETION_ONSTACK(comp); unsigned int chunk; struct smu_cmd cmd; int rc; @@ -917,7 +918,7 @@ static int smu_read_datablock(u8 *dest, unsigned int addr, unsigned int len) static struct smu_sdbp_header *smu_create_sdb_partition(int id) { - DECLARE_COMPLETION(comp); + DECLARE_COMPLETION_ONSTACK(comp); struct smu_simple_cmd cmd; unsigned int addr, len, tlen; struct smu_sdbp_header *hdr; diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index a0f30d0853e..3d3bf1643e7 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -24,13 +24,14 @@ #include <linux/suspend.h> #include <linux/kthread.h> #include <linux/moduleparam.h> +#include <linux/freezer.h> #include <asm/prom.h> #include <asm/machdep.h> #include <asm/io.h> #include <asm/system.h> #include <asm/sections.h> -#include <asm/of_device.h> +#include <asm/of_platform.h> #undef DEBUG diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index d00c0c37a12..2e4ad44a863 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -129,6 +129,7 @@ #include <asm/sections.h> #include <asm/of_device.h> #include <asm/macio.h> +#include <asm/of_platform.h> #include "therm_pm72.h" @@ -2236,14 +2237,14 @@ static int __init therm_pm72_init(void) return -ENODEV; } - of_register_driver(&fcu_of_platform_driver); + of_register_platform_driver(&fcu_of_platform_driver); return 0; } static void __exit therm_pm72_exit(void) { - of_unregister_driver(&fcu_of_platform_driver); + of_unregister_platform_driver(&fcu_of_platform_driver); if (of_dev) of_device_unregister(of_dev); diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 738faab1b22..a1d3a987cb3 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -36,12 +36,13 @@ #include <linux/i2c.h> #include <linux/slab.h> #include <linux/init.h> + #include <asm/prom.h> #include <asm/machdep.h> #include <asm/io.h> #include <asm/system.h> #include <asm/sections.h> -#include <asm/of_device.h> +#include <asm/of_platform.h> #include <asm/macio.h> #define LOG_TEMP 0 /* continously log temperature */ @@ -511,14 +512,14 @@ g4fan_init( void ) return -ENODEV; } - of_register_driver( &therm_of_driver ); + of_register_platform_driver( &therm_of_driver ); return 0; } static void __exit g4fan_exit( void ) { - of_unregister_driver( &therm_of_driver ); + of_unregister_platform_driver( &therm_of_driver ); if( x.of_dev ) of_device_unregister( x.of_dev ); diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index 7512d1c1520..df66291b132 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c @@ -98,8 +98,8 @@ static int cuda_reset_adb_bus(void); static int cuda_init_via(void); static void cuda_start(void); -static irqreturn_t cuda_interrupt(int irq, void *arg, struct pt_regs *regs); -static void cuda_input(unsigned char *buf, int nb, struct pt_regs *regs); +static irqreturn_t cuda_interrupt(int irq, void *arg); +static void cuda_input(unsigned char *buf, int nb); void cuda_poll(void); static int cuda_write(struct adb_request *req); @@ -437,12 +437,12 @@ cuda_poll(void) * disable_irq(), would that work on m68k ? --BenH */ local_irq_save(flags); - cuda_interrupt(0, NULL, NULL); + cuda_interrupt(0, NULL); local_irq_restore(flags); } static irqreturn_t -cuda_interrupt(int irq, void *arg, struct pt_regs *regs) +cuda_interrupt(int irq, void *arg) { int status; struct adb_request *req = NULL; @@ -594,12 +594,12 @@ cuda_interrupt(int irq, void *arg, struct pt_regs *regs) (*done)(req); } if (ibuf_len) - cuda_input(ibuf, ibuf_len, regs); + cuda_input(ibuf, ibuf_len); return IRQ_HANDLED; } static void -cuda_input(unsigned char *buf, int nb, struct pt_regs *regs) +cuda_input(unsigned char *buf, int nb) { int i; @@ -615,7 +615,7 @@ cuda_input(unsigned char *buf, int nb, struct pt_regs *regs) } #endif /* CONFIG_XMON */ #ifdef CONFIG_ADB - adb_input(buf+2, nb-2, regs, buf[1] & 0x40); + adb_input(buf+2, nb-2, buf[1] & 0x40); #endif /* CONFIG_ADB */ break; diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c index 2a2ffe06016..5d88d5b0ad9 100644 --- a/drivers/macintosh/via-macii.c +++ b/drivers/macintosh/via-macii.c @@ -77,7 +77,7 @@ static volatile unsigned char *via; static int macii_init_via(void); static void macii_start(void); -static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs); +static irqreturn_t macii_interrupt(int irq, void *arg); static void macii_retransmit(int); static void macii_queue_poll(void); @@ -295,7 +295,7 @@ static void macii_poll(void) unsigned long flags; local_irq_save(flags); - if (via[IFR] & SR_INT) macii_interrupt(0, NULL, NULL); + if (via[IFR] & SR_INT) macii_interrupt(0, NULL); local_irq_restore(flags); } @@ -410,7 +410,7 @@ static void macii_start(void) * Note: As of 21/10/97, the MacII ADB part works including timeout detection * and retransmit (Talk to the last active device). */ -static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs) +static irqreturn_t macii_interrupt(int irq, void *arg) { int x, adbdir; unsigned long flags; @@ -602,8 +602,7 @@ static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs) current_req = req->next; if (req->done) (*req->done)(req); } else { - adb_input(reply_buf, reply_ptr - reply_buf, - regs, 0); + adb_input(reply_buf, reply_ptr - reply_buf, 0); } /* diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c index 0129fcc3b18..1f0aa5dc9aa 100644 --- a/drivers/macintosh/via-maciisi.c +++ b/drivers/macintosh/via-maciisi.c @@ -84,8 +84,8 @@ static int maciisi_init(void); static int maciisi_send_request(struct adb_request* req, int sync); static void maciisi_sync(struct adb_request *req); static int maciisi_write(struct adb_request* req); -static irqreturn_t maciisi_interrupt(int irq, void* arg, struct pt_regs* regs); -static void maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs); +static irqreturn_t maciisi_interrupt(int irq, void* arg); +static void maciisi_input(unsigned char *buf, int nb); static int maciisi_init_via(void); static void maciisi_poll(void); static int maciisi_start(void); @@ -421,7 +421,7 @@ maciisi_poll(void) local_irq_save(flags); if (via[IFR] & SR_INT) { - maciisi_interrupt(0, NULL, NULL); + maciisi_interrupt(0, NULL); } else /* avoid calling this function too quickly in a loop */ udelay(ADB_DELAY); @@ -433,7 +433,7 @@ maciisi_poll(void) register is either full or empty. In practice, I have no idea what it means :( */ static irqreturn_t -maciisi_interrupt(int irq, void* arg, struct pt_regs* regs) +maciisi_interrupt(int irq, void* arg) { int status; struct adb_request *req; @@ -612,7 +612,7 @@ maciisi_interrupt(int irq, void* arg, struct pt_regs* regs) /* Obviously, we got it */ reading_reply = 0; } else { - maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf, regs); + maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf); } maciisi_state = idle; status = via[B] & (TIP|TREQ); @@ -657,7 +657,7 @@ maciisi_interrupt(int irq, void* arg, struct pt_regs* regs) } static void -maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs) +maciisi_input(unsigned char *buf, int nb) { #ifdef DEBUG_MACIISI_ADB int i; @@ -665,7 +665,7 @@ maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs) switch (buf[0]) { case ADB_PACKET: - adb_input(buf+2, nb-2, regs, buf[1] & 0x40); + adb_input(buf+2, nb-2, buf[1] & 0x40); break; default: #ifdef DEBUG_MACIISI_ADB diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index a82f313d9dc..6c29fe727c0 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c @@ -16,7 +16,7 @@ #define MAX_PMU_LEVEL 0xFF static struct backlight_properties pmu_backlight_data; -static spinlock_t pmu_backlight_lock; +static DEFINE_SPINLOCK(pmu_backlight_lock); static int sleeping; static u8 bl_curve[FB_BACKLIGHT_LEVELS]; diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index dda03985dcf..c8558d4ed50 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -42,7 +42,7 @@ #include <linux/interrupt.h> #include <linux/device.h> #include <linux/sysdev.h> -#include <linux/suspend.h> +#include <linux/freezer.h> #include <linux/syscalls.h> #include <linux/cpu.h> #include <asm/prom.h> @@ -191,8 +191,8 @@ static int pmu_adb_reset_bus(void); static int init_pmu(void); static void pmu_start(void); -static irqreturn_t via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs); -static irqreturn_t gpio1_interrupt(int irq, void *arg, struct pt_regs *regs); +static irqreturn_t via_pmu_interrupt(int irq, void *arg); +static irqreturn_t gpio1_interrupt(int irq, void *arg); static int proc_get_info(char *page, char **start, off_t off, int count, int *eof, void *data); static int proc_get_irqstats(char *page, char **start, off_t off, @@ -336,8 +336,10 @@ int __init find_via_pmu(void) if (gaddr != OF_BAD_ADDR) gpio_reg = ioremap(gaddr, 0x10); } - if (gpio_reg == NULL) + if (gpio_reg == NULL) { printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n"); + goto fail_gpio; + } } else pmu_kind = PMU_UNKNOWN; @@ -365,6 +367,9 @@ int __init find_via_pmu(void) return 1; fail: of_node_put(vias); + iounmap(gpio_reg); + gpio_reg = NULL; + fail_gpio: vias = NULL; return 0; } @@ -550,7 +555,7 @@ init_pmu(void) } if (pmu_state == idle) adb_int_pending = 1; - via_pmu_interrupt(0, NULL, NULL); + via_pmu_interrupt(0, NULL); udelay(10); } @@ -1210,7 +1215,7 @@ pmu_poll(void) return; if (disable_poll) return; - via_pmu_interrupt(0, NULL, NULL); + via_pmu_interrupt(0, NULL); } void @@ -1223,7 +1228,7 @@ pmu_poll_adb(void) /* Kicks ADB read when PMU is suspended */ adb_int_pending = 1; do { - via_pmu_interrupt(0, NULL, NULL); + via_pmu_interrupt(0, NULL); } while (pmu_suspended && (adb_int_pending || pmu_state != idle || req_awaiting_reply)); } @@ -1234,7 +1239,7 @@ pmu_wait_complete(struct adb_request *req) if (!via) return; while((pmu_state != idle && pmu_state != locked) || !req->complete) - via_pmu_interrupt(0, NULL, NULL); + via_pmu_interrupt(0, NULL); } /* This function loops until the PMU is idle and prevents it from @@ -1263,7 +1268,7 @@ pmu_suspend(void) spin_unlock_irqrestore(&pmu_lock, flags); if (req_awaiting_reply) adb_int_pending = 1; - via_pmu_interrupt(0, NULL, NULL); + via_pmu_interrupt(0, NULL); spin_lock_irqsave(&pmu_lock, flags); if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) { #ifdef SUSPEND_USES_PMU @@ -1313,7 +1318,7 @@ pmu_resume(void) /* Interrupt data could be the result data from an ADB cmd */ static void -pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) +pmu_handle_data(unsigned char *data, int len) { unsigned char ints, pirq; int i = 0; @@ -1388,7 +1393,7 @@ next: if (!(pmu_kind == PMU_OHARE_BASED && len == 4 && data[1] == 0x2c && data[3] == 0xff && (data[2] & ~1) == 0xf4)) - adb_input(data+1, len-1, regs, 1); + adb_input(data+1, len-1, 1); #endif /* CONFIG_ADB */ } } @@ -1426,7 +1431,7 @@ next: } static struct adb_request* -pmu_sr_intr(struct pt_regs *regs) +pmu_sr_intr(void) { struct adb_request *req; int bite = 0; @@ -1532,7 +1537,7 @@ pmu_sr_intr(struct pt_regs *regs) } static irqreturn_t -via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) +via_pmu_interrupt(int irq, void *arg) { unsigned long flags; int intr; @@ -1562,7 +1567,7 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs) pmu_irq_stats[0]++; } if (intr & SR_INT) { - req = pmu_sr_intr(regs); + req = pmu_sr_intr(); if (req) break; } @@ -1608,7 +1613,7 @@ no_free_slot: /* Deal with interrupt datas outside of the lock */ if (int_data >= 0) { - pmu_handle_data(interrupt_data[int_data], interrupt_data_len[int_data], regs); + pmu_handle_data(interrupt_data[int_data], interrupt_data_len[int_data]); spin_lock_irqsave(&pmu_lock, flags); ++disable_poll; int_data_state[int_data] = int_data_empty; @@ -1633,7 +1638,7 @@ pmu_unlock(void) static irqreturn_t -gpio1_interrupt(int irq, void *arg, struct pt_regs *regs) +gpio1_interrupt(int irq, void *arg) { unsigned long flags; @@ -1646,7 +1651,7 @@ gpio1_interrupt(int irq, void *arg, struct pt_regs *regs) pmu_irq_stats[1]++; adb_int_pending = 1; spin_unlock_irqrestore(&pmu_lock, flags); - via_pmu_interrupt(0, NULL, NULL); + via_pmu_interrupt(0, NULL); return IRQ_HANDLED; } return IRQ_NONE; @@ -1827,7 +1832,7 @@ pbook_alloc_pci_save(void) struct pci_dev *pd = NULL; npci = 0; - while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { + while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { ++npci; } if (npci == 0) @@ -1857,9 +1862,11 @@ pbook_pci_save(void) if (ps == NULL) return; - while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { - if (npci-- == 0) + while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { + if (npci-- == 0) { + pci_dev_put(pd); return; + } #ifndef HACKED_PCI_SAVE pci_read_config_word(pd, PCI_COMMAND, &ps->command); pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat); @@ -1887,11 +1894,13 @@ pbook_pci_restore(void) int npci = pbook_npci_saves; int j; - while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { + while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { #ifdef HACKED_PCI_SAVE int i; - if (npci-- == 0) + if (npci-- == 0) { + pci_dev_put(pd); return; + } ps++; for (i=2;i<16;i++) pci_write_config_dword(pd, i<<4, ps->config[i]); @@ -2107,7 +2116,7 @@ pmac_wakeup_devices(void) /* Force a poll of ADB interrupts */ adb_int_pending = 1; - via_pmu_interrupt(0, NULL, NULL); + via_pmu_interrupt(0, NULL); /* Restart jiffies & scheduling */ wakeup_decrementer(); diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index 35b70323e7e..d9986f3a3fb 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -107,7 +107,7 @@ BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); static int pmu_probe(void); static int pmu_init(void); static void pmu_start(void); -static irqreturn_t pmu_interrupt(int irq, void *arg, struct pt_regs *regs); +static irqreturn_t pmu_interrupt(int irq, void *arg); static int pmu_send_request(struct adb_request *req, int sync); static int pmu_autopoll(int devs); void pmu_poll(void); @@ -118,8 +118,7 @@ static void pmu_start(void); static void send_byte(int x); static void recv_byte(void); static void pmu_done(struct adb_request *req); -static void pmu_handle_data(unsigned char *data, int len, - struct pt_regs *regs); +static void pmu_handle_data(unsigned char *data, int len); static void set_volume(int level); static void pmu_enable_backlight(int on); static void pmu_set_brightness(int level); @@ -222,7 +221,7 @@ pmu_init(void) } if (pmu_state == idle) { adb_int_pending = 1; - pmu_interrupt(0, NULL, NULL); + pmu_interrupt(0, NULL); } pmu_poll(); udelay(10); @@ -563,17 +562,17 @@ pmu_poll(void) local_irq_save(flags); if (via1[IFR] & SR_INT) { via1[IFR] = SR_INT; - pmu_interrupt(IRQ_MAC_ADB_SR, NULL, NULL); + pmu_interrupt(IRQ_MAC_ADB_SR, NULL); } if (via1[IFR] & CB1_INT) { via1[IFR] = CB1_INT; - pmu_interrupt(IRQ_MAC_ADB_CL, NULL, NULL); + pmu_interrupt(IRQ_MAC_ADB_CL, NULL); } local_irq_restore(flags); } static irqreturn_t -pmu_interrupt(int irq, void *dev_id, struct pt_regs *regs) +pmu_interrupt(int irq, void *dev_id) { struct adb_request *req; int timeout, bite = 0; /* to prevent compiler warning */ @@ -657,7 +656,7 @@ pmu_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (pmu_state == reading_intr) { - pmu_handle_data(interrupt_data, data_index, regs); + pmu_handle_data(interrupt_data, data_index); } else { req = current_req; current_req = req->next; @@ -701,7 +700,7 @@ pmu_done(struct adb_request *req) /* Interrupt data could be the result data from an ADB cmd */ static void -pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) +pmu_handle_data(unsigned char *data, int len) { static int show_pmu_ints = 1; @@ -726,7 +725,7 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) } pmu_done(req); } else { - adb_input(data+1, len-1, regs, 1); + adb_input(data+1, len-1, 1); } } else { if (data[0] == 0x08 && len == 3) { @@ -843,7 +842,7 @@ pbook_pci_save(void) struct pci_save *ps; npci = 0; - while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) + while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) ++npci; n_pbook_pci_saves = npci; if (npci == 0) @@ -854,7 +853,7 @@ pbook_pci_save(void) return; pd = NULL; - while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { + while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { pci_read_config_word(pd, PCI_COMMAND, &ps->command); pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat); pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr); @@ -871,7 +870,7 @@ pbook_pci_restore(void) struct pci_dev *pd = NULL; int j; - while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { + while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { if (ps->command == 0) continue; pci_read_config_word(pd, PCI_COMMAND, &cmd); diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index ab3faa702d5..e947af982f9 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c @@ -34,6 +34,7 @@ #include <linux/device.h> #include <linux/platform_device.h> #include <linux/mutex.h> +#include <linux/freezer.h> #include <asm/prom.h> diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index ef66bf2778e..b3fbb45bc90 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c @@ -650,24 +650,26 @@ static struct notifier_block pm112_events = { .notifier_call = pm112_wf_notify, }; -static int wf_pm112_probe(struct device *dev) +static int wf_pm112_probe(struct platform_device *dev) { wf_register_client(&pm112_events); return 0; } -static int wf_pm112_remove(struct device *dev) +static int __devexit wf_pm112_remove(struct platform_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, +static struct platform_driver wf_pm112_driver = { .probe = wf_pm112_probe, - .remove = wf_pm112_remove, + .remove = __devexit_p(wf_pm112_remove), + .driver = { + .name = "windfarm", + .bus = &platform_bus_type, + }, }; static int __init wf_pm112_init(void) @@ -683,13 +685,24 @@ static int __init wf_pm112_init(void) ++nr_cores; printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); - driver_register(&wf_pm112_driver); + +#ifdef MODULE + request_module("windfarm_smu_controls"); + request_module("windfarm_smu_sensors"); + request_module("windfarm_smu_sat"); + request_module("windfarm_lm75_sensor"); + request_module("windfarm_max6690_sensor"); + request_module("windfarm_cpufreq_clamp"); + +#endif /* MODULE */ + + platform_driver_register(&wf_pm112_driver); return 0; } static void __exit wf_pm112_exit(void) { - driver_unregister(&wf_pm112_driver); + platform_driver_unregister(&wf_pm112_driver); } module_init(wf_pm112_init); diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index 2ff546e4c92..f24fa734046 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -131,8 +131,6 @@ static int wf_smu_mach_model; /* machine model id */ -static struct device *wf_smu_dev; - /* Controls & sensors */ static struct wf_sensor *sensor_cpu_power; static struct wf_sensor *sensor_cpu_temp; @@ -717,16 +715,14 @@ static int wf_init_pm(void) return 0; } -static int wf_smu_probe(struct device *ddev) +static int wf_smu_probe(struct platform_device *ddev) { - wf_smu_dev = ddev; - wf_register_client(&wf_smu_events); return 0; } -static int wf_smu_remove(struct device *ddev) +static int __devexit wf_smu_remove(struct platform_device *ddev) { wf_unregister_client(&wf_smu_events); @@ -766,16 +762,16 @@ static int wf_smu_remove(struct device *ddev) if (wf_smu_cpu_fans) kfree(wf_smu_cpu_fans); - wf_smu_dev = NULL; - return 0; } -static struct device_driver wf_smu_driver = { - .name = "windfarm", - .bus = &platform_bus_type, +static struct platform_driver wf_smu_driver = { .probe = wf_smu_probe, - .remove = wf_smu_remove, + .remove = __devexit_p(wf_smu_remove), + .driver = { + .name = "windfarm", + .bus = &platform_bus_type, + }, }; @@ -792,9 +788,10 @@ static int __init wf_smu_init(void) request_module("windfarm_smu_controls"); request_module("windfarm_smu_sensors"); request_module("windfarm_lm75_sensor"); + request_module("windfarm_cpufreq_clamp"); #endif /* MODULE */ - driver_register(&wf_smu_driver); + platform_driver_register(&wf_smu_driver); } return rc; @@ -803,7 +800,7 @@ static int __init wf_smu_init(void) static void __exit wf_smu_exit(void) { - driver_unregister(&wf_smu_driver); + platform_driver_unregister(&wf_smu_driver); } diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 59e9ffe37c3..26eee69ebe6 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c @@ -63,8 +63,6 @@ */ #undef HACKED_OVERTEMP -static struct device *wf_smu_dev; - /* Controls & sensors */ static struct wf_sensor *sensor_cpu_power; static struct wf_sensor *sensor_cpu_temp; @@ -641,16 +639,14 @@ static int wf_init_pm(void) return 0; } -static int wf_smu_probe(struct device *ddev) +static int wf_smu_probe(struct platform_device *ddev) { - wf_smu_dev = ddev; - wf_register_client(&wf_smu_events); return 0; } -static int wf_smu_remove(struct device *ddev) +static int __devexit wf_smu_remove(struct platform_device *ddev) { wf_unregister_client(&wf_smu_events); @@ -698,16 +694,16 @@ static int wf_smu_remove(struct device *ddev) if (wf_smu_cpu_fans) kfree(wf_smu_cpu_fans); - wf_smu_dev = NULL; - return 0; } -static struct device_driver wf_smu_driver = { - .name = "windfarm", - .bus = &platform_bus_type, +static struct platform_driver wf_smu_driver = { .probe = wf_smu_probe, - .remove = wf_smu_remove, + .remove = __devexit_p(wf_smu_remove), + .driver = { + .name = "windfarm", + .bus = &platform_bus_type, + }, }; @@ -723,9 +719,10 @@ static int __init wf_smu_init(void) request_module("windfarm_smu_controls"); request_module("windfarm_smu_sensors"); request_module("windfarm_lm75_sensor"); + request_module("windfarm_cpufreq_clamp"); #endif /* MODULE */ - driver_register(&wf_smu_driver); + platform_driver_register(&wf_smu_driver); } return rc; @@ -734,7 +731,7 @@ static int __init wf_smu_init(void) static void __exit wf_smu_exit(void) { - driver_unregister(&wf_smu_driver); + platform_driver_unregister(&wf_smu_driver); } diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index bff1f372f18..31b750d6120 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c @@ -56,7 +56,7 @@ static int smu_set_fan(int pwm, u8 id, u16 value) { struct smu_cmd cmd; u8 buffer[16]; - DECLARE_COMPLETION(comp); + DECLARE_COMPLETION_ONSTACK(comp); int rc; /* Fill SMU command structure */ diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index aceb61d9fbc..83f79de7174 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -397,12 +397,7 @@ static int wf_sat_detach(struct i2c_client *client) static int __init sat_sensors_init(void) { - int err; - - err = i2c_add_driver(&wf_sat_driver); - if (err < 0) - return err; - return 0; + return i2c_add_driver(&wf_sat_driver); } static void __exit sat_sensors_exit(void) diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c index defe9922ebd..01b4c50143d 100644 --- a/drivers/macintosh/windfarm_smu_sensors.c +++ b/drivers/macintosh/windfarm_smu_sensors.c @@ -67,7 +67,7 @@ static void smu_ads_release(struct wf_sensor *sr) static int smu_read_adc(u8 id, s32 *value) { struct smu_simple_cmd cmd; - DECLARE_COMPLETION(comp); + DECLARE_COMPLETION_ONSTACK(comp); int rc; rc = smu_queue_simple(&cmd, SMU_CMD_READ_ADC, 1, |