summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-04-01 03:32:51 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-04-01 03:32:51 +0000
commite11f564413d1d8feac7a60fb3aa440bf66a4e25a (patch)
tree9fc9db586b30cbdf4b414273201eab7c5598cb71 /arch
parent3c73e78526f87333ed70059e41c7e6a5ccda7ced (diff)
Rest of Nino updates.
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/philips/drivers/.cvsignore2
-rw-r--r--arch/mips/philips/drivers/generic_serial.c1078
-rw-r--r--arch/mips/philips/drivers/uart-pr31700.c1313
-rw-r--r--arch/mips/philips/drivers/uart-pr31700.h126
-rw-r--r--arch/mips/philips/nino/Makefile11
-rw-r--r--arch/mips/philips/nino/int-handler.S9
-rw-r--r--arch/mips/philips/nino/irq.c42
-rw-r--r--arch/mips/philips/nino/kgdb.c6
-rw-r--r--arch/mips/philips/nino/power.c6
-rw-r--r--arch/mips/philips/nino/prom.c73
-rw-r--r--arch/mips/philips/nino/ramdisk/Makefile (renamed from arch/mips/philips/drivers/Makefile)14
-rw-r--r--arch/mips/philips/nino/ramdisk/ld.script11
-rw-r--r--arch/mips/philips/nino/reset.c4
-rw-r--r--arch/mips/philips/nino/rtc.c7
-rw-r--r--arch/mips/philips/nino/setup.c17
-rw-r--r--arch/mips/philips/nino/time.c8
-rw-r--r--arch/mips/philips/nino/wbflush.c4
17 files changed, 117 insertions, 2614 deletions
diff --git a/arch/mips/philips/drivers/.cvsignore b/arch/mips/philips/drivers/.cvsignore
deleted file mode 100644
index 857dd22e9..000000000
--- a/arch/mips/philips/drivers/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.depend
-.*.flags
diff --git a/arch/mips/philips/drivers/generic_serial.c b/arch/mips/philips/drivers/generic_serial.c
deleted file mode 100644
index acd3402f8..000000000
--- a/arch/mips/philips/drivers/generic_serial.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/*
- * generic_serial.c
- *
- * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl
- *
- * written for the SX serial driver.
- * Contains the code that should be shared over all the serial drivers.
- *
- * Credit for the idea to do it this way might go to Alan Cox.
- *
- *
- * Version 0.1 -- December, 1998. Initial version.
- * Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc.
- * Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus.
- *
- * BitWizard is actively maintaining this file. We sometimes find
- * that someone submitted changes to this file. We really appreciate
- * your help, but please submit changes through us. We're doing our
- * best to be responsive. -- REW
- * */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/mm.h>
-#include <linux/generic_serial.h>
-#include <asm/semaphore.h>
-#include <asm/uaccess.h>
-
-#define DEBUG
-
-static char * tmp_buf;
-static DECLARE_MUTEX(tmp_buf_sem);
-
-static int gs_debug;
-
-#ifdef DEBUG
-#define gs_dprintk(f, str...) if (gs_debug & f) printk (str)
-#else
-#define gs_dprintk(f, str...) /* nothing */
-#endif
-
-#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter " __FUNCTION__ "\n")
-#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit " __FUNCTION__ "\n")
-
-#if NEW_WRITE_LOCKING
-#define DECL /* Nothing */
-#define LOCKIT down (& port->port_write_sem);
-#define RELEASEIT up (&port->port_write_sem);
-#else
-#define DECL unsigned long flags;
-#define LOCKIT save_flags (flags);cli ()
-#define RELEASEIT restore_flags (flags)
-#endif
-
-#define RS_EVENT_WRITE_WAKEUP 1
-
-MODULE_PARM(gs_debug, "i");
-
-
-void gs_put_char(struct tty_struct * tty, unsigned char ch)
-{
- struct gs_port *port;
- DECL
-
- func_enter ();
-
- if (!tty) return;
-
- port = tty->driver_data;
-
- if (!port) return;
-
- if (! (port->flags & ASYNC_INITIALIZED)) return;
-
- /* Take a lock on the serial tranmit buffer! */
- LOCKIT;
-
- if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
- /* Sorry, buffer is full, drop character. Update statistics???? -- REW */
- RELEASEIT;
- return;
- }
-
- port->xmit_buf[port->xmit_head++] = ch;
- port->xmit_head &= SERIAL_XMIT_SIZE - 1;
- port->xmit_cnt++; /* Characters in buffer */
-
- RELEASEIT;
- func_exit ();
-}
-
-
-#ifdef NEW_WRITE_LOCKING
-
-/*
-> Problems to take into account are:
-> -1- Interrupts that empty part of the buffer.
-> -2- page faults on the access to userspace.
-> -3- Other processes that are also trying to do a "write".
-*/
-
-int gs_write(struct tty_struct * tty, int from_user,
- const unsigned char *buf, int count)
-{
- struct gs_port *port;
- int c, total = 0;
- int t;
-
- func_enter ();
-
- if (!tty) return 0;
-
- port = tty->driver;
-
- if (!port) return 0;
-
- if (! (port->flags & ASYNC_INITIALIZED))
- return 0;
-
- /* get exclusive "write" access to this port (problem 3) */
- /* This is not a spinlock because we can have a disk access (page
- fault) in copy_from_user */
- down (& port->port_write_sem);
-
- while (1) {
-
- c = count;
-
- /* This is safe because we "OWN" the "head". Noone else can
- change the "head": we own the port_write_sem. */
- /* Don't overrun the end of the buffer */
- t = SERIAL_XMIT_SIZE - port->xmit_head;
- if (t < c) c = t;
-
- /* This is safe because the xmit_cnt can only decrease. This
- would increase "t", so we might copy too little chars. */
- /* Don't copy past the "head" of the buffer */
- t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt;
- if (t < c) c = t;
-
- /* Can't copy more? break out! */
- if (c <= 0) break;
- if (from_user)
- copy_from_user (port->xmit_buf + port->xmit_head, buf, c);
- else
- memcpy (port->xmit_buf + port->xmit_head, buf, c);
-
- port -> xmit_cnt += c;
- port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1);
- buf += c;
- count -= c;
- total += c;
- }
- up (& port->port_write_sem);
-
- gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n",
- (port->flags & GS_TX_INTEN)?"enabled": "disabled");
-
- if (port->xmit_cnt &&
- !tty->stopped &&
- !tty->hw_stopped &&
- !(port->flags & GS_TX_INTEN)) {
- port->flags |= GS_TX_INTEN;
- port->rd->enable_tx_interrupts (port);
- }
- func_exit ();
- return total;
-}
-#else
-/*
-> Problems to take into account are:
-> -1- Interrupts that empty part of the buffer.
-> -2- page faults on the access to userspace.
-> -3- Other processes that are also trying to do a "write".
-*/
-
-int gs_write(struct tty_struct * tty, int from_user,
- const unsigned char *buf, int count)
-{
- struct gs_port *port;
- int c, total = 0;
- int t;
- unsigned long flags;
-
- func_enter ();
-
- /* The standard serial driver returns 0 in this case.
- That sounds to me as "No error, I just didn't get to writing any
- bytes. Feel free to try again."
- The "official" way to write n bytes from buf is:
-
- for (nwritten = 0;nwritten < n;nwritten += rv) {
- rv = write (fd, buf+nwritten, n-nwritten);
- if (rv < 0) break; // Error: bail out. //
- }
-
- which will loop endlessly in this case. The manual page for write
- agrees with me. In practise almost everybody writes
- "write (fd, buf,n);" but some people might have had to deal with
- incomplete writes in the past and correctly implemented it by now...
- */
-
- if (!tty) return -EIO;
-
- port = tty->driver_data;
- if (!port || !port->xmit_buf || !tmp_buf)
- return -EIO;
-
- save_flags(flags);
- if (from_user) {
- down(&tmp_buf_sem);
- while (1) {
- c = count;
-
- /* This is safe because we "OWN" the "head". Noone else can
- change the "head": we own the port_write_sem. */
- /* Don't overrun the end of the buffer */
- t = SERIAL_XMIT_SIZE - port->xmit_head;
- if (t < c) c = t;
-
- /* This is safe because the xmit_cnt can only decrease. This
- would increase "t", so we might copy too little chars. */
- /* Don't copy past the "head" of the buffer */
- t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt;
- if (t < c) c = t;
-
- /* Can't copy more? break out! */
- if (c <= 0) break;
-
- c -= copy_from_user(tmp_buf, buf, c);
- if (!c) {
- if (!total)
- total = -EFAULT;
- break;
- }
- cli();
- t = SERIAL_XMIT_SIZE - port->xmit_head;
- if (t < c) c = t;
- t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt;
- if (t < c) c = t;
-
- memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c);
- port->xmit_head = ((port->xmit_head + c) &
- (SERIAL_XMIT_SIZE-1));
- port->xmit_cnt += c;
- restore_flags(flags);
- buf += c;
- count -= c;
- total += c;
- }
- up(&tmp_buf_sem);
- } else {
- while (1) {
- cli();
- c = count;
-
- /* This is safe because we "OWN" the "head". Noone else can
- change the "head": we own the port_write_sem. */
- /* Don't overrun the end of the buffer */
- t = SERIAL_XMIT_SIZE - port->xmit_head;
- if (t < c) c = t;
-
- /* This is safe because the xmit_cnt can only decrease. This
- would increase "t", so we might copy too little chars. */
- /* Don't copy past the "head" of the buffer */
- t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt;
- if (t < c) c = t;
-
- /* Can't copy more? break out! */
- if (c <= 0) {
- restore_flags(flags);
- break;
- }
- memcpy(port->xmit_buf + port->xmit_head, buf, c);
- port->xmit_head = ((port->xmit_head + c) &
- (SERIAL_XMIT_SIZE-1));
- port->xmit_cnt += c;
- restore_flags(flags);
- buf += c;
- count -= c;
- total += c;
- }
- }
-
- if (port->xmit_cnt &&
- !tty->stopped &&
- !tty->hw_stopped &&
- !(port->flags & GS_TX_INTEN)) {
- port->flags |= GS_TX_INTEN;
- port->rd->enable_tx_interrupts (port);
- }
- func_exit ();
- return total;
-}
-
-#endif
-
-
-
-int gs_write_room(struct tty_struct * tty)
-{
- struct gs_port *port = tty->driver_data;
- int ret;
-
- func_enter ();
- ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
- if (ret < 0)
- ret = 0;
- func_exit ();
- return ret;
-}
-
-
-int gs_chars_in_buffer(struct tty_struct *tty)
-{
- struct gs_port *port = tty->driver_data;
- func_enter ();
-
- func_exit ();
- return port->xmit_cnt;
-}
-
-
-int gs_real_chars_in_buffer(struct tty_struct *tty)
-{
- struct gs_port *port;
- func_enter ();
-
- if (!tty) return 0;
- port = tty->driver_data;
-
- if (!port->rd) return 0;
- if (!port->rd->chars_in_buffer) return 0;
-
- func_exit ();
- return port->xmit_cnt + port->rd->chars_in_buffer (port);
-}
-
-
-static int gs_wait_tx_flushed (void * ptr, int timeout)
-{
- struct gs_port *port = ptr;
- long end_jiffies;
- int jiffies_to_transmit, charsleft = 0, rv = 0;
- int to, rcib;
-
- func_enter();
-
- gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port);
- if (port) {
- gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n",
- port->xmit_cnt, port->xmit_buf, port->tty);
- }
-
- if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
- gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n");
- func_exit();
- return -EINVAL; /* This is an error which we don't know how to handle. */
- }
-
- rcib = gs_real_chars_in_buffer(port->tty);
-
- if(rcib <= 0) {
- gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
- func_exit();
- return rv;
- }
- /* stop trying: now + twice the time it would normally take + seconds */
- end_jiffies = jiffies;
- if (timeout != MAX_SCHEDULE_TIMEOUT)
- end_jiffies += port->baud?(2 * rcib * 10 * HZ / port->baud):0;
- end_jiffies += timeout;
-
- gs_dprintk (GS_DEBUG_FLUSH, "now=%lx, end=%lx (%ld).\n",
- jiffies, end_jiffies, end_jiffies-jiffies);
-
- to = 100;
- /* the expression is actually jiffies < end_jiffies, but that won't
- work around the wraparound. Tricky eh? */
- while (to-- &&
- (charsleft = gs_real_chars_in_buffer (port->tty)) &&
- time_after (end_jiffies, jiffies)) {
- /* Units check:
- chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies!
- check! */
-
- charsleft += 16; /* Allow 16 chars more to be transmitted ... */
- jiffies_to_transmit = port->baud?(1 + charsleft * 10 * HZ / port->baud):0;
- /* ^^^ Round up.... */
- if (jiffies_to_transmit <= 0) jiffies_to_transmit = 1;
-
- gs_dprintk (GS_DEBUG_FLUSH, "Expect to finish in %d jiffies "
- "(%d chars).\n", jiffies_to_transmit, charsleft);
-
- set_current_state (TASK_INTERRUPTIBLE);
- schedule_timeout(jiffies_to_transmit);
- if (signal_pending (current)) {
- gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: ");
- rv = -EINTR;
- break;
- }
- }
-
- gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft);
- set_current_state (TASK_RUNNING);
-
- func_exit();
- return rv;
-}
-
-
-
-void gs_flush_buffer(struct tty_struct *tty)
-{
- struct gs_port *port;
- unsigned long flags;
-
- func_enter ();
-
- if (!tty) return;
-
- port = tty->driver_data;
-
- if (!port) return;
-
- /* XXX Would the write semaphore do? */
- save_flags(flags); cli();
- port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
- restore_flags(flags);
-
- wake_up_interruptible(&tty->write_wait);
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
- func_exit ();
-}
-
-
-void gs_flush_chars(struct tty_struct * tty)
-{
- struct gs_port *port;
-
- func_enter ();
-
- if (!tty) return;
-
- port = tty->driver_data;
-
- if (!port) return;
-
- if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
- !port->xmit_buf) {
- func_exit ();
- return;
- }
-
- /* Beats me -- REW */
- port->flags |= GS_TX_INTEN;
- port->rd->enable_tx_interrupts (port);
- func_exit ();
-}
-
-
-void gs_stop(struct tty_struct * tty)
-{
- struct gs_port *port;
-
- func_enter ();
-
- if (!tty) return;
-
- port = tty->driver_data;
-
- if (!port) return;
-
- if (port->xmit_cnt &&
- port->xmit_buf &&
- (port->flags & GS_TX_INTEN) ) {
- port->flags &= ~GS_TX_INTEN;
- port->rd->disable_tx_interrupts (port);
- }
- func_exit ();
-}
-
-
-void gs_start(struct tty_struct * tty)
-{
- struct gs_port *port;
-
- if (!tty) return;
-
- port = tty->driver_data;
-
- if (!port) return;
-
- if (port->xmit_cnt &&
- port->xmit_buf &&
- !(port->flags & GS_TX_INTEN) ) {
- port->flags |= GS_TX_INTEN;
- port->rd->enable_tx_interrupts (port);
- }
- func_exit ();
-}
-
-
-void gs_shutdown_port (struct gs_port *port)
-{
- long flags;
-
- func_enter();
-
- if (!port) return;
-
- if (!(port->flags & ASYNC_INITIALIZED))
- return;
-
- save_flags (flags);
- cli ();
-
- if (port->xmit_buf) {
- free_page((unsigned long) port->xmit_buf);
- port->xmit_buf = 0;
- }
-
- if (port->tty)
- set_bit(TTY_IO_ERROR, &port->tty->flags);
-
- port->rd->shutdown_port (port);
-
- port->flags &= ~ASYNC_INITIALIZED;
- restore_flags (flags);
-
- func_exit();
-}
-
-
-void gs_hangup(struct tty_struct *tty)
-{
- struct gs_port *port;
-
- func_enter ();
-
- if (!tty) return;
-
- port = tty->driver_data;
- tty = port->tty;
- if (!tty)
- return;
-
- gs_shutdown_port (port);
- port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE |GS_ACTIVE);
- port->tty = NULL;
- port->count = 0;
-
- wake_up_interruptible(&port->open_wait);
- func_exit ();
-}
-
-
-void gs_do_softint(void *private_)
-{
- struct gs_port *port = private_;
- struct tty_struct *tty;
-
- func_enter ();
-
- if (!port) return;
-
- tty = port->tty;
-
- if (!tty) return;
-
- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
- wake_up_interruptible(&tty->write_wait);
- }
- func_exit ();
-}
-
-
-int gs_block_til_ready(void *port_, struct file * filp)
-{
- struct gs_port *port = port_;
- DECLARE_WAITQUEUE(wait, current);
- int retval;
- int do_clocal = 0;
- int CD;
- struct tty_struct *tty;
-
- func_enter ();
-
- if (!port) return 0;
-
- tty = port->tty;
-
- if (!tty) return 0;
-
- gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n");
- /*
- * If the device is in the middle of being closed, then block
- * until it's done, and then try again.
- */
- if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&port->close_wait);
- if (port->flags & ASYNC_HUP_NOTIFY)
- return -EAGAIN;
- else
- return -ERESTARTSYS;
- }
-
- gs_dprintk (GS_DEBUG_BTR, "after hung up\n");
-
- /*
- * If this is a callout device, then just make sure the normal
- * device isn't being used.
- */
- if (tty->driver.subtype == GS_TYPE_CALLOUT) {
- if (port->flags & ASYNC_NORMAL_ACTIVE)
- return -EBUSY;
- if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
- (port->flags & ASYNC_SESSION_LOCKOUT) &&
- (port->session != current->session))
- return -EBUSY;
- if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
- (port->flags & ASYNC_PGRP_LOCKOUT) &&
- (port->pgrp != current->pgrp))
- return -EBUSY;
- port->flags |= ASYNC_CALLOUT_ACTIVE;
- return 0;
- }
-
- gs_dprintk (GS_DEBUG_BTR, "after subtype\n");
-
- /*
- * If non-blocking mode is set, or the port is not enabled,
- * then make the check up front and then exit.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
- if (port->flags & ASYNC_CALLOUT_ACTIVE)
- return -EBUSY;
- port->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;
- }
-
- gs_dprintk (GS_DEBUG_BTR, "after nonblock\n");
-
- if (port->flags & ASYNC_CALLOUT_ACTIVE) {
- if (port->normal_termios.c_cflag & CLOCAL)
- do_clocal = 1;
- } else {
- if (C_CLOCAL(tty))
- 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
- * this loop, port->count is dropped by one, so that
- * rs_close() knows when to free things. We restore it upon
- * exit, either normal or abnormal.
- */
- retval = 0;
-
- add_wait_queue(&port->open_wait, &wait);
-
- gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n");
- cli();
- if (!tty_hung_up_p(filp))
- port->count--;
- sti();
- port->blocked_open++;
- while (1) {
- CD = port->rd->get_CD (port);
- gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD);
- set_current_state (TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(port->flags & ASYNC_INITIALIZED)) {
- if (port->flags & ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
- break;
- }
- if (!(port->flags & ASYNC_CALLOUT_ACTIVE) &&
- !(port->flags & ASYNC_CLOSING) &&
- (do_clocal || CD))
- break;
- gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n",
- (int)signal_pending (current), *(long*)(&current->blocked));
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- schedule();
- }
- gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n",
- port->blocked_open);
- set_current_state (TASK_RUNNING);
- remove_wait_queue(&port->open_wait, &wait);
- if (!tty_hung_up_p(filp))
- port->count++;
- port->blocked_open--;
- if (retval)
- return retval;
-
- port->flags |= ASYNC_NORMAL_ACTIVE;
- func_exit ();
- return 0;
-}
-
-
-void gs_close(struct tty_struct * tty, struct file * filp)
-{
- unsigned long flags;
- struct gs_port *port;
-
- func_enter ();
-
- if (!tty) return;
-
- port = (struct gs_port *) tty->driver_data;
-
- if (!port) return;
-
- if (!port->tty) {
- /* This seems to happen when this is called from vhangup. */
- gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->tty is NULL\n");
- port->tty = tty;
- }
-
- save_flags(flags); cli();
-
- if (tty_hung_up_p(filp)) {
- restore_flags(flags);
- port->rd->hungup (port);
- func_exit ();
- return;
- }
-
- if ((tty->count == 1) && (port->count != 1)) {
- printk(KERN_ERR "gs: gs_close: bad port count;"
- " tty->count is 1, port count is %d\n", port->count);
- port->count = 1;
- }
- if (--port->count < 0) {
- printk(KERN_ERR "gs: gs_close: bad port count: %d\n", port->count);
- port->count = 0;
- }
- if (port->count) {
- gs_dprintk(GS_DEBUG_CLOSE, "gs_close: count: %d\n", port->count);
- restore_flags(flags);
- func_exit ();
- return;
- }
- port->flags |= ASYNC_CLOSING;
-
- /*
- * Save the termios structure, since this port may have
- * separate termios for callout and dialin.
- */
- if (port->flags & ASYNC_NORMAL_ACTIVE)
- port->normal_termios = *tty->termios;
- if (port->flags & ASYNC_CALLOUT_ACTIVE)
- port->callout_termios = *tty->termios;
- /*
- * Now we wait for the transmit buffer to clear; and we notify
- * the line discipline to only process XON/XOFF characters.
- */
- tty->closing = 1;
- /* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, port->closing_wait); */
-
- /*
- * At this point we stop accepting input. To do this, we
- * disable the receive line status interrupts, and tell the
- * interrupt driver to stop checking the data ready bit in the
- * line status register.
- */
-
- port->rd->disable_rx_interrupts (port);
-
- /* close has no way of returning "EINTR", so discard return value */
- if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- gs_wait_tx_flushed (port, port->closing_wait);
-
- port->flags &= ~GS_ACTIVE;
-
- if (tty->driver.flush_buffer)
- tty->driver.flush_buffer(tty);
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
- tty->closing = 0;
-
- port->event = 0;
- port->rd->close (port);
- port->rd->shutdown_port (port);
- port->tty = 0;
-
- if (port->blocked_open) {
- if (port->close_delay) {
- set_current_state (TASK_INTERRUPTIBLE);
- schedule_timeout(port->close_delay);
- }
- wake_up_interruptible(&port->open_wait);
- }
- port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
- ASYNC_CLOSING | ASYNC_INITIALIZED);
- wake_up_interruptible(&port->close_wait);
-
- restore_flags(flags);
- func_exit ();
-}
-
-
-static unsigned int gs_baudrates[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
-};
-
-
-void gs_set_termios (struct tty_struct * tty,
- struct termios * old_termios)
-{
- struct gs_port *port;
- int baudrate, tmp, rv;
- struct termios *tiosp;
-
- func_enter();
-
- if (!tty) return;
-
- port = tty->driver_data;
-
- if (!port) return;
-
- tiosp = tty->termios;
-
- if (gs_debug & GS_DEBUG_TERMIOS) {
- gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
- }
-
-#if 0
- /* This is an optimization that is only allowed for dumb cards */
- /* Smart cards require knowledge of iflags and oflags too: that
- might change hardware cooking mode.... */
-#endif
- if (old_termios) {
- if( (tiosp->c_iflag == old_termios->c_iflag)
- && (tiosp->c_oflag == old_termios->c_oflag)
- && (tiosp->c_cflag == old_termios->c_cflag)
- && (tiosp->c_lflag == old_termios->c_lflag)
- && (tiosp->c_line == old_termios->c_line)
- && (memcmp(tiosp->c_cc, old_termios->c_cc, NCC) == 0)) {
- gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: optimized away\n");
- return /* 0 */;
- }
- } else
- gs_dprintk(GS_DEBUG_TERMIOS, "gs_set_termios: no old_termios: "
- "no optimization\n");
-
- if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) {
- if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n");
- if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n");
- if(tiosp->c_cflag != old_termios->c_cflag) printk("c_cflag changed\n");
- if(tiosp->c_lflag != old_termios->c_lflag) printk("c_lflag changed\n");
- if(tiosp->c_line != old_termios->c_line) printk("c_line changed\n");
- if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n");
- }
-
- baudrate = tiosp->c_cflag & CBAUD;
- if (baudrate & CBAUDEX) {
- baudrate &= ~CBAUDEX;
- if ((baudrate < 1) || (baudrate > 4))
- tiosp->c_cflag &= ~CBAUDEX;
- else
- baudrate += 15;
- }
-
- baudrate = gs_baudrates[baudrate];
- if ((tiosp->c_cflag & CBAUD) == B38400) {
- if ( (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- baudrate = 57600;
- else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- baudrate = 115200;
- else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- baudrate = 230400;
- else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- baudrate = 460800;
- else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
- baudrate = (port->baud_base / port->custom_divisor);
- }
-
- /* I recommend using THIS instead of the mess in termios (and
- duplicating the above code). Next we should create a clean
- interface towards this variable. If your card supports arbitrary
- baud rates, (e.g. CD1400 or 16550 based cards) then everything
- will be very easy..... */
- port->baud = baudrate;
-
- /* Two timer ticks seems enough to wakeup something like SLIP driver */
- /* Baudrate/10 is cps. Divide by HZ to get chars per tick. */
- tmp = (baudrate / 10 / HZ) * 2;
-
- if (tmp < 0) tmp = 0;
- if (tmp >= SERIAL_XMIT_SIZE) tmp = SERIAL_XMIT_SIZE-1;
-
- port->wakeup_chars = tmp;
-
- /* We should really wait for the characters to be all sent before
- changing the settings. -- CAL */
- rv = gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT);
- if (rv < 0) return /* rv */;
-
- rv = port->rd->set_real_termios(port);
- if (rv < 0) return /* rv */;
-
- if ((!old_termios ||
- (old_termios->c_cflag & CRTSCTS)) &&
- !( tiosp->c_cflag & CRTSCTS)) {
- tty->stopped = 0;
- gs_start(tty);
- }
-
-#ifdef tytso_patch_94Nov25_1726
- /* This "makes sense", Why is it commented out? */
-
- if (!(old_termios->c_cflag & CLOCAL) &&
- (tty->termios->c_cflag & CLOCAL))
- wake_up_interruptible(&info->open_wait);
-#endif
-
- func_exit();
- return /* 0 */;
-}
-
-
-
-/* Must be called with interrupts enabled */
-int gs_init_port(struct gs_port *port)
-{
- unsigned long flags;
- unsigned long page;
-
- save_flags (flags);
- if (!tmp_buf) {
- page = get_free_page(GFP_KERNEL);
-
- cli (); /* Don't expect this to make a difference. */
- if (tmp_buf)
- free_page(page);
- else
- tmp_buf = (unsigned char *) page;
- restore_flags (flags);
-
- if (!tmp_buf) {
- return -ENOMEM;
- }
- }
-
- if (port->flags & ASYNC_INITIALIZED)
- return 0;
-
- if (!port->xmit_buf) {
- /* We may sleep in get_free_page() */
- unsigned long tmp;
-
- tmp = get_free_page(GFP_KERNEL);
-
- /* Spinlock? */
- cli ();
- if (port->xmit_buf)
- free_page (tmp);
- else
- port->xmit_buf = (unsigned char *) tmp;
- restore_flags (flags);
-
- if (!port->xmit_buf)
- return -ENOMEM;
- }
-
- cli();
-
- if (port->tty)
- clear_bit(TTY_IO_ERROR, &port->tty->flags);
-
- port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-
- gs_set_termios(port->tty, NULL);
-
- port->flags |= ASYNC_INITIALIZED;
- port->flags &= ~GS_TX_INTEN;
-
- restore_flags(flags);
- return 0;
-}
-
-
-int gs_setserial(struct gs_port *port, struct serial_struct *sp)
-{
- struct serial_struct sio;
-
- copy_from_user(&sio, sp, sizeof(struct serial_struct));
-
- if (!capable(CAP_SYS_ADMIN)) {
- if ((sio.baud_base != port->baud_base) ||
- (sio.close_delay != port->close_delay) ||
- ((sio.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK)))
- return(-EPERM);
- }
-
- port->flags = (port->flags & ~ASYNC_USR_MASK) |
- (sio.flags & ASYNC_USR_MASK);
-
- port->baud_base = sio.baud_base;
- port->close_delay = sio.close_delay;
- port->closing_wait = sio.closing_wait;
- port->custom_divisor = sio.custom_divisor;
-
- gs_set_termios (port->tty, NULL);
-
- return 0;
-}
-
-
-/*****************************************************************************/
-
-/*
- * Generate the serial struct info.
- */
-
-void gs_getserial(struct gs_port *port, struct serial_struct *sp)
-{
- struct serial_struct sio;
-
- memset(&sio, 0, sizeof(struct serial_struct));
- sio.flags = port->flags;
- sio.baud_base = port->baud_base;
- sio.close_delay = port->close_delay;
- sio.closing_wait = port->closing_wait;
- sio.custom_divisor = port->custom_divisor;
- sio.hub6 = 0;
-
- /* If you want you can override these. */
- sio.type = PORT_UNKNOWN;
- sio.xmit_fifo_size = -1;
- sio.line = -1;
- sio.port = -1;
- sio.irq = -1;
-
- if (port->rd->getserial)
- port->rd->getserial (port, &sio);
-
- copy_to_user(sp, &sio, sizeof(struct serial_struct));
-}
-
-EXPORT_SYMBOL(gs_put_char);
-EXPORT_SYMBOL(gs_write);
-EXPORT_SYMBOL(gs_write_room);
-EXPORT_SYMBOL(gs_chars_in_buffer);
-EXPORT_SYMBOL(gs_flush_buffer);
-EXPORT_SYMBOL(gs_flush_chars);
-EXPORT_SYMBOL(gs_stop);
-EXPORT_SYMBOL(gs_start);
-EXPORT_SYMBOL(gs_hangup);
-EXPORT_SYMBOL(gs_do_softint);
-EXPORT_SYMBOL(gs_block_til_ready);
-EXPORT_SYMBOL(gs_close);
-EXPORT_SYMBOL(gs_set_termios);
-EXPORT_SYMBOL(gs_init_port);
-EXPORT_SYMBOL(gs_setserial);
-EXPORT_SYMBOL(gs_getserial);
-
diff --git a/arch/mips/philips/drivers/uart-pr31700.c b/arch/mips/philips/drivers/uart-pr31700.c
deleted file mode 100644
index 92adb7056..000000000
--- a/arch/mips/philips/drivers/uart-pr31700.c
+++ /dev/null
@@ -1,1313 +0,0 @@
-/*
- * Serial driver for r39xx
- *
- * Copyright (C) 2000 Jim Pick <jim@jimpick.com>
- *
- * Inspired by, and/or includes bits from:
- *
- * drivers/char/serial.c (standard serial driver)
- * drivers/char/sx.c (use of generic_serial interface)
- * drivers/char/esp.c (another UART that uses DMA)
- * arch/mips/vr41xx/serial.c (another MIPS serial driver)
- *
- * Please see those files for credits.
- *
- * Also, the original rough serial console code was:
- *
- * Copyright (C) 1999 Harald Koerfgen
- *
- * $Id: r39xx_serial.c,v 1.16 2001/01/11 20:24:47 pavel Exp $
- */
-
-#include <linux/init.h>
-#include <linux/config.h>
-#include <linux/tty.h>
-#include <linux/major.h>
-#include <linux/ptrace.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/malloc.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <asm/uaccess.h>
-#include <asm/philips/pr31700.h>
-#include <asm/delay.h>
-#include <asm/wbflush.h>
-#include "uart-pr31700.h"
-
-/* Prototypes */
-
-static void rs_disable_tx_interrupts (void * ptr);
-static void rs_enable_tx_interrupts (void * ptr);
-static void rs_disable_rx_interrupts (void * ptr);
-static void rs_enable_rx_interrupts (void * ptr);
-static int rs_get_CD (void * ptr);
-static void rs_shutdown_port (void * ptr);
-static int rs_set_real_termios (void *ptr);
-static int rs_chars_in_buffer (void * ptr);
-static void rs_hungup (void *ptr);
-static void rs_close (void *ptr);
-
-
-
-static struct real_driver rs_real_driver = {
- disable_tx_interrupts: rs_disable_tx_interrupts,
- enable_tx_interrupts: rs_enable_tx_interrupts,
- disable_rx_interrupts: rs_disable_rx_interrupts,
- enable_rx_interrupts: rs_enable_rx_interrupts,
- get_CD: rs_get_CD,
- shutdown_port: rs_shutdown_port,
- set_real_termios: rs_set_real_termios,
- chars_in_buffer: rs_chars_in_buffer,
- close: rs_close,
- hungup: rs_hungup,
-};
-
-static struct tty_driver rs_driver, rs_callout_driver;
-
-static struct tty_struct * rs_table[RS_NPORTS] = { NULL, };
-static struct termios ** rs_termios;
-static struct termios ** rs_termios_locked;
-
-struct rs_port *rs_ports;
-int rs_refcount;
-int rs_initialized = 0;
-
-#ifdef CONFIG_PM
-static struct pm_dev *pmdev;
-static int pm_request(struct pm_dev* dev, pm_request_t req, void* data);
-#endif
-
-#define DEBUG
-#undef DEBUG2
-
-#ifdef DEBUG2
-int rs_debug = RS_DEBUG_ALL & ~RS_DEBUG_TRANSMIT;
-#else
-int rs_debug = 0;
-#endif
-
-
-/*
- * Helper routines
- */
-
-
-static inline unsigned int serial_in(struct rs_port *port, int offset)
-{
- unsigned int tmp;
-
- tmp = *(volatile unsigned int *)(port->base + offset);
- tmp &= 0xff;
- barrier();
- return tmp;
-}
-
-static inline void serial_out(struct rs_port *port, int offset, int value)
-{
- *(volatile unsigned int *)(port->base + offset) = (unsigned char)value;
-
- barrier();
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines. All of the following
- * subroutines are declared as inline and are folded into
- * rs_interrupt(). They were separated out for readability's sake.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off. People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible. After you are done making modifications, it is not a bad
- * idea to do:
- *
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * - Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-
-
-static inline void receive_char_pio(struct rs_port *port)
-{
- struct tty_struct *tty = port->gs.tty;
- unsigned char ch;
- int counter = 2048;
-
- /* While there are characters, get them ... */
- while (counter>0) {
- // printk("R%08x", (int)port->base[UART_R39XX_CTRL1]);
- if (!(port->base[UART_R39XX_CTRL1] & UART_RX_HOLD_FULL)) {
- break;
- }
- ch = serial_in(port, UART_R39XX_DATA);
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- *tty->flip.char_buf_ptr++ = ch;
- *tty->flip.flag_buf_ptr++ = 0;
- tty->flip.count++;
- }
- udelay(1); /* Allow things to happen - it take a while */
- counter--;
- }
- if (!counter)
- printk( "Ugh, looped in receive_char_pio!\n" );
-
- tty_flip_buffer_push(tty);
-#if 0
- /* Now handle error conditions */
- if (*status & (INTTYPE(UART_RXOVERRUN_INT) |
- INTTYPE(UART_FRAMEERR_INT) |
- INTTYPE(UART_PARITYERR_INT) |
- INTTYPE(UART_BREAK_INT))) {
-
- /*
- * Now check to see if character should be
- * ignored, and mask off conditions which
- * should be ignored.
- */
- if (*status & port->ignore_status_mask) {
- goto ignore_char;
- }
- *status &= port->read_status_mask;
-
- if (*status & INTTYPE(UART_BREAK_INT)) {
- rs_dprintk(RS_DEBUG_INTERRUPTS, "handling break....");
- *tty->flip.flag_buf_ptr = TTY_BREAK;
- }
- else if (*status & INTTYPE(UART_PARITYERR_INT)) {
- *tty->flip.flag_buf_ptr = TTY_PARITY;
- }
- else if (*status & INTTYPE(UART_FRAMEERR_INT)) {
- *tty->flip.flag_buf_ptr = TTY_FRAME;
- }
- if (*status & INTTYPE(UART_RXOVERRUN_INT)) {
- /*
- * Overrun is special, since it's
- * reported immediately, and doesn't
- * affect the current character
- */
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- tty->flip.count++;
- tty->flip.flag_buf_ptr++;
- tty->flip.char_buf_ptr++;
- *tty->flip.flag_buf_ptr = TTY_OVERRUN;
- }
- }
- }
-
- tty->flip.flag_buf_ptr++;
- tty->flip.char_buf_ptr++;
- tty->flip.count++;
-
- ignore_char:
-
- tty_flip_buffer_push(tty);
-#endif
-}
-
-static inline void transmit_char_pio(struct rs_port *port)
-{
- /* While I'm able to transmit ... */
- for (;;) {
- // printk("T%08x", (int)port->base[UART_R39XX_CTRL1]);
- if (!(port->base[UART_R39XX_CTRL1] & UART_TX_EMPTY)) {
- break;
- }
- else if (port->x_char) {
- serial_out(port, UART_R39XX_DATA, port->x_char);
- port->icount.tx++;
- port->x_char = 0;
- }
- else if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
- port->gs.tty->hw_stopped) {
- break;
- }
- else {
- serial_out(port, UART_R39XX_DATA, port->gs.xmit_buf[port->gs.xmit_tail++]);
- port->icount.tx++;
- port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
- if (--port->gs.xmit_cnt <= 0) {
- break;
- }
- }
- udelay(10); /* Allow things to happen - it take a while */
- }
-
- if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
- port->gs.tty->hw_stopped) {
- rs_disable_tx_interrupts(port);
- }
-
- if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
- if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- port->gs.tty->ldisc.write_wakeup)
- (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
- rs_dprintk (RS_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
- port->gs.wakeup_chars);
- wake_up_interruptible(&port->gs.tty->write_wait);
- }
-}
-
-
-
-static inline void check_modem_status(struct rs_port *port)
-{
- /* We don't have a carrier detect line - but just respond
- like we had one anyways so that open() becomes unblocked */
- wake_up_interruptible(&port->gs.open_wait);
-}
-
-int count = 0;
-
-/*
- * This is the serial driver's interrupt routine (inlined, because
- * there are two different versions of this, one for each serial port,
- * differing only by the bits used in interrupt status 2 register)
- */
-
-static inline void rs_rx_interrupt(int irq, void *dev_id,
- struct pt_regs * regs, int intshift)
-{
- struct rs_port * port;
- unsigned long int2status;
- unsigned long flags;
- unsigned long ints;
-
- save_and_cli(flags);
-
- port = (struct rs_port *)dev_id;
- /* rs_dprintk (RS_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift); */
-
- /* Get the interrrupts we have enabled */
- int2status = IntStatus2 & IntEnable2;
-
- /* Get interrupts in easy to use form */
- ints = int2status >> intshift;
- // printk("IR%03x%03x", (int)(IntStatus2 >> intshift), (int)(IntEnable2 >> intshift));
-
- /* Clear any interrupts we might be about to handle */
- IntClear2 = int2status & (
- (INTTYPE(UART_RXOVERRUN_INT) |
- INTTYPE(UART_FRAMEERR_INT) |
- INTTYPE(UART_BREAK_INT) |
- INTTYPE(UART_PARITYERR_INT) |
- INTTYPE(UART_RX_INT)) << intshift);
-
- if (!port || !port->gs.tty) {
- restore_flags(flags);
- return;
- }
-
- /* RX Receiver Holding Register Overrun */
- if (ints & INTTYPE(UART_RXOVERRUN_INT)) {
- rs_dprintk (RS_DEBUG_INTERRUPTS, "overrun");
- port->icount.overrun++;
- }
-
- /* RX Frame Error */
- if (ints & INTTYPE(UART_FRAMEERR_INT)) {
- rs_dprintk (RS_DEBUG_INTERRUPTS, "frame error");
- port->icount.frame++;
- }
-
- /* Break signal received */
- if (ints & INTTYPE(UART_BREAK_INT)) {
- rs_dprintk (RS_DEBUG_INTERRUPTS, "break");
- port->icount.brk++;
- }
-
- /* RX Parity Error */
- if (ints & INTTYPE(UART_PARITYERR_INT)) {
- rs_dprintk (RS_DEBUG_INTERRUPTS, "parity error");
- port->icount.parity++;
- }
-
- /* Receive byte (non-DMA) */
- if (ints & INTTYPE(UART_RX_INT)) {
- receive_char_pio(port);
- }
-
- /*
- check_modem_status();
- */
-
- // printk("OR%03x", (int)((IntStatus2 & IntEnable2) >> intshift));
-
- restore_flags(flags);
-
-/* rs_dprintk (RS_DEBUG_INTERRUPTS, "end.\n"); */
-
-}
-
-static inline void rs_tx_interrupt(int irq, void *dev_id,
- struct pt_regs * regs, int intshift)
-{
- struct rs_port * port;
- unsigned long int2status;
- unsigned long flags;
- unsigned long ints;
-
- save_and_cli(flags);
-
- port = (struct rs_port *)dev_id;
- /* rs_dprintk (RS_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift); */
-
- /* Get the interrrupts we have enabled */
- int2status = IntStatus2 & IntEnable2;
-
- if (!port || !port->gs.tty) {
- restore_flags(flags);
- return;
- }
-
- /* Get interrupts in easy to use form */
- ints = int2status >> intshift;
-
- /* Clear any interrupts we might be about to handle */
- IntClear2 = int2status & (
- (INTTYPE(UART_TX_INT) |
- INTTYPE(UART_EMPTY_INT) |
- INTTYPE(UART_TXOVERRUN_INT)) << intshift);
-
- //printk("IT%03x", (int)ints);
-
- /* TX holding register empty, so transmit byte (non-DMA) */
- if (ints & (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT))) {
- transmit_char_pio(port);
- }
-
- /* TX Transmit Holding Register Overrun (shouldn't happen) */
- if (ints & INTTYPE(UART_TXOVERRUN_INT)) {
- printk ( "rs: TX overrun\n");
- }
-
- /*
- check_modem_status();
- */
-
- restore_flags(flags);
-
-/* rs_dprintk (RS_DEBUG_INTERRUPTS, "end.\n"); */
-
-}
-
-static void rs_rx_interrupt_uarta(int irq, void *dev_id,
- struct pt_regs * regs)
-{
- rs_rx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
-}
-
-static void rs_tx_interrupt_uarta(int irq, void *dev_id,
- struct pt_regs * regs)
-{
- rs_tx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
-}
-
-#if 0
-static void rs_interrupt_uartb(int irq, void *dev_id,
- struct pt_regs * regs)
-{
- rs_interrupt(irq, dev_id, regs, UARTB_SHIFT);
-}
-#endif
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-
-
-
-
-/* ********************************************************************** *
- * Here are the routines that actually *
- * interface with the generic_serial driver *
- * ********************************************************************** */
-
-static void rs_disable_tx_interrupts (void * ptr)
-{
- struct rs_port *port = ptr;
- unsigned long flags;
-
- save_and_cli(flags);
- port->gs.flags &= ~GS_TX_INTEN;
-
- IntEnable2 &= ~((INTTYPE(UART_TX_INT) |
- INTTYPE(UART_EMPTY_INT) |
- INTTYPE(UART_TXOVERRUN_INT)) << port->intshift);
-
- IntClear2 = (INTTYPE(UART_TX_INT) |
- INTTYPE(UART_EMPTY_INT) |
- INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
-
- restore_flags(flags);
-}
-
-
-static void rs_enable_tx_interrupts (void * ptr)
-{
- struct rs_port *port = ptr;
- unsigned long flags;
-
- save_and_cli(flags);
-
- IntClear2 = (INTTYPE(UART_TX_INT) |
- INTTYPE(UART_EMPTY_INT) |
- INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
-
- IntEnable2 |= (INTTYPE(UART_TX_INT) |
- INTTYPE(UART_EMPTY_INT) |
- INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
-
- /* Send a char to start TX interrupts happening */
- transmit_char_pio(port);
-
- restore_flags(flags);
-}
-
-
-static void rs_disable_rx_interrupts (void * ptr)
-{
- struct rs_port *port = ptr;
- unsigned long flags;
-
- save_and_cli(flags);
-
- IntEnable2 &= ~((INTTYPE(UART_RX_INT) |
- INTTYPE(UART_RXOVERRUN_INT) |
- INTTYPE(UART_FRAMEERR_INT) |
- INTTYPE(UART_BREAK_INT) |
- INTTYPE(UART_PARITYERR_INT)) << port->intshift);
-
- IntClear2 = (INTTYPE(UART_RX_INT) |
- INTTYPE(UART_RXOVERRUN_INT) |
- INTTYPE(UART_FRAMEERR_INT) |
- INTTYPE(UART_BREAK_INT) |
- INTTYPE(UART_PARITYERR_INT)) << port->intshift;
-
- restore_flags(flags);
-}
-
-static void rs_enable_rx_interrupts (void * ptr)
-{
- struct rs_port *port = ptr;
- unsigned long flags;
-
- save_and_cli(flags);
-
- IntEnable2 |= (INTTYPE(UART_RX_INT) |
- INTTYPE(UART_RXOVERRUN_INT) |
- INTTYPE(UART_FRAMEERR_INT) |
- INTTYPE(UART_BREAK_INT) |
- INTTYPE(UART_PARITYERR_INT)) << port->intshift;
-
- /* Empty the input buffer - apparently this is *vital* */
- while (port->base[UART_R39XX_CTRL1] & UART_RX_HOLD_FULL) {
- serial_in(port, UART_R39XX_DATA);
- }
-
- IntClear2 = (INTTYPE(UART_RX_INT) |
- INTTYPE(UART_RXOVERRUN_INT) |
- INTTYPE(UART_FRAMEERR_INT) |
- INTTYPE(UART_BREAK_INT) |
- INTTYPE(UART_PARITYERR_INT)) << port->intshift;
-
- restore_flags(flags);
-}
-
-
-static int rs_get_CD (void * ptr)
-{
- struct rs_port *port = ptr;
- func_enter2();
-
- /* No Carried Detect in Hardware - just return true */
-
- func_exit();
- return (1);
-}
-
-
-
-
-static void rs_shutdown_port (void * ptr)
-{
- struct rs_port *port = ptr;
-
- func_enter();
-
- port->gs.flags &= ~ GS_ACTIVE;
-
- /* Jim: Disable interrupts and power down port? */
-
- func_exit();
-}
-
-
-
-static int rs_set_real_termios (void *ptr)
-{
- struct rs_port *port = ptr;
- int t;
-
- func_enter2();
-
- switch (port->gs.baud) {
- /* Save some typing work... */
-#define e(x) case x:t= SER_BAUD_ ## x ; break
- e(300);e(600);e(1200);e(2400);e(4800);e(9600);
- e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
- case 0 :t = -1;
- break;
- default:
- /* Can I return "invalid"? */
- t = SER_BAUD_9600;
- printk (KERN_INFO "rs: unsupported baud rate: %d.\n", port->gs.baud);
- break;
- }
-#undef e
- if (t >= 0) {
- /* Jim: Set Hardware Baud rate - there is some good
- code in drivers/char/serial.c */
-
- /* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
- UartA_Ctrl1 &= 0xf000000f;
- UartA_Ctrl1 &= ~(UART_DIS_TXD | SER_SEVEN_BIT | SER_EVEN_PARITY | SER_TWO_STOP);
-
-#define CFLAG port->gs.tty->termios->c_cflag
- if (C_PARENB(port->gs.tty))
- if (!C_PARODD(port->gs.tty))
- UartA_Ctrl1 |= SER_EVEN_PARITY;
- else
- UartA_Ctrl1 |= SER_ODD_PARITY;
- if ((CFLAG & CSIZE)==CS6)
- printk(KERN_ERR "6 bits not supported\n");
- if ((CFLAG & CSIZE)==CS5)
- printk(KERN_ERR "5 bits not supported\n");
- if ((CFLAG & CSIZE)==CS7)
- UartA_Ctrl1 |= SER_SEVEN_BIT;
- if (C_CSTOPB(port->gs.tty))
- UartA_Ctrl1 |= SER_TWO_STOP;
-
- UartA_Ctrl2 = t;
- UartA_DMActl1 = 0;
- UartA_DMActl2 = 0;
- UartA_Ctrl1 |= UART_ON;
- }
-
- /* Jim: Lots of good stuff in drivers/char/serial.c:change_speed() */
-
- func_exit ();
- return 0;
-}
-
-
-static int rs_chars_in_buffer (void * ptr)
-{
- struct rs_port *port = ptr;
- int scratch;
-/* func_enter2(); */
-
- scratch = serial_in(port, UART_R39XX_CTRL1);
-
-/* func_exit(); */
- return ( (scratch & UART_TX_EMPTY) ? 0 : 1 );
-}
-
-
-
-/* ********************************************************************** *
- * Here are the routines that actually *
- * interface with the rest of the system *
- * ********************************************************************** */
-
-
-static int rs_open (struct tty_struct * tty, struct file * filp)
-{
- struct rs_port *port;
- int retval, line;
-
- func_enter();
-
- if (!rs_initialized) {
- return -EIO;
- }
-
- line = MINOR(tty->device) - tty->driver.minor_start;
- rs_dprintk (RS_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p)\n",
- (int) current->pid, line, tty, current->tty);
-
- if ((line < 0) || (line >= RS_NPORTS))
- return -ENODEV;
-
- /* Pre-initialized already */
- port = & rs_ports[line];
-
- rs_dprintk (RS_DEBUG_OPEN, "port = %p\n", port);
-
- tty->driver_data = port;
- port->gs.tty = tty;
- port->gs.count++;
-
- rs_dprintk (RS_DEBUG_OPEN, "starting port\n");
-
- /*
- * Start up serial port
- */
- retval = gs_init_port(&port->gs);
- rs_dprintk (RS_DEBUG_OPEN, "done gs_init\n");
- if (retval) {
- port->gs.count--;
- return retval;
- }
-
- port->gs.flags |= GS_ACTIVE;
-
- rs_dprintk (RS_DEBUG_OPEN, "before inc_use_count (count=%d.\n",
- port->gs.count);
- if (port->gs.count == 1) {
- MOD_INC_USE_COUNT;
- }
- rs_dprintk (RS_DEBUG_OPEN, "after inc_use_count\n");
-
- /* Jim: Initialize port hardware here */
-
- /* Enable high-priority interrupts for UARTA */
- IntEnable6 |= INT6_UARTARXINT;
- rs_enable_rx_interrupts(&rs_ports[0]);
-
- retval = gs_block_til_ready(&port->gs, filp);
- rs_dprintk (RS_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n",
- retval, port->gs.count);
-
- if (retval) {
- MOD_DEC_USE_COUNT;
- port->gs.count--;
- return retval;
- }
- /* tty->low_latency = 1; */
-
- if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
- if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
- *tty->termios = port->gs.normal_termios;
- else
- *tty->termios = port->gs.callout_termios;
- rs_set_real_termios (port);
- }
-
- port->gs.session = current->session;
- port->gs.pgrp = current->pgrp;
- func_exit();
-
- /* Jim */
-/* cli(); */
-
- return 0;
-
-}
-
-
-
-static void rs_close (void *ptr)
-{
- func_enter ();
-
- /* Anything to do here? */
-
- MOD_DEC_USE_COUNT;
- func_exit ();
-}
-
-
-/* I haven't the foggiest why the decrement use count has to happen
- here. The whole linux serial drivers stuff needs to be redesigned.
- My guess is that this is a hack to minimize the impact of a bug
- elsewhere. Thinking about it some more. (try it sometime) Try
- running minicom on a serial port that is driven by a modularized
- driver. Have the modem hangup. Then remove the driver module. Then
- exit minicom. I expect an "oops". -- REW */
-static void rs_hungup (void *ptr)
-{
- func_enter ();
- MOD_DEC_USE_COUNT;
- func_exit ();
-}
-
-static int rs_ioctl (struct tty_struct * tty, struct file * filp,
- unsigned int cmd, unsigned long arg)
-{
- int rc;
- struct rs_port *port = tty->driver_data;
- int ival;
-
- /* func_enter2(); */
-
- rc = 0;
- switch (cmd) {
- case TIOCGSOFTCAR:
- rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
- (unsigned int *) arg);
- break;
- case TIOCSSOFTCAR:
- if ((rc = verify_area(VERIFY_READ, (void *) arg,
- sizeof(int))) == 0) {
- get_user(ival, (unsigned int *) arg);
- tty->termios->c_cflag =
- (tty->termios->c_cflag & ~CLOCAL) |
- (ival ? CLOCAL : 0);
- }
- break;
- case TIOCGSERIAL:
- if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
- sizeof(struct serial_struct))) == 0)
- gs_getserial(&port->gs, (struct serial_struct *) arg);
- break;
- case TIOCSSERIAL:
- if ((rc = verify_area(VERIFY_READ, (void *) arg,
- sizeof(struct serial_struct))) == 0)
- rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
- break;
- default:
- rc = -ENOIOCTLCMD;
- break;
- }
-
- /* func_exit(); */
- return rc;
-}
-
-
-/*
- * This function is used to send a high-priority XON/XOFF character to
- * the device
- */
-static void rs_send_xchar(struct tty_struct * tty, char ch)
-{
- struct rs_port *port = (struct rs_port *)tty->driver_data;
- func_enter ();
-
- port->x_char = ch;
- if (ch) {
- /* Make sure transmit interrupts are on */
- rs_enable_tx_interrupts(tty);
- }
-
- func_exit();
-}
-
-
-/*
- * ------------------------------------------------------------
- * rs_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void rs_throttle(struct tty_struct * tty)
-{
-#ifdef RS_DEBUG_THROTTLE
- char buf[64];
-
- printk("throttle %s: %d....\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
-#endif
-
- func_enter ();
-
- if (I_IXOFF(tty))
- rs_send_xchar(tty, STOP_CHAR(tty));
-
- func_exit ();
-}
-
-static void rs_unthrottle(struct tty_struct * tty)
-{
- struct rs_port *port = (struct rs_port *)tty->driver_data;
-#ifdef RS_DEBUG_THROTTLE
- char buf[64];
-
- printk("unthrottle %s: %d....\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
-#endif
-
- func_enter();
-
- if (I_IXOFF(tty)) {
- if (port->x_char)
- port->x_char = 0;
- else
- rs_send_xchar(tty, START_CHAR(tty));
- }
-
- func_exit();
-}
-
-
-
-
-
-/* ********************************************************************** *
- * Here are the initialization routines. *
- * ********************************************************************** */
-
-void * ckmalloc (int size)
-{
- void *p;
-
- p = kmalloc(size, GFP_KERNEL);
- if (p)
- memset(p, 0, size);
- return p;
-}
-
-
-
-static int rs_init_portstructs(void)
-{
- struct rs_port *port;
- int i;
-
- func_enter();
-
- /* Many drivers statically allocate the maximum number of ports
- There is no reason not to allocate them dynamically. Is there? -- REW */
- rs_ports = ckmalloc(RS_NPORTS * sizeof (struct rs_port));
- if (!rs_ports)
- return -ENOMEM;
-
- rs_termios = ckmalloc(RS_NPORTS * sizeof (struct termios *));
- if (!rs_termios) {
- kfree (rs_ports);
- return -ENOMEM;
- }
-
- rs_termios_locked = ckmalloc(RS_NPORTS * sizeof (struct termios *));
- if (!rs_termios_locked) {
- kfree (rs_ports);
- kfree (rs_termios);
- return -ENOMEM;
- }
-
- /* Adjust the values in the "driver" */
- rs_driver.termios = rs_termios;
- rs_driver.termios_locked = rs_termios_locked;
-
- port = rs_ports;
- for (i=0; i < RS_NPORTS;i++) {
- rs_dprintk (RS_DEBUG_INIT, "initing port %d\n", i);
- port->gs.callout_termios = tty_std_termios;
- port->gs.normal_termios = tty_std_termios;
- port->gs.magic = SERIAL_MAGIC;
- port->gs.close_delay = HZ/2;
- port->gs.closing_wait = 30 * HZ;
- port->gs.rd = &rs_real_driver;
-#ifdef NEW_WRITE_LOCKING
- port->gs.port_write_sem = MUTEX;
-#endif
-#ifdef DECLARE_WAITQUEUE
- init_waitqueue_head(&port->gs.open_wait);
- init_waitqueue_head(&port->gs.close_wait);
-#endif
- port->base = (i == 0) ? (unsigned long *) &UartA_Ctrl1 :
- (unsigned long *) &UartB_Ctrl1;
- port->intshift = (i == 0) ? UARTA_SHIFT : UARTB_SHIFT;
- rs_dprintk (RS_DEBUG_INIT, "base %p intshift %d\n",
- port->base, port->intshift);
- port++;
- }
-
- func_exit();
- return 0;
-}
-
-static int rs_init_drivers(void)
-{
- int error;
-
- func_enter();
-
- memset(&rs_driver, 0, sizeof(rs_driver));
- rs_driver.magic = TTY_DRIVER_MAGIC;
- rs_driver.driver_name = "serial";
- rs_driver.name = "ttyS";
- rs_driver.major = TTY_MAJOR;
- rs_driver.minor_start = 64;
- rs_driver.num = RS_NPORTS;
- rs_driver.type = TTY_DRIVER_TYPE_SERIAL;
- rs_driver.subtype = SERIAL_TYPE_NORMAL;
- rs_driver.init_termios = tty_std_termios;
- rs_driver.init_termios.c_cflag =
- //B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- B115200 | CS8 | CREAD | HUPCL | CLOCAL;
- rs_driver.flags = TTY_DRIVER_REAL_RAW;
- rs_driver.refcount = &rs_refcount;
- rs_driver.table = rs_table;
- rs_driver.termios = rs_termios;
- rs_driver.termios_locked = rs_termios_locked;
-
- rs_driver.open = rs_open;
- rs_driver.close = gs_close;
- rs_driver.write = gs_write;
- rs_driver.put_char = gs_put_char;
- rs_driver.flush_chars = gs_flush_chars;
- rs_driver.write_room = gs_write_room;
- rs_driver.chars_in_buffer = gs_chars_in_buffer;
- rs_driver.flush_buffer = gs_flush_buffer;
- rs_driver.ioctl = rs_ioctl;
- rs_driver.throttle = rs_throttle;
- rs_driver.unthrottle = rs_unthrottle;
- rs_driver.set_termios = gs_set_termios;
- rs_driver.stop = gs_stop;
- rs_driver.start = gs_start;
- rs_driver.hangup = gs_hangup;
-
- rs_callout_driver = rs_driver;
- rs_callout_driver.name = "cua";
- rs_callout_driver.major = TTYAUX_MAJOR;
- rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-
- if ((error = tty_register_driver(&rs_driver))) {
- printk(KERN_ERR "Couldn't register serial driver, error = %d\n",
- error);
- return 1;
- }
- if ((error = tty_register_driver(&rs_callout_driver))) {
- tty_unregister_driver(&rs_driver);
- printk(KERN_ERR "Couldn't register callout driver, error = %d\n",
- error);
- return 1;
- }
-
- func_exit();
- return 0;
-}
-
-
-static void rs_release_drivers(void)
-{
- func_enter();
- tty_unregister_driver(&rs_driver);
- tty_unregister_driver(&rs_callout_driver);
-#ifdef CONFIG_PM
- pm_unregister(pmdev);
-#endif
- func_exit();
-}
-
-#if defined(CONFIG_VTECH_HELIO) && defined(CONFIG_PM)
-static
-int pm_request(struct pm_dev* dev, pm_request_t req, void* data)
-{
- static unsigned long ctrlA;
- static unsigned long ctrlB;
- static unsigned long clk;
- static unsigned long out;
-
- switch (req) {
- case PM_SUSPEND:
- /* disable both uarts */
- ctrlA = UartA_Ctrl1 & (UART_ENABLE | UART_DIS_TXD);
- UartA_Ctrl1 &= ~UART_ENABLE;
-#if 0 /* would be nice if this worked, but it hangs the suspend process for me - 20001030 nop */
- while (UartA_Ctrl1 & UART_ON)
- /*wait till its empty */;
-#endif
- UartA_Ctrl1 |= UART_DIS_TXD;
- ctrlB = UartB_Ctrl1 & (UART_ENABLE | UART_DIS_TXD);
- UartB_Ctrl1 &= ~UART_ENABLE;
-#if 0 /* would be nice if this worked */
- while (UartB_Ctrl1 & UART_ON)
- /*wait till its empty */;
-#endif
- UartB_Ctrl1 |= UART_DIS_TXD;
-
- /* turn the clocks off */
- clk = ClockControl & (CLK_EN_UART_A | CLK_EN_UART_B);
- ClockControl &= ~(CLK_EN_UART_A | CLK_EN_UART_B);
-
- /* remember the state of these pins */
- out = MFIOOutput & (MFIO_PIN_UART_TX_ENABLE |
- MFIO_PIN_UART_RX_DISABLE |
- MFIO_PIN_MODEM_RTS);
-
- MFIOOutput &= ~MFIO_PIN_UART_TX_ENABLE;
- MFIOOutput |= (MFIO_PIN_UART_RX_DISABLE | /* Set High (Disable RX) */
- MFIO_PIN_MODEM_RTS);
- break;
-
- case PM_RESUME:
-
- /* restore the driver pin state */
- MFIOOutput = (MFIOOutput & ~(MFIO_PIN_UART_TX_ENABLE |
- MFIO_PIN_UART_RX_DISABLE |
- MFIO_PIN_MODEM_RTS)) | out;
-
- /* restore the clock */
- ClockControl = (ClockControl & ~(CLK_EN_UART_A | CLK_EN_UART_B)) | clk;
-
- /* restore the Uart state */
- UartA_Ctrl1 = (UartA_Ctrl1 & ~(UART_ENABLE | UART_DIS_TXD))
- | ctrlA;
- UartB_Ctrl1 = (UartB_Ctrl1 & ~(UART_ENABLE | UART_DIS_TXD))
- | ctrlB;
- break;
- }
- return 0;
-}
-#endif
-
-
-int __init rs_init(void)
-{
- int rc;
-
- func_enter();
- rs_dprintk (RS_DEBUG_INIT, "Initing serial module... (rs_debug=%d)\n", rs_debug);
-
- if (abs ((long) (&rs_debug) - rs_debug) < 0x10000) {
- printk (KERN_WARNING "rs: rs_debug is an address, instead of a value. "
- "Assuming -1.\n");
- printk ("(%p)\n", &rs_debug);
- rs_debug=-1;
- }
-
- rc = rs_init_portstructs ();
- rs_init_drivers ();
- if (request_irq(2, rs_tx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
- "serial", &rs_ports[0])) {
- printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
- rc = 0;
- }
- if (request_irq(3, rs_rx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
- "serial", &rs_ports[0])) {
- printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
- rc = 0;
- }
-
- IntEnable6 |= INT6_UARTARXINT;
- rs_enable_rx_interrupts(&rs_ports[0]);
-
-#ifndef CONFIG_SERIAL_CONSOLE
- printk( "Initializing uart...\n" );
- earlyInitUartPR31700();
- printk( "okay\n" );
-#endif
-
- /* Note: I didn't do anything to enable the second UART */
-
- if (rc >= 0)
- rs_initialized++;
-
- func_exit();
- return 0;
-}
-
-
-void rs_exit(void)
-{
- func_enter();
- rs_dprintk (RS_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", rs_initialized);
- if (rs_initialized)
- rs_release_drivers ();
-
- kfree (rs_ports);
- kfree (rs_termios);
- kfree (rs_termios_locked);
- func_exit();
-
-}
-
-module_init(rs_init);
-module_exit(rs_exit);
-
-
-#ifdef DEBUG
-void my_hd (unsigned char *addr, int len)
-{
- int i, j, ch;
-
- for (i=0;i<len;i+=16) {
- printk ("%08x ", (int) addr+i);
- for (j=0;j<16;j++) {
- printk ("%02x %s", addr[j+i], (j==7)?" ":"");
- }
- for (j=0;j<16;j++) {
- ch = addr[j+i];
- printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
- }
- printk ("\n");
- }
-}
-#endif
-
-
-
-
-/*
- *
- * Very simple routines to get UART humming...
- *
- */
-
-/* not static, its called from prom_init() too */
-void earlyInitUartPR31700(void)
-{
- /* Setup master clock for UART */
- ClockControl &= ~CLK_SIBMCLKDIV_MASK;
- ClockControl |= CLK_SIBMCLKDIR | CLK_ENSIBMCLK |
- ((2 << CLK_SIBMCLKDIV_SHIFT) & CLK_SIBMCLKDIV_MASK) |
- CLK_CSERSEL;
-
- /* Configure UARTA clock */
- ClockControl |= ((3 << CLK_CSERDIV_SHIFT) & CLK_CSERDIV_MASK) |
- CLK_ENCSERCLK | CLK_EN_UART_A;
-
- /* Setup UARTA for 115200 baud, 8N1 */
- UartA_Ctrl1 &= 0xf000000f;
- UartA_Ctrl1 &= ~UART_DIS_TXD; /* turn on txd */
- UartA_Ctrl1 &= ~SER_SEVEN_BIT; /* use 8-bit data */
- UartA_Ctrl1 &= ~SER_EVEN_PARITY; /* no parity */
- UartA_Ctrl1 &= ~SER_TWO_STOP; /* 1 stop bit */
- UartA_Ctrl2 = SER_BAUD_115200;
- UartA_DMActl1 = 0; /* No DMA */
- UartA_DMActl2 = 0; /* No DMA */
- UartA_Ctrl1 |= UART_ON; /* Turn UART on */
-
- while (~UartA_Ctrl1 & UART_ON);
-}
-
-void serial_outc(unsigned char c)
-{
- int i;
- unsigned long int2;
- #define BUSY_WAIT 10000
-
- /*
- * Turn UART A Interrupts off
- */
- int2 = IntEnable2;
- IntEnable2 &=
- ~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
-
- /*
- * The UART_TX_EMPTY bit in UartA_Ctrl1 seems
- * not to be very reliable :-(
- *
- * Wait for the Tx register to become empty
- */
- for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
-
- IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
-
- UartA_Data = c;
- for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
- IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
-
- IntEnable2 = int2;
-}
-
-void serial_console_read_raw(struct console *co, char *buf, int size)
-{
- int i;
- unsigned int int2, flags;
-
- save_and_cli(flags);
-
- int2 = IntEnable2;
- IntEnable2 = 0;
-
- for (i=0; i<size; i++) {
- while (!(UartA_Ctrl1 & UART_RX_HOLD_FULL))
- ;
- buf[i] = UartA_Data;
- udelay(10); /* Allow things to happen - it take a while */
- }
- IntEnable2 = int2;
- restore_flags(flags);
-}
-
-int serial_console_wait_key(struct console *co)
-{
- unsigned int int2, res;
-
- int2 = IntEnable2;
- IntEnable2 = 0;
-
- while (!(UartA_Ctrl1 & UART_RX_HOLD_FULL))
- ;
- res = UartA_Data;
- udelay(10); /* Allow things to happen - it take a while */
-
- IntEnable2 = int2;
- return res;
-}
-
-/* used in slip? in Slip??? SLIP /ought/ to work with sl->tty! (PM2000) */
-void serial_console_write_raw(struct console *co, const char *s,
- unsigned count)
-{
- unsigned int i;
-
- for (i = 0; i < count; i++) {
- serial_outc(*s++);
- }
-}
-
-#ifdef CONFIG_SERIAL_CONSOLE
-
-void serial_console_write(struct console *co, const char *s,
- unsigned count)
-{
- unsigned int i;
-
- for (i = 0; i < count; i++) {
- if (*s == '\n')
- serial_outc('\r');
- serial_outc(*s++);
- }
-}
-
-static kdev_t serial_console_device(struct console *c)
-{
- return MKDEV(TTY_MAJOR, 64 + c->index);
-}
-
-static __init int serial_console_setup(struct console *co, char *options)
-{
- earlyInitUartPR31700();
-
- return 0;
-}
-
-
-static struct console sercons = {
- name: "ttyS",
- write: serial_console_write,
- device: serial_console_device,
- wait_key: serial_console_wait_key,
- setup: serial_console_setup,
- flags: CON_PRINTBUFFER,
- index: -1
-};
-
-/*
- * Register console.
- */
-
-void __init serial_console_init(void)
-{
- register_console(&sercons);
-}
-
-#endif
diff --git a/arch/mips/philips/drivers/uart-pr31700.h b/arch/mips/philips/drivers/uart-pr31700.h
deleted file mode 100644
index 221baa89f..000000000
--- a/arch/mips/philips/drivers/uart-pr31700.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Serial driver for r39xx
- *
- * Copyright (C) 2000 Jim Pick <jim@jimpick.com>
- *
- * Inspired by, and/or includes bits from:
- *
- * drivers/char/serial.c (standard serial driver)
- * drivers/char/sx.c (use of generic_serial interface)
- * drivers/char/esp.c (another UART that uses DMA)
- * arch/mips/vr41xx/serial.c (another MIPS serial driver)
- *
- * Please see those files for credits.
- *
- * Also, the original rough serial console code was:
- *
- * Copyright (C) 1999 Harald Koerfgen
- *
- * $Id: r39xx_serial.h,v 1.3 2000/11/01 03:02:27 nop Exp $
- */
-
-#include <linux/serial.h>
-#include <linux/generic_serial.h>
-
-
-/* r39xx UART Register Offsets */
-#define UART_R39XX_CTRL1 0
-#define UART_R39XX_CTRL2 1
-#define UART_R39XX_DMACTRL1 2
-#define UART_R39XX_DMACTRL2 3
-#define UART_R39XX_DMACNT 4
-#define UART_R39XX_DATA 5
-
-/* UART Interrupt (Interrupt 2) bits (UARTA,UARTB) */
-#define UART_RX_INT 9 /* receiver holding register full (31, 21) */
-#define UART_RXOVERRUN_INT 8 /* receiver overrun error (30, 20) */
-#define UART_FRAMEERR_INT 7 /* receiver frame error (29, 19) */
-#define UART_BREAK_INT 6 /* received break signal (28, 18) */
-#define UART_PARITYERR_INT 5 /* receiver parity error (27, 17) */
-#define UART_TX_INT 4 /* transmit holding register empty (26, 16) */
-#define UART_TXOVERRUN_INT 3 /* transmit overrun error (25, 15) */
-#define UART_EMPTY_INT 2 /* both trans/recv regs empty (24, 14) */
-#define UART_DMAFULL_INT 1 /* DMA at end of buffer (23, 13) */
-#define UART_DMAHALF_INT 0 /* DMA halfway through buffer */ (22, 12) */
-
-#define UARTA_SHIFT 22
-#define UARTB_SHIFT 12
-
-#define INT2BIT(interrupttype, intshift) (1 << (interrupttype + intshift))
-#define INTTYPE(interrupttype) (1 << interrupttype)
-
-/* Driver status flags */
-#define RS_STAT_RX_TIMEOUT 0x01
-#define RS_STAT_DMA_RX 0x02
-#define RS_STAT_DMA_TX 0x04
-#define RS_STAT_NEVER_DMA 0x08
-#define RS_STAT_USE_PIO 0x10
-
-/*
- This driver can spew a whole lot of debugging output at you. If you
- need maximum performance, you should disable the DEBUG define. To
- aid in debugging in the field, I'm leaving the compile-time debug
- features enabled, and disable them "runtime". That allows me to
- instruct people with problems to enable debugging without requiring
- them to recompile...
-*/
-#define DEBUG
-
-
-#ifdef DEBUG
-#define rs_dprintk(f, str...) if (rs_debug & f) printk (str)
-#else
-#define rs_dprintk(f, str...) /* nothing */
-#endif
-
-
-
-#define func_enter() rs_dprintk (RS_DEBUG_FLOW, "rs: enter " __FUNCTION__ "\n")
-#define func_exit() rs_dprintk (RS_DEBUG_FLOW, "rs: exit " __FUNCTION__ "\n")
-
-#define func_enter2() rs_dprintk (RS_DEBUG_FLOW, "rs: enter " __FUNCTION__ \
- "(port %p, base %p)\n", port, port->base)
-
-
-/* Debug flags. Add these together to get more debug info. */
-
-#define RS_DEBUG_OPEN 0x00000001
-#define RS_DEBUG_SETTING 0x00000002
-#define RS_DEBUG_FLOW 0x00000004
-#define RS_DEBUG_MODEMSIGNALS 0x00000008
-#define RS_DEBUG_TERMIOS 0x00000010
-#define RS_DEBUG_TRANSMIT 0x00000020
-#define RS_DEBUG_RECEIVE 0x00000040
-#define RS_DEBUG_INTERRUPTS 0x00000080
-#define RS_DEBUG_PROBE 0x00000100
-#define RS_DEBUG_INIT 0x00000200
-#define RS_DEBUG_CLEANUP 0x00000400
-#define RS_DEBUG_CLOSE 0x00000800
-#define RS_DEBUG_FIRMWARE 0x00001000
-#define RS_DEBUG_MEMTEST 0x00002000
-#define RS_DEBUG_THROTTLE 0x00004000
-
-#define RS_DEBUG_ALL 0xffffffff
-
-
-#define RS_NPORTS 2
-
-struct rs_port {
- /* must be first field! */
- struct gs_port gs;
-
- /* rest is private for this driver */
- unsigned long *base;
- int intshift; /* for interrupt register */
- struct wait_queue *shutdown_wait;
- int stat_flags;
- struct async_icount icount; /* kernel counters for the 4
- input interrupts */
- int read_status_mask;
- int ignore_status_mask;
- int x_char; /* xon/xoff character */
-};
-
-
-
-#define SERIAL_MAGIC 0x5301
diff --git a/arch/mips/philips/nino/Makefile b/arch/mips/philips/nino/Makefile
index 7d31a66fb..bcdd9b2e3 100644
--- a/arch/mips/philips/nino/Makefile
+++ b/arch/mips/philips/nino/Makefile
@@ -17,10 +17,17 @@ all: nino.o
obj-y := int-handler.o setup.o irq.o time.o reset.o rtc.o prom.o power.o wbflush.o
-obj-$(CONFIG_BLK_DEV_INITRD) += ../boot/ramdisk.o
+int-handler.o: int-handler.S
obj-$(CONFIG_REMOTE_DEBUG) += kgdb.o
-int-handler.o: int-handler.S
+obj-$(CONFIG_BLK_DEV_INITRD) += ramdisk.o
+
+ramdisk.o:
+ $(MAKE) -C ramdisk
+ ln -sf ramdisk/ramdisk.o ramdisk.o
+
+clean:
+ rm -f *.o
include $(TOPDIR)/Rules.make
diff --git a/arch/mips/philips/nino/int-handler.S b/arch/mips/philips/nino/int-handler.S
index 90d7f8818..ff2e48e90 100644
--- a/arch/mips/philips/nino/int-handler.S
+++ b/arch/mips/philips/nino/int-handler.S
@@ -1,22 +1,21 @@
/*
* linux/arch/mips/philips/nino/int-handler.S
*
- * Copyright (C) 1999 Harald Koerfgen (Harald.Koerfgen@home.ivm.de)
+ * Copyright (C) 1999 Harald Koerfgen
* Copyright (C) 2000 Jim Pick (jim@jimpick.com)
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Interrupt handler for PR31700.
+ * Interrupt handler for Philips Nino.
*/
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
-#include <asm/philips/pr31700.h>
-
+#include <asm/tx3912.h>
.data
.globl HighPriVect
diff --git a/arch/mips/philips/nino/irq.c b/arch/mips/philips/nino/irq.c
index 71aba8599..3d7a88afe 100644
--- a/arch/mips/philips/nino/irq.c
+++ b/arch/mips/philips/nino/irq.c
@@ -2,15 +2,15 @@
* linux/arch/mips/philips/nino/irq.c
*
* Copyright (C) 1992 Linus Torvalds
- * Copyright (C) 1999 Harald Koerfgen (Harald.Koerfgen@home.ivm.de)
+ * Copyright (C) 1999 Harald Koerfgen
* Copyright (C) 2000 Pavel Machek (pavel@suse.cz)
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Generic interrupt handler for PR31700.
+ * Generic interrupt handler for Philips Nino.
*/
#include <linux/errno.h>
#include <linux/init.h>
@@ -30,7 +30,7 @@
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
-#include <asm/philips/pr31700.h>
+#include <asm/tx3912.h>
unsigned long spurious_count = 0;
@@ -45,10 +45,12 @@ static inline void mask_irq(unsigned int irq_nr)
IntEnable6 &= ~INT6_PERIODICINT;
break;
- case 3: /* Serial port receive interrupt */
+ case 3:
+ /* Serial port receive interrupt */
break;
- case 2: /* Serial port transmit interrupt */
+ case 2:
+ /* Serial port transmit interrupt */
break;
default:
@@ -63,12 +65,12 @@ static inline void unmask_irq(unsigned int irq_nr)
IntEnable6 |= INT6_PERIODICINT;
break;
- case 3: /* Serial port receive interrupt */
- /* FIXME: currently handled in driver */
+ case 3:
+ /* Serial port receive interrupt */
break;
- case 2: /* Serial port transmit interrupt */
- /* FIXME: currently handled in driver */
+ case 2:
+ /* Serial port transmit interrupt */
break;
default:
@@ -149,17 +151,24 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
struct irqaction *action;
int do_random, cpu;
+ if (irq == 20) {
+ if (IntStatus2 & 0xfffff00) {
+ if (IntStatus2 & 0x0f000000)
+ return do_IRQ(2, regs);
+ }
+ }
+
cpu = smp_processor_id();
irq_enter(cpu, irq);
kstat.irqs[cpu][irq]++;
if (irq == 20) {
- printk("20 %08lx %08lx\n %08lx %08lx\n %08lx\n",
- IntStatus1, IntStatus2, IntStatus3,
- IntStatus4, IntStatus5 );
- printk("20 %08lx %08lx\n %08lx %08lx\n %08lx\n",
- IntEnable1, IntEnable2, IntEnable3,
- IntEnable4, IntEnable5 );
+ printk("20 %08lx %08lx\n %08lx %08lx\n %08lx\n",
+ IntStatus1, IntStatus2, IntStatus3,
+ IntStatus4, IntStatus5 );
+ printk("20 %08lx %08lx\n %08lx %08lx\n %08lx\n",
+ IntEnable1, IntEnable2, IntEnable3,
+ IntEnable4, IntEnable5 );
}
@@ -179,6 +188,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
unmask_irq(irq);
__cli();
} else {
+ IntClear1 = ~0;
IntClear3 = ~0;
IntClear4 = ~0;
IntClear5 = ~0;
diff --git a/arch/mips/philips/nino/kgdb.c b/arch/mips/philips/nino/kgdb.c
index 0bb03e86f..0d3ebf23b 100644
--- a/arch/mips/philips/nino/kgdb.c
+++ b/arch/mips/philips/nino/kgdb.c
@@ -1,16 +1,16 @@
/*
* linux/arch/mips/philips/nino/kgdb.c
*
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Low level functions for remote debugging on PR31700.
+ * Kernel debugging on the Philips Nino.
*/
#include <asm/system.h>
-#include <asm/philips/pr31700.h>
+#include <asm/tx3912.h>
static int remoteDebugInitialized = 0;
diff --git a/arch/mips/philips/nino/power.c b/arch/mips/philips/nino/power.c
index 907b134b7..fccf2fbdb 100644
--- a/arch/mips/philips/nino/power.c
+++ b/arch/mips/philips/nino/power.c
@@ -2,15 +2,15 @@
* linux/arch/mips/philips/nino/power.c
*
* Copyright (C) 2000 Jim Pick <jim@jimpick.com>
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Routines for power management on the Nino.
+ * Power management routines on the Philips Nino.
*/
-#include <asm/philips/pr31700.h>
+#include <asm/tx3912.h>
void nino_wait(void)
{
diff --git a/arch/mips/philips/nino/prom.c b/arch/mips/philips/nino/prom.c
index bb4582099..b83d7a084 100644
--- a/arch/mips/philips/nino/prom.c
+++ b/arch/mips/philips/nino/prom.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/mips/philips-hpc/nino/prom.c
+ * linux/arch/mips/philips/nino/prom.c
*
* Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
@@ -7,50 +7,30 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Early initialization code for the Nino.
+ * Early initialization code for the Philips Nino.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
char arcs_cmdline[COMMAND_LINE_SIZE];
-#ifdef CONFIG_LL_DEBUG
-extern void init_uart(void);
-
-int __init prom_printf(const char * fmt, ...)
-{
- extern void serial_outc(char);
- static char buf[1024];
- va_list args;
- char c;
- int i = 0;
-
- /*
- * Printing messages via serial port
- */
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
-
- for (i = 0; buf[i] != '\0'; i++) {
- c = buf[i];
- if (c == '\n')
- serial_outc('\r');
- serial_outc(c);
- }
-
- return i;
-}
+#ifdef CONFIG_FB_TX3912
+extern u_long tx3912fb_paddr;
+extern u_long tx3912fb_vaddr;
+extern u_long tx3912fb_size;
#endif
/* Do basic initialization */
void __init prom_init(int argc, char **argv,
unsigned long magic, int *prom_vec)
{
- int i;
+ u_long free_end, mem_size;
+ u_int i;
/*
* collect args and prepare cmd_line
@@ -61,20 +41,37 @@ void __init prom_init(int argc, char **argv,
strcat(arcs_cmdline, " ");
}
-#ifdef CONFIG_LL_DEBUG
- earlyInitUartPR31700();
-#endif
-
mips_machgroup = MACH_GROUP_PHILIPS;
mips_machtype = MACH_PHILIPS_NINO;
- /* Add memory region */
#ifdef CONFIG_NINO_4MB
- add_memory_region(0, 4 << 20, BOOT_MEM_RAM);
+ mem_size = 4 << 20;
#elif CONFIG_NINO_8MB
- add_memory_region(0, 8 << 20, BOOT_MEM_RAM);
+ mem_size = 8 << 20;
#elif CONFIG_NINO_16MB
- add_memory_region(0, 16 << 20, BOOT_MEM_RAM);
+ mem_size = 16 << 20;
+#endif
+
+#ifdef CONFIG_FB_TX3912
+ /*
+ * The LCD controller requires that the framebuffer
+ * start address fall within a 1MB segment and is
+ * aligned on a 16 byte boundary. The way to assure
+ * this is to place the framebuffer at the end of
+ * memory and mark it as reserved.
+ */
+ free_end = (mem_size - tx3912fb_size) & PAGE_MASK;
+ add_memory_region(0, free_end, BOOT_MEM_RAM);
+ add_memory_region(free_end, (mem_size - free_end), BOOT_MEM_RESERVED);
+
+ /*
+ * Calculate physical and virtual addresses for
+ * the beginning of the framebuffer.
+ */
+ tx3912fb_paddr = PHYSADDR(free_end);
+ tx3912fb_vaddr = KSEG1ADDR(free_end);
+#else
+ add_memory_region(0, mem_size, BOOT_MEM_RAM);
#endif
}
diff --git a/arch/mips/philips/drivers/Makefile b/arch/mips/philips/nino/ramdisk/Makefile
index a0e316db0..1e7658863 100644
--- a/arch/mips/philips/drivers/Makefile
+++ b/arch/mips/philips/nino/ramdisk/Makefile
@@ -1,20 +1,12 @@
#
-# Makefile for the Philips Nino specific parts of the kernel
+# Makefile for the Philips Nino ramdisk
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
-.S.s:
- $(CPP) $(AFLAGS) $< -o $@
-.S.o:
- $(CC) $(AFLAGS) -c $< -o $@
-
-O_TARGET := drivers.o
-
-all: drivers.o
-
-obj-$(CONFIG_SERIAL) += uart-pr31700.o generic_serial.o
+ramdisk.o: ramdisk.gz ld.script
+ $(LD) -T ld.script -b binary -o $@ ramdisk.gz
include $(TOPDIR)/Rules.make
diff --git a/arch/mips/philips/nino/ramdisk/ld.script b/arch/mips/philips/nino/ramdisk/ld.script
new file mode 100644
index 000000000..87fd81108
--- /dev/null
+++ b/arch/mips/philips/nino/ramdisk/ld.script
@@ -0,0 +1,11 @@
+OUTPUT_FORMAT("ecoff-littlemips")
+OUTPUT_ARCH(mips)
+SECTIONS
+{
+ .data :
+ {
+ __rd_start = .;
+ *(.data)
+ __rd_end = .;
+ }
+}
diff --git a/arch/mips/philips/nino/reset.c b/arch/mips/philips/nino/reset.c
index c809b6b93..51113f1bd 100644
--- a/arch/mips/philips/nino/reset.c
+++ b/arch/mips/philips/nino/reset.c
@@ -1,13 +1,13 @@
/*
* linux/arch/mips/philips/nino/reset.c
*
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Generic restart, halt and power off functions.
+ * Generic restart, halt and power off functions for Philips Nino.
*/
#include <linux/init.h>
#include <asm/reboot.h>
diff --git a/arch/mips/philips/nino/rtc.c b/arch/mips/philips/nino/rtc.c
index 0b2584411..bcca11cf7 100644
--- a/arch/mips/philips/nino/rtc.c
+++ b/arch/mips/philips/nino/rtc.c
@@ -1,14 +1,15 @@
/*
- * linux/arch/mips/philips-mobile/nino/rtc.c
+ * linux/arch/mips/philips/nino/rtc.c
*
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Functions to access the RTC on the PR31700 chip.
+ * Functions to access RTC on the Philips Nino.
*/
+#include <linux/spinlock.h>
#include <linux/mc146818rtc.h>
static unsigned char nino_rtc_read_data(unsigned long addr)
diff --git a/arch/mips/philips/nino/setup.c b/arch/mips/philips/nino/setup.c
index 2554d3bfb..85e247cb4 100644
--- a/arch/mips/philips/nino/setup.c
+++ b/arch/mips/philips/nino/setup.c
@@ -1,13 +1,13 @@
/*
* linux/arch/mips/philips/nino/setup.c
*
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Interrupt and exception initialization for PR31700.
+ * Interrupt and exception initialization for Philips Nino.
*/
#include <linux/console.h>
#include <linux/init.h>
@@ -18,7 +18,7 @@
#include <asm/gdb-stub.h>
#include <asm/irq.h>
#include <asm/wbflush.h>
-#include <asm/philips/pr31700.h>
+#include <asm/tx3912.h>
extern struct rtc_ops nino_rtc_ops;
@@ -58,7 +58,7 @@ static void __init nino_irq_setup(void)
* Enable only the interrupts for the UART and negative
* edge (1-to-0) triggered multi-function I/O pins.
*/
- clear_cp0_status(ST0_BEV);
+ change_cp0_status(ST0_BEV, 0);
tmp = read_32bit_cp0_register(CP0_STATUS);
change_cp0_status(ST0_IM, tmp | IE_IRQ2 | IE_IRQ4);
@@ -75,6 +75,8 @@ static void __init nino_irq_setup(void)
static __init void nino_time_init(struct irqaction *irq)
{
+ unsigned int scratch = 0;
+
/*
* Enable periodic interrupts
*/
@@ -83,7 +85,10 @@ static __init void nino_time_init(struct irqaction *irq)
RTCperiodTimer = PER_TIMER_COUNT;
RTCtimerControl = TIM_ENPERTIMER;
IntEnable5 |= INT5_PERIODICINT;
- ClockControl |= CLK_ENTIMERCLK;
+
+ scratch = inl(TX3912_CLK_CTRL_BASE);
+ scratch |= TX3912_CLK_CTRL_ENTIMERCLK;
+ outl(scratch, TX3912_CLK_CTRL_BASE);
/* Enable all interrupts */
IntEnable6 |= INT6_GLOBALEN | INT6_PERIODICINT;
@@ -96,7 +101,7 @@ void __init nino_setup(void)
board_time_init = nino_time_init;
/* Base address to use for PC type I/O accesses */
- mips_io_port_base = KSEG1ADDR(0x08000000);
+ mips_io_port_base = KSEG1ADDR(0xB0C00000);
setup_nino_reset_vectors();
diff --git a/arch/mips/philips/nino/time.c b/arch/mips/philips/nino/time.c
index b3bc87e7e..5a3c368c1 100644
--- a/arch/mips/philips/nino/time.c
+++ b/arch/mips/philips/nino/time.c
@@ -1,15 +1,15 @@
/*
* linux/arch/mips/philips/nino/time.c
*
- * Copyright (C) 1999 Harald Koerfgen (Harald.Koerfgen@home.ivm.de)
+ * Copyright (C) 1999 Harald Koerfgen
* Copyright (C) 2000 Pavel Machek (pavel@suse.cz)
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Time handling details for PR31700.
+ * Time handling functinos for Philips Nino.
*/
#include <linux/errno.h>
#include <linux/init.h>
@@ -21,7 +21,7 @@
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/delay.h>
-#include <asm/philips/pr31700.h>
+#include <asm/tx3912.h>
extern volatile unsigned long wall_jiffies;
extern rwlock_t xtime_lock;
diff --git a/arch/mips/philips/nino/wbflush.c b/arch/mips/philips/nino/wbflush.c
index 2b1056259..f70b5ef69 100644
--- a/arch/mips/philips/nino/wbflush.c
+++ b/arch/mips/philips/nino/wbflush.c
@@ -1,13 +1,13 @@
/*
* linux/arch/mips/philips/nino/wbflush.c
*
- * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * Function to flush the write buffer on the PR31700 chip.
+ * Function to flush the write buffer on the Philips Nino.
*/
#include <linux/init.h>