summaryrefslogtreecommitdiffstats
path: root/drivers/macintosh
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-06-15 01:55:58 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-06-15 01:55:58 +0000
commit53b3988d474435254a3b053a68bb24ce9e439295 (patch)
treef8da8e40f01f4ad02bbd76b8c9920749b118235f /drivers/macintosh
parentb0cb48abe83d1a4389ea938bf624f8baa82c5047 (diff)
Merge with 2.3.99-pre9.
Diffstat (limited to 'drivers/macintosh')
-rw-r--r--drivers/macintosh/Makefile30
-rw-r--r--drivers/macintosh/adb.c6
-rw-r--r--drivers/macintosh/mac_keyb.c64
-rw-r--r--drivers/macintosh/macserial.c233
-rw-r--r--drivers/macintosh/macserial.h2
-rw-r--r--drivers/macintosh/mediabay.c112
-rw-r--r--drivers/macintosh/nvram.c13
-rw-r--r--drivers/macintosh/via-pmu.c49
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(&current->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;