diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-15 01:55:58 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-15 01:55:58 +0000 |
commit | 53b3988d474435254a3b053a68bb24ce9e439295 (patch) | |
tree | f8da8e40f01f4ad02bbd76b8c9920749b118235f /drivers/macintosh | |
parent | b0cb48abe83d1a4389ea938bf624f8baa82c5047 (diff) |
Merge with 2.3.99-pre9.
Diffstat (limited to 'drivers/macintosh')
-rw-r--r-- | drivers/macintosh/Makefile | 30 | ||||
-rw-r--r-- | drivers/macintosh/adb.c | 6 | ||||
-rw-r--r-- | drivers/macintosh/mac_keyb.c | 64 | ||||
-rw-r--r-- | drivers/macintosh/macserial.c | 233 | ||||
-rw-r--r-- | drivers/macintosh/macserial.h | 2 | ||||
-rw-r--r-- | drivers/macintosh/mediabay.c | 112 | ||||
-rw-r--r-- | drivers/macintosh/nvram.c | 13 | ||||
-rw-r--r-- | drivers/macintosh/via-pmu.c | 49 |
8 files changed, 334 insertions, 175 deletions
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index c9a40a3c1..ac096db95 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -12,20 +12,20 @@ SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) -L_TARGET := macintosh.a -L_OBJS := +O_TARGET := macintosh.o +O_OBJS := M_OBJS := ifeq ($(CONFIG_PMAC_PBOOK),y) - L_OBJS += mediabay.o + O_OBJS += mediabay.o else ifeq ($(CONFIG_MAC_FLOPPY),y) - L_OBJS += mediabay.o + O_OBJS += mediabay.o endif endif ifeq ($(CONFIG_MAC_SERIAL),y) - L_OBJS += macserial.o + O_OBJS += macserial.o else ifeq ($(CONFIG_MAC_SERIAL),m) M_OBJS += macserial.o @@ -33,7 +33,7 @@ else endif ifeq ($(CONFIG_NVRAM),y) - L_OBJS += nvram.o + O_OBJS += nvram.o else ifeq ($(CONFIG_NVRAM),m) M_OBJS += nvram.o @@ -41,39 +41,39 @@ else endif ifdef CONFIG_ADB - LX_OBJS := adb.o + OX_OBJS := adb.o endif ifdef CONFIG_ADB_KEYBOARD - L_OBJS += mac_keyb.o + O_OBJS += mac_keyb.o endif ifdef CONFIG_ADB_MACII - L_OBJS += via-macii.o + O_OBJS += via-macii.o endif ifdef CONFIG_ADB_MACIISI - L_OBJS += via-maciisi.o + O_OBJS += via-maciisi.o endif ifdef CONFIG_ADB_CUDA - L_OBJS += via-cuda.o + O_OBJS += via-cuda.o endif ifdef CONFIG_ADB_IOP - L_OBJS += adb-iop.o + O_OBJS += adb-iop.o endif ifdef CONFIG_ADB_PMU - L_OBJS += via-pmu.o + O_OBJS += via-pmu.o endif ifdef CONFIG_ADB_PMU68K - L_OBJS += via-pmu68k.o + O_OBJS += via-pmu68k.o endif ifdef CONFIG_ADB_MACIO - L_OBJS += macio-adb.o + O_OBJS += macio-adb.o endif include $(TOPDIR)/Rules.make diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index fd8c1645a..2fc74f806 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -72,6 +72,7 @@ static struct adb_driver *adb_driver_list[] = { struct adb_driver *adb_controller; struct notifier_block *adb_client_list = NULL; static int adb_got_sleep = 0; +static int adb_inited = 0; #ifdef CONFIG_PMAC_PBOOK static int adb_notify_sleep(struct pmu_sleep_notifier *self, int when); @@ -213,6 +214,11 @@ int __init adb_init(void) return 0; #endif + /* xmon may do early-init */ + if (adb_inited) + return 0; + adb_inited = 1; + adb_controller = NULL; i = 0; diff --git a/drivers/macintosh/mac_keyb.c b/drivers/macintosh/mac_keyb.c index 04999bb4c..261e41d61 100644 --- a/drivers/macintosh/mac_keyb.c +++ b/drivers/macintosh/mac_keyb.c @@ -16,7 +16,7 @@ * * - Standard 1 button mouse * - All standard Apple Extended protocol (handler ID 4) - * - mouseman and trackman mice & trackballs + * - mouseman and trackman mice & trackballs * - PowerBook Trackpad (default setup: enable tapping) * - MicroSpeed mouse & trackball (needs testing) * - CH Products Trackball Pro (needs testing) @@ -344,7 +344,7 @@ input_keycode(int keycode, int repeat) #ifdef CONFIG_ADBMOUSE /* * XXX: Add mouse button 2+3 fake codes here if mouse open. - * Keep track of 'button' states here as we only send + * Keep track of 'button' states here as we only send * single up/down events! * Really messy; might need to check if keyboard is in * VC_RAW mode. @@ -591,11 +591,12 @@ extern int backlight_level; static void buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) { +#ifdef CONFIG_ADB_PMU /* * XXX: Where is the contrast control for the passive? * -- Cort */ - + /* Ignore data from register other than 0 */ #if 0 if ((adb_hardware != ADB_VIAPMU) || (data[0] & 0x3) || (nb < 2)) @@ -603,7 +604,7 @@ buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) if ((data[0] & 0x3) || (nb < 2)) #endif return; - + switch (data[1]&0xf ) { /* mute */ @@ -627,28 +628,25 @@ buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll) /* brightness decrease */ case 0xa: /* down event */ -#ifdef CONFIG_PPC if ( data[1] == (data[1]&0xf) ) { if (backlight_level > 2) pmu_set_brightness(backlight_level-2); else pmu_set_brightness(0); } -#endif break; /* brightness increase */ case 0x9: /* down event */ -#ifdef CONFIG_PPC if ( data[1] == (data[1]&0xf) ) { if (backlight_level < 0x1e) pmu_set_brightness(backlight_level+2); - else + else pmu_set_brightness(0x1f); } -#endif break; } +#endif /* CONFIG_ADB_PMU */ } /* Map led flags as defined in kbd_kern.h to bits for Apple keyboard. */ @@ -736,7 +734,7 @@ void __init mackbd_init_hw(void) led_request.complete = 1; mackeyb_probe(); - + notifier_chain_register(&adb_client_list, &mackeyb_adb_notifier); } @@ -744,11 +742,11 @@ static int adb_message_handler(struct notifier_block *this, unsigned long code, void *x) { unsigned long flags; - + switch (code) { case ADB_MSG_PRE_RESET: case ADB_MSG_POWERDOWN: - /* Stop the repeat timer. Autopoll is already off at this point */ + /* Stop the repeat timer. Autopoll is already off at this point */ save_flags(flags); cli(); del_timer(&repeat_timer); @@ -758,7 +756,7 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x) while(!led_request.complete) adb_poll(); break; - + case ADB_MSG_POST_RESET: mackeyb_probe(); break; @@ -841,7 +839,7 @@ mackeyb_probe(void) || (adb_mouse_kinds[id] == ADBMOUSE_MICROSPEED)) { init_microspeed(id); } else if (adb_mouse_kinds[id] == ADBMOUSE_MS_A3) { - init_ms_a3(id); + init_ms_a3(id); } else if (adb_mouse_kinds[id] == ADBMOUSE_EXTENDED) { /* * Register 1 is usually used for device @@ -854,7 +852,7 @@ mackeyb_probe(void) if ((req.reply_len) && (req.reply[1] == 0x9a) && ((req.reply[2] == 0x21) - || (req.reply[2] == 0x20))) + || (req.reply[2] == 0x20))) init_trackball(id); else if ((req.reply_len >= 4) && (req.reply[1] == 0x74) && (req.reply[2] == 0x70) && @@ -877,10 +875,10 @@ mackeyb_probe(void) } } -static void +static void init_trackpad(int id) { - struct adb_request req; + struct adb_request req; unsigned char r1_buffer[8]; printk(" (trackpad)"); @@ -907,15 +905,15 @@ init_trackpad(int id) adb_request(&req, NULL, ADBREQ_SYNC, 9, ADB_WRITEREG(id,2), - 0x99, - 0x94, - 0x19, - 0xff, - 0xb2, - 0x8a, - 0x1b, - 0x50); - + 0x99, + 0x94, + 0x19, + 0xff, + 0xb2, + 0x8a, + 0x1b, + 0x50); + adb_request(&req, NULL, ADBREQ_SYNC, 9, ADB_WRITEREG(id,1), r1_buffer[0], @@ -929,13 +927,13 @@ init_trackpad(int id) } } -static void +static void init_trackball(int id) { struct adb_request req; - + printk(" (trackman/mouseman)"); - + adb_mouse_kinds[id] = ADBMOUSE_TRACKBALL; adb_request(&req, NULL, ADBREQ_SYNC, 3, @@ -971,7 +969,7 @@ init_turbomouse(int id) printk(" (TurboMouse 5)"); adb_mouse_kinds[id] = ADBMOUSE_TURBOMOUSE5; - + adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id)); adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3)); @@ -1012,7 +1010,7 @@ init_microspeed(int id) /* This will initialize mice using the Microspeed, MacPoint and other compatible firmware. Bit 12 enables extended protocol. - + Register 1 Listen (4 Bytes) 0 - 3 Button is mouse (set also for double clicking!!!) 4 - 7 Button is locking (affects change speed also) @@ -1027,7 +1025,7 @@ init_microspeed(int id) 0 - 7 Product code 8 - 23 undefined, reserved 24 - 31 Version number - + Speed 0 is max. 1 to 255 set speed in increments of 1/256 of max. */ adb_request(&req, NULL, ADBREQ_SYNC, 5, @@ -1051,7 +1049,7 @@ init_ms_a3(int id) ADB_WRITEREG(id, 0x2), 0x00, 0x07); - + adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id)); } diff --git a/drivers/macintosh/macserial.c b/drivers/macintosh/macserial.c index 94ec60e1c..8e0528cba 100644 --- a/drivers/macintosh/macserial.c +++ b/drivers/macintosh/macserial.c @@ -131,17 +131,17 @@ static int serial_refcount; #define _INLINE_ inline #ifdef SERIAL_DEBUG_OPEN -#define OPNDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg) +#define OPNDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg) #else #define OPNDBG(fmt, arg...) do { } while (0) #endif #ifdef SERIAL_DEBUG_POWER -#define PWRDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg) +#define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg) #else #define PWRDBG(fmt, arg...) do { } while (0) #endif #ifdef SERIAL_DEBUG_BAUDS -#define BAUDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg) +#define BAUDBG(fmt, arg...) printk(fmt , ## arg) #else #define BAUDBG(fmt, arg...) do { } while (0) #endif @@ -414,7 +414,7 @@ static _INLINE_ void receive_chars(struct mac_serial *info, continue; if (tty->flip.count >= TTY_FLIPBUF_SIZE) tty_flip_buffer_push(tty); - + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { static int flip_buf_ovf; if (++flip_buf_ovf <= 1) @@ -505,7 +505,7 @@ static _INLINE_ void status_handle(struct mac_serial *info) if (info->tx_stopped) { #ifdef SERIAL_DEBUG_FLOW printk("CTS up\n"); -#endif +#endif info->tx_stopped = 0; if (!info->tx_active) transmit_chars(info); @@ -513,7 +513,7 @@ static _INLINE_ void status_handle(struct mac_serial *info) } else { #ifdef SERIAL_DEBUG_FLOW printk("CTS down\n"); -#endif +#endif info->tx_stopped = 1; } } @@ -536,7 +536,7 @@ static _INLINE_ void receive_special_dma(struct mac_serial *info) == virt_to_bus(info->rx_cmds[info->rx_cbuf] + 1)) where -= in_le16(&info->rx->res_count); where--; - + stat = read_zsreg(info->zs_channel, R1); flag = stat_to_flag(stat); @@ -582,7 +582,7 @@ static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) #ifdef SERIAL_DEBUG_INTR printk("rs_interrupt: irq %d, zs_intreg 0x%x\n", irq, (int)zs_intreg); -#endif +#endif if ((zs_intreg & CHAN_IRQMASK) == 0) break; @@ -659,7 +659,7 @@ static void rs_stop(struct tty_struct *tty) if (serial_paranoia_check(info, tty->device, "rs_stop")) return; - + #if 0 save_flags(flags); cli(); if (info->curregs[5] & TxENAB) { @@ -675,7 +675,7 @@ static void rs_start(struct tty_struct *tty) { struct mac_serial *info = (struct mac_serial *)tty->driver_data; unsigned long flags; - + #ifdef SERIAL_DEBUG_STOP printk("rs_start %ld....\n", tty->ldisc.chars_in_buffer(tty)); @@ -683,7 +683,7 @@ static void rs_start(struct tty_struct *tty) if (serial_paranoia_check(info, tty->device, "rs_start")) return; - + save_flags(flags); cli(); #if 0 if (info->xmit_cnt && info->xmit_buf && !(info->curregs[5] & TxENAB)) { @@ -717,7 +717,7 @@ static void do_softint(void *private_) { struct mac_serial *info = (struct mac_serial *) private_; struct tty_struct *tty; - + tty = info->tty; if (!tty) return; @@ -750,7 +750,7 @@ static int startup(struct mac_serial * info, int can_sleep) OPNDBG("starting up ttyS%d (irq %d)...\n", info->line, info->irq); delay = set_scc_power(info, 1); - + setup_scc(info); OPNDBG("enabling IRQ on ttyS%d (irq %d)...\n", info->line, info->irq); @@ -758,7 +758,6 @@ static int startup(struct mac_serial * info, int can_sleep) info->flags |= ZILOG_INITIALIZED; enable_irq(info->irq); if (info->dma_initted) { -// enable_irq(info->tx_dma_irq); enable_irq(info->rx_dma_irq); } @@ -881,8 +880,6 @@ static void dma_init(struct mac_serial * info) volatile struct dbdma_cmd *cd; unsigned char *p; -//printk(KERN_DEBUG "SCC: dma_init\n"); - info->rx_nbuf = 8; /* various mem set up */ @@ -958,10 +955,10 @@ static void dma_init(struct mac_serial * info) static int setup_scc(struct mac_serial * info) { unsigned long flags; - + OPNDBG("setting up ttys%d SCC...\n", info->line); - save_flags(flags); cli(); /* Disable interrupts */ + save_flags(flags); cli(); /* Disable interrupts */ /* * Reset the chip. @@ -992,7 +989,8 @@ static int setup_scc(struct mac_serial * info) /* * Turn on RTS and DTR. */ - zs_rtsdtr(info, 1); + if (!info->is_irda) + zs_rtsdtr(info, 1); /* * Finally, enable sequencing and interrupts @@ -1058,7 +1056,7 @@ static void shutdown(struct mac_serial * info) { OPNDBG("Shutting down serial port %d (irq %d)....\n", info->line, info->irq); - + if (!(info->flags & ZILOG_INITIALIZED)) { OPNDBG("(already shutdown)\n"); return; @@ -1124,7 +1122,7 @@ static int set_scc_power(struct mac_serial * info, int state) /* The timings looks strange but that's the ones MacOS seems to use for the internal modem. I think we can use a lot faster ones, at least whe not using the modem, this should be tested. - */ + */ if (state) { PWRDBG("ttyS%02d: powering up hardware\n", info->line); if (feature_test(info->dev_node, FEATURE_Serial_enable) == 0) { @@ -1150,7 +1148,7 @@ static int set_scc_power(struct mac_serial * info, int state) delay = 2500; /* wait for 2.5s before using */ } #ifdef CONFIG_PMAC_PBOOK - if (info->is_pwbk_ir) + if (info->is_irda) pmu_enable_irled(1); #endif /* CONFIG_PMAC_PBOOK */ } else { @@ -1161,14 +1159,14 @@ static int set_scc_power(struct mac_serial * info, int state) mdelay(10); } #ifdef CONFIG_PMAC_PBOOK - if (info->is_pwbk_ir) + if (info->is_irda) pmu_enable_irled(0); #endif /* CONFIG_PMAC_PBOOK */ - - if (info->zs_chan_a == info->zs_channel) { + + if (info->zs_chan_a == info->zs_channel && !info->is_irda) { PWRDBG("ttyS%02d: shutting down SCC channel A\n", info->line); feature_clear(info->dev_node, FEATURE_Serial_IO_A); - } else { + } else if (!info->is_irda) { PWRDBG("ttyS%02d: shutting down SCC channel B\n", info->line); feature_clear(info->dev_node, FEATURE_Serial_IO_B); } @@ -1188,6 +1186,113 @@ static int set_scc_power(struct mac_serial * info, int state) return delay; } +static void irda_rts_pulses(struct mac_serial *info, int w) +{ + unsigned long flags; + + udelay(w); + save_flags(flags); cli(); + write_zsreg(info->zs_channel, 5, Tx8 | TxENAB); + udelay(2); + write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS); + udelay(8); + write_zsreg(info->zs_channel, 5, Tx8 | TxENAB); + udelay(4); + write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS); + restore_flags(flags); +} + +/* + * Set the irda codec on the imac to the specified baud rate. + */ +static void irda_setup(struct mac_serial *info) +{ + int code, speed, t; + unsigned long flags; + + speed = info->tty->termios->c_cflag & CBAUD; + if (speed < B2400 || speed > B115200) + return; + code = 0x4d + B115200 - speed; + + /* disable serial interrupts and receive DMA */ + write_zsreg(info->zs_channel, 1, info->curregs[1] & ~0x9f); + + /* wait for transmitter to drain */ + t = 10000; + while ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0 + || (read_zsreg(info->zs_channel, 1) & ALL_SNT) == 0) { + if (--t <= 0) { + printk(KERN_ERR "transmitter didn't drain\n"); + return; + } + udelay(10); + } + udelay(100); + + /* set to 8 bits, no parity, 19200 baud, RTS on, DTR off */ + write_zsreg(info->zs_channel, 4, X16CLK | SB1); + write_zsreg(info->zs_channel, 11, TCBR | RCBR); + t = BPS_TO_BRG(19200, ZS_CLOCK/16); + write_zsreg(info->zs_channel, 12, t); + write_zsreg(info->zs_channel, 13, t >> 8); + write_zsreg(info->zs_channel, 14, BRENABL); + write_zsreg(info->zs_channel, 3, Rx8 | RxENABLE); + write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS); + + /* set TxD low for ~104us and pulse RTS */ + udelay(1000); + save_flags(flags); cli(); + write_zsdata(info->zs_channel, 0xfe); + irda_rts_pulses(info, 150); + restore_flags(flags); + irda_rts_pulses(info, 180); + irda_rts_pulses(info, 50); + udelay(100); + + /* assert DTR, wait 30ms, talk to the chip */ + write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS | DTR); + udelay(30000); + while (read_zsreg(info->zs_channel, 0) & Rx_CH_AV) + read_zsdata(info->zs_channel); + + write_zsdata(info->zs_channel, 1); + t = 1000; + while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) == 0) { + if (--t <= 0) { + printk(KERN_ERR "irda_setup timed out on 1st byte\n"); + goto out; + } + udelay(10); + } + t = read_zsdata(info->zs_channel); + if (t != 4) + printk(KERN_ERR "irda_setup 1st byte = %x\n", t); + + write_zsdata(info->zs_channel, code); + t = 1000; + while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) == 0) { + if (--t <= 0) { + printk(KERN_ERR "irda_setup timed out on 2nd byte\n"); + goto out; + } + udelay(10); + } + t = read_zsdata(info->zs_channel); + if (t != code) + printk(KERN_ERR "irda_setup 2nd byte = %x (%x)\n", t, code); + + /* Drop DTR again and do some more RTS pulses */ + out: + udelay(100); + write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS); + irda_rts_pulses(info, 80); + + /* We should be right to go now. We assume that load_zsregs + will get called soon to load up the correct baud rate etc. */ + info->curregs[5] = (info->curregs[5] | RTS) & ~DTR; + info->pendregs[5] = info->curregs[5]; +} /* * This routine is called to set the UART divisor registers to match @@ -1195,7 +1300,6 @@ static int set_scc_power(struct mac_serial * info, int state) */ static void change_speed(struct mac_serial *info, struct termios *old_termios) { - unsigned short port; unsigned cflag; int bits; int brg, baud; @@ -1203,8 +1307,6 @@ static void change_speed(struct mac_serial *info, struct termios *old_termios) if (!info->tty || !info->tty->termios) return; - if (!(port = info->port)) - return; cflag = info->tty->termios->c_cflag; baud = tty_get_baud_rate(info->tty); @@ -1227,7 +1329,7 @@ static void change_speed(struct mac_serial *info, struct termios *old_termios) info->zs_baud = baud; info->clk_divisor = 16; - BAUDBG("set speed to %d bds, ", baud); + BAUDBG(KERN_DEBUG "set speed to %d bds, ", baud); switch (baud) { case ZS_CLOCK/16: /* 230400 */ @@ -1325,6 +1427,10 @@ static void change_speed(struct mac_serial *info, struct termios *old_termios) BAUDBG("timeout=%d/%ds, base:%d\n", (int)info->timeout, (int)HZ, (int)info->baud_base); + /* set the irda codec to the right rate */ + if (info->is_irda) + irda_setup(info); + /* Load up the new values */ load_zsregs(info->zs_channel, info->curregs); @@ -1391,7 +1497,7 @@ static int rs_write(struct tty_struct * tty, int from_user, } else { while (1) { save_flags(flags); - cli(); + cli(); c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, SERIAL_XMIT_SIZE - info->xmit_head)); @@ -1419,7 +1525,7 @@ static int rs_write_room(struct tty_struct *tty) { struct mac_serial *info = (struct mac_serial *)tty->driver_data; int ret; - + if (serial_paranoia_check(info, tty->device, "rs_write_room")) return 0; ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; @@ -1431,7 +1537,7 @@ static int rs_write_room(struct tty_struct *tty) static int rs_chars_in_buffer(struct tty_struct *tty) { struct mac_serial *info = (struct mac_serial *)tty->driver_data; - + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) return 0; return info->xmit_cnt; @@ -1441,7 +1547,7 @@ static void rs_flush_buffer(struct tty_struct *tty) { struct mac_serial *info = (struct mac_serial *)tty->driver_data; unsigned long flags; - + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) return; save_flags(flags); cli(); @@ -1466,13 +1572,12 @@ static void rs_throttle(struct tty_struct * tty) struct mac_serial *info = (struct mac_serial *)tty->driver_data; unsigned long flags; #ifdef SERIAL_DEBUG_THROTTLE - printk("throttle %ld....\n",tty->ldisc.chars_in_buffer(tty)); #endif if (serial_paranoia_check(info, tty->device, "rs_throttle")) return; - + if (I_IXOFF(tty)) { save_flags(flags); cli(); info->x_char = STOP_CHAR(tty); @@ -1502,13 +1607,12 @@ static void rs_unthrottle(struct tty_struct * tty) struct mac_serial *info = (struct mac_serial *)tty->driver_data; unsigned long flags; #ifdef SERIAL_DEBUG_THROTTLE - printk("unthrottle %s: %d....\n",tty->ldisc.chars_in_buffer(tty)); #endif if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) return; - + if (I_IXOFF(tty)) { save_flags(flags); cli(); if (info->x_char) @@ -1685,8 +1789,6 @@ static void rs_break(struct tty_struct *tty, int break_state) if (serial_paranoia_check(info, tty->device, "rs_break")) return; - if (!info->port) - return; save_flags(flags); cli(); if (break_state == -1) @@ -1714,7 +1816,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; } - + switch (cmd) { case TIOCMGET: return get_modem_info(info, (unsigned int *) arg); @@ -1736,7 +1838,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, info, sizeof(struct mac_serial))) return -EFAULT; return 0; - + default: return -ENOIOCTLCMD; } @@ -1775,15 +1877,15 @@ static void rs_close(struct tty_struct *tty, struct file * filp) if (!info || serial_paranoia_check(info, tty->device, "rs_close")) return; - + save_flags(flags); cli(); - + if (tty_hung_up_p(filp)) { MOD_DEC_USE_COUNT; restore_flags(flags); return; } - + OPNDBG("rs_close ttys%d, count = %d\n", info->line, info->count); if ((tty->count == 1) && (info->count != 1)) { /* @@ -1984,7 +2086,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, info->flags |= ZILOG_CALLOUT_ACTIVE; return 0; } - + /* * If non-blocking mode is set, or the port is not enabled, * then make the check up front and then exit. @@ -2004,7 +2106,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, if (tty->termios->c_cflag & CLOCAL) do_clocal = 1; } - + /* * Block waiting for the carrier detect and the line to become * free (i.e., not in use by the callout). While we are in @@ -2024,7 +2126,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, while (1) { cli(); if (!(info->flags & ZILOG_CALLOUT_ACTIVE) && - (tty->termios->c_cflag & CBAUD)) + (tty->termios->c_cflag & CBAUD) && + !info->is_irda) zs_rtsdtr(info, 1); sti(); set_current_state(TASK_INTERRUPTIBLE); @@ -2034,7 +2137,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, if (info->flags & ZILOG_HUP_NOTIFY) retval = -EAGAIN; else - retval = -ERESTARTSYS; + retval = -ERESTARTSYS; #else retval = -EAGAIN; #endif @@ -2063,7 +2166,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, return retval; info->flags |= ZILOG_NORMAL_ACTIVE; return 0; -} +} /* * This routine is called whenever a serial port is opened. It @@ -2208,11 +2311,11 @@ chan_init(struct mac_serial *zss, struct mac_zschannel *zs_chan, /* XXX tested only with wallstreet PowerBook, should do no harm anyway */ conn = get_property(ch, "AAPL,connector", &len); - zss->is_pwbk_ir = conn && (strcmp(conn, "infrared") == 0); + zss->is_irda = conn && (strcmp(conn, "infrared") == 0); /* 1999 Powerbook G3 has slot-names property instead */ slots = (struct slot_names_prop *)get_property(ch, "slot-names", &len); if (slots && slots->count > 0 && strcmp(slots->name, "IrDA") == 0) - zss->is_pwbk_ir = 1; + zss->is_irda = 1; if (zss->has_dma) { zss->dma_priv = NULL; @@ -2345,7 +2448,11 @@ int macserial_init(void) memset(&serial_driver, 0, sizeof(struct tty_driver)); serial_driver.magic = TTY_DRIVER_MAGIC; +#ifdef CONFIG_DEVFS_FS + serial_driver.name = "tts/%d"; +#else serial_driver.name = "ttyS"; +#endif /* CONFIG_DEVFS_FS */ serial_driver.major = TTY_MAJOR; serial_driver.minor_start = 64; serial_driver.num = zs_channels_found; @@ -2383,7 +2490,11 @@ int macserial_init(void) * major number and the subtype code. */ callout_driver = serial_driver; +#ifdef CONFIG_DEVFS_FS + callout_driver.name = "cua/%d"; +#else callout_driver.name = "cua"; +#endif /* CONFIG_DEVFS_FS */ callout_driver.major = TTYAUX_MAJOR; callout_driver.subtype = SERIAL_TYPE_CALLOUT; @@ -2402,7 +2513,7 @@ int macserial_init(void) zs_soft[channel].clk_divisor = 16; /* -- we are not sure the SCC is powered ON at this point zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); -*/ +*/ zs_soft[channel].zs_baud = 38400; /* If console serial line, then enable interrupts. */ @@ -2453,16 +2564,16 @@ int macserial_init(void) printk(", port = %s", connector); if (info->is_cobalt_modem) printk(" (cobalt modem)"); - if (info->is_pwbk_ir) - printk(" (powerbook IR)"); + if (info->is_irda) + printk(" (IrDA)"); printk("\n"); #ifndef CONFIG_XMON #ifdef CONFIG_KGDB if (!info->kgdb_channel) #endif /* CONFIG_KGDB */ - /* By default, disable the port */ - set_scc_power(info, 0); + /* By default, disable the port */ + set_scc_power(info, 0); #endif /* CONFIG_XMON */ } tmp_buf = 0; @@ -2561,7 +2672,7 @@ static void serial_console_write(struct console *co, const char *s, while ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0) eieio(); - + write_zsdata(info->zs_channel, 13); } } @@ -2869,7 +2980,7 @@ void __init zs_kgdb_hook(int tty_num) probe_sccs(); set_scc_power(&zs_soft[tty_num], 1); - + zs_kgdbchan = zs_soft[tty_num].zs_channel; zs_soft[tty_num].change_needed = 0; zs_soft[tty_num].clk_divisor = 16; @@ -2891,12 +3002,12 @@ int serial_notify_sleep(struct pmu_sleep_notifier *self, int when) { int i; - + switch (when) { case PBOOK_SLEEP_REQUEST: case PBOOK_SLEEP_REJECT: break; - + case PBOOK_SLEEP_NOW: for (i=0; i<zs_channels_found; i++) { struct mac_serial *info = &zs_soft[i]; diff --git a/drivers/macintosh/macserial.h b/drivers/macintosh/macserial.h index 3ba2e6062..86fe77599 100644 --- a/drivers/macintosh/macserial.h +++ b/drivers/macintosh/macserial.h @@ -111,7 +111,7 @@ struct mac_serial { char kgdb_channel; /* Kgdb is running on this channel */ char is_cons; /* Is this our console. */ char is_cobalt_modem; /* is a gatwick-based cobalt modem */ - char is_pwbk_ir; /* is connected to an IR led on powerbooks */ + char is_irda; /* is connected to an IrDA codec */ unsigned char tx_active; /* character is being xmitted */ unsigned char tx_stopped; /* output is suspended */ diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 439526804..6002870b4 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -3,6 +3,8 @@ * * Copyright (C) 1998 Paul Mackerras. * + * Various evolutions by Benjamin Herrenschmidt & Henry Worth + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -56,12 +58,15 @@ struct media_bay_hw { struct media_bay_info { volatile struct media_bay_hw* addr; + volatile u8* extint_gpio; int content_id; int state; int last_value; int value_count; int timer; struct device_node* dev_node; + int pismo; /* New PowerBook3,1 */ + int gpio_cache; #ifdef CONFIG_BLK_DEV_IDE unsigned long cd_base; int cd_index; @@ -75,7 +80,25 @@ struct media_bay_info { static volatile struct media_bay_info media_bays[MAX_BAYS]; int media_bay_count = 0; -#define MB_CONTENTS(i) ((in_8(&media_bays[i].addr->contents) >> 4) & 7) +inline int mb_content(volatile struct media_bay_info *bay) +{ + if (bay->pismo) { + unsigned char new_gpio = in_8(bay->extint_gpio + 0xe) & 2; + if (new_gpio) { + bay->gpio_cache = new_gpio; + return MB_NO; + } else if (bay->gpio_cache != new_gpio) { + /* make sure content bits are set */ + feature_set(bay->dev_node, FEATURE_Mediabay_content); + udelay(5); + bay->gpio_cache = new_gpio; + } + return (in_le32((unsigned*)bay->addr) >> 4) & 0xf; + } else { + int cont = (in_8(&bay->addr->contents) >> 4) & 7; + return (cont == 7) ? MB_NO : cont; + } +} #ifdef CONFIG_BLK_DEV_IDE /* check the busy bit in the media-bay ide interface @@ -184,12 +207,22 @@ media_bay_init(void) media_bays[n].addr = (volatile struct media_bay_hw *) ioremap(np->addrs[0].address, sizeof(struct media_bay_hw)); + media_bays[n].pismo = device_is_compatible(np, "keylargo-media-bay"); + if (media_bays[n].pismo) { + if (!np->parent || strcmp(np->parent->name, "mac-io")) { + printk(KERN_ERR "Pismo media-bay has no mac-io parent !\n"); + continue; + } + media_bays[n].extint_gpio = ioremap(np->parent->addrs[0].address + + 0x58, 0x10); + } + #ifdef MB_USE_INTERRUPTS if (np->n_intrs == 0) { printk(KERN_ERR "media bay %d has no irq\n",n); continue; } - + if (request_irq(np->intrs[0].line, media_bay_intr, 0, "Media bay", (void *)n)) { printk(KERN_ERR "Couldn't get IRQ %d for media bay %d\n", np->intrs[0].line, n); @@ -203,10 +236,11 @@ media_bay_init(void) /* Force an immediate detect */ set_mb_power(n,0); mdelay(MB_POWER_DELAY); - out_8(&media_bays[n].addr->contents, 0x70); + if(!media_bays[n].pismo) + out_8(&media_bays[n].addr->contents, 0x70); mdelay(MB_STABLE_DELAY); media_bays[n].content_id = MB_NO; - media_bays[n].last_value = MB_CONTENTS(n); + media_bays[n].last_value = mb_content(&media_bays[n]); media_bays[n].value_count = MS_TO_HZ(MB_STABLE_DELAY); media_bays[n].state = mb_empty; do { @@ -214,11 +248,11 @@ media_bay_init(void) media_bay_step(n); } while((media_bays[n].state != mb_empty) && (media_bays[n].state != mb_up)); - + n++; np=np->next; } - + if (media_bay_count) { printk(KERN_INFO "Registered %d media-bay(s)\n", media_bay_count); @@ -227,7 +261,8 @@ media_bay_init(void) pmu_register_sleep_notifier(&mb_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ - kernel_thread(media_bay_task, NULL, 0); + kernel_thread(media_bay_task, NULL, + CLONE_FS | CLONE_FILES | CLONE_SIGHAND); } } @@ -252,7 +287,11 @@ set_mb_power(int which, int onoff) MBDBG("mediabay%d: powering up\n", which); } else { feature_clear(mb->dev_node, FEATURE_Mediabay_floppy_enable); - feature_clear(mb->dev_node, FEATURE_IDE1_enable); + if (mb->pismo) + feature_clear(mb->dev_node, FEATURE_IDE0_enable); + else + feature_clear(mb->dev_node, FEATURE_IDE1_enable); + feature_clear(mb->dev_node, FEATURE_Mediabay_IDE_switch); feature_clear(mb->dev_node, FEATURE_Mediabay_PCI_enable); feature_clear(mb->dev_node, FEATURE_SWIM3_enable); feature_clear(mb->dev_node, FEATURE_Mediabay_power); @@ -271,9 +310,17 @@ set_media_bay(int which, int id) switch (id) { case MB_CD: - feature_set(bay->dev_node, FEATURE_IDE1_enable); - udelay(10); - feature_set(bay->dev_node, FEATURE_IDE1_reset); + if (bay->pismo) { + feature_set(bay->dev_node, FEATURE_Mediabay_IDE_switch); + udelay(10); + feature_set(bay->dev_node, FEATURE_IDE0_enable); + udelay(10); + feature_set(bay->dev_node, FEATURE_IDE0_reset); + } else { + feature_set(bay->dev_node, FEATURE_IDE1_enable); + udelay(10); + feature_set(bay->dev_node, FEATURE_IDE1_reset); + } printk(KERN_INFO "media bay %d contains a CD-ROM drive\n", which); break; case MB_FD: @@ -345,8 +392,8 @@ media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, if ((MB_CD != media_bays[i].content_id) || media_bays[i].state != mb_up) return 0; - - printk(KERN_DEBUG "Registered ide %d for media bay %d\n", index, i); + + printk(KERN_DEBUG "Registered ide %d for media bay %d\n", index, i); do { if (MB_IDE_READY(i)) { media_bays[i].cd_index = index; @@ -354,7 +401,7 @@ media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, } mdelay(1); } while(--timeout); - printk(KERN_DEBUG "Timeout waiting IDE in bay %d\n", i); + printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i); return -ENODEV; } #endif @@ -397,7 +444,10 @@ media_bay_step(int i) } #ifdef CONFIG_BLK_DEV_IDE MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id); - feature_clear(bay->dev_node, FEATURE_IDE1_reset); + if (bay->pismo) + feature_clear(bay->dev_node, FEATURE_IDE0_reset); + else + feature_clear(bay->dev_node, FEATURE_IDE1_reset); bay->timer = MS_TO_HZ(MB_IDE_WAIT); bay->state = mb_ide_resetting; #else @@ -476,23 +526,21 @@ media_bay_step(int i) int __pmac media_bay_task(void *x) { - int i = 0; - + int i; + strcpy(current->comm, "media-bay"); #ifdef MB_IGNORE_SIGNALS sigfillset(¤t->blocked); #endif for (;;) { - media_bay_step(i); + for (i = 0; i < media_bay_count; ++i) + media_bay_step(i); - if (++i >= media_bay_count) { - i = 0; current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); if (signal_pending(current)) return 0; - } } } @@ -500,7 +548,7 @@ void __pmac poll_media_bay(int which) { volatile struct media_bay_info* bay = &media_bays[which]; - int id = MB_CONTENTS(which); + int id = mb_content(bay); if (id == bay->last_value) { if (id != bay->content_id @@ -548,27 +596,26 @@ mb_notify_sleep(struct pmu_sleep_notifier *self, int when) bay = &media_bays[i]; set_mb_power(i, 0); mdelay(10); - out_8(&bay->addr->contents, 0x70); } break; case PBOOK_WAKE: for (i=0; i<media_bay_count; i++) { bay = &media_bays[i]; /* We re-enable the bay using it's previous content - only if it did not change. Note those bozo timings, they seem - to help the 3400 get it right + only if it did not change. Note those bozo timings, + they seem to help the 3400 get it right. */ mdelay(MB_STABLE_DELAY); - out_8(&bay->addr->contents, 0x70); + if (!bay->pismo) + out_8(&bay->addr->contents, 0x70); mdelay(MB_STABLE_DELAY); - if (MB_CONTENTS(i) != bay->content_id) + if (mb_content(bay) != bay->content_id) continue; set_mb_power(i, 1); - mdelay(MB_POWER_DELAY); - media_bays[i].last_value = bay->content_id; - media_bays[i].value_count = MS_TO_HZ(MB_STABLE_DELAY); - media_bays[i].timer = 0; - media_bays[i].cd_retry = 0; + bay->last_value = bay->content_id; + bay->value_count = MS_TO_HZ(MB_STABLE_DELAY); + bay->timer = MS_TO_HZ(MB_POWER_DELAY); + bay->cd_retry = 0; do { mdelay(1000/HZ); media_bay_step(i); @@ -580,3 +627,4 @@ mb_notify_sleep(struct pmu_sleep_notifier *self, int when) return PBOOK_SLEEP_OK; } #endif /* CONFIG_PMAC_PBOOK */ + diff --git a/drivers/macintosh/nvram.c b/drivers/macintosh/nvram.c index eb5dcaa3b..a44e624d8 100644 --- a/drivers/macintosh/nvram.c +++ b/drivers/macintosh/nvram.c @@ -96,21 +96,18 @@ static struct miscdevice nvram_dev = { &nvram_fops }; -int nvram_init(void) +int __init nvram_init(void) { printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n", NVRAM_VERSION); misc_register(&nvram_dev); return 0; } -#ifdef MODULE -int init_module (void) -{ - return( nvram_init() ); -} -void cleanup_module (void) +void __exit nvram_cleanup(void) { misc_deregister( &nvram_dev ); } -#endif + +module_init(nvram_init); +module_exit(nvram_cleanup); diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 4acdc55c5..2b6402b0c 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -41,6 +41,7 @@ #include <asm/feature.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> +#include <asm/heathrow.h> /* Misc minor number allocated for /dev/pmu */ #define PMU_MINOR 154 @@ -201,7 +202,7 @@ static char *pbook_type[] = { "PowerBook 2400/3400/3500(G3)", "PowerBook G3 Series", "1999 PowerBook G3", - "Core99 (iBook/iMac/G4)" + "Core99" }; int __openfirmware @@ -326,7 +327,7 @@ void via_pmu_start(void) out_8(&via[IER], IER_SET | SR_INT | CB1_INT); pmu_fully_inited = 1; - + /* Enable backlight */ pmu_enable_backlight(1); } @@ -508,7 +509,7 @@ pmu_adb_reset_bus(void) if (save_autopoll != 0) pmu_adb_autopoll(save_autopoll); - + return 0; } @@ -845,9 +846,9 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) } else { #ifdef CONFIG_XMON if (len == 4 && data[1] == 0x2c) { - extern int xmon_wants_key, xmon_pmu_keycode; + extern int xmon_wants_key, xmon_adb_keycode; if (xmon_wants_key) { - xmon_pmu_keycode = data[2]; + xmon_adb_keycode = data[2]; return; } } @@ -886,7 +887,7 @@ pmu_enable_backlight(int on) if ((vias == NULL) || !pmu_has_backlight) return; - + /* first call: get current backlight value */ if (on && backlight_level < 0) { switch (pmu_kind) { @@ -983,12 +984,12 @@ pmu_restart(void) struct adb_request req; cli(); - + pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB | PMU_INT_TICK ); while(!req.complete) pmu_poll(); - + pmu_request(&req, NULL, 1, PMU_RESET); while(!req.complete || (pmu_state != idle)) pmu_poll(); @@ -1002,7 +1003,7 @@ pmu_shutdown(void) struct adb_request req; cli(); - + pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB | PMU_INT_TICK ); while(!req.complete) @@ -1065,6 +1066,8 @@ broadcast_sleep(int when, int fallback) current = list_entry(list, struct pmu_sleep_notifier, list); ret = current->notifier_call(current, when); if (ret != PBOOK_SLEEP_OK) { + printk(KERN_DEBUG "sleep %d rejected by %p (%p)\n", + when, current, current->notifier_call); for (; list != &sleep_notifiers; list = list->next) { current = list_entry(list, struct pmu_sleep_notifier, list); current->notifier_call(current, fallback); @@ -1179,7 +1182,7 @@ void pmu_blink(int n) while (!req.complete) pmu_poll(); udelay(50000); } - udelay(50000); + udelay(150000); } #endif @@ -1240,20 +1243,14 @@ int __openfirmware powerbook_sleep_G3(void) /* Make sure the decrementer won't interrupt us */ asm volatile("mtdec %0" : : "r" (0x7fffffff)); -#if 0 - /* Save the state of PCI config space for some slots */ - pbook_pci_save(); -#endif + /* For 750, save backside cache setting and disable it */ save_l2cr = _get_L2CR(); /* (returns 0 if not 750) */ if (save_l2cr) _set_L2CR(0); - if (macio_base != 0) { + if (macio_base != 0) save_fcr = in_le32(FEATURE_CTRL(macio_base)); - /* Check if this is still valid on older powerbooks */ - out_le32(FEATURE_CTRL(macio_base), save_fcr & ~(0x00000140UL)); - } if (current->thread.regs && (current->thread.regs->msr & MSR_FP) != 0) giveup_fpu(current); @@ -1267,12 +1264,15 @@ int __openfirmware powerbook_sleep_G3(void) /* Ask the PMU to put us to sleep */ pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); while (!sleep_req.complete) - mb(); + pmu_poll(); cli(); while (pmu_state != idle) pmu_poll(); + /* clear IOBUS enable */ + out_le32(FEATURE_CTRL(macio_base), save_fcr & ~HRW_IOBUS_ENABLE); + /* Call low-level ASM sleep handler */ low_sleep_handler(); @@ -1281,17 +1281,15 @@ int __openfirmware powerbook_sleep_G3(void) pmcr1 &= ~(GRACKLE_PM|GRACKLE_DOZE|GRACKLE_SLEEP|GRACKLE_NAP); grackle_pcibios_write_config_word(0, 0, 0x70, pmcr1); + /* reenable IOBUS */ + out_le32(FEATURE_CTRL(macio_base), save_fcr | HRW_IOBUS_ENABLE); + /* Make sure the PMU is idle */ while (pmu_state != idle) pmu_poll(); sti(); -#if 0 - /* According to someone from Apple, this should not be needed, - at least not for all devices. Let's keep it for now until we - have something that works. */ - pbook_pci_restore(); -#endif + set_context(current->mm->context); /* Restore L2 cache */ @@ -1302,6 +1300,7 @@ int __openfirmware powerbook_sleep_G3(void) sleep_restore_intrs(); /* Notify drivers */ + mdelay(10); broadcast_wake(); return 0; |