This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / serial / pmac_zilog.c
index 34e1490..7258659 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * 2004-08-06 Harald Welte <laforge@gnumonks.org>
- *     - Enable BREAK interrupt
- *     - Add support for sysreq
- *
  * TODO:   - Add DMA support
  *         - Defer port shutdown to a few seconds after close
  *         - maybe put something right into uap->clk_divisor
@@ -40,7 +36,6 @@
 
 #undef DEBUG
 #undef DEBUG_HARD
-#undef USE_CTRL_O_SYSRQ
 
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
-#include <linux/bitops.h>
-#include <linux/sysrq.h>
 #include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/prom.h>
+#include <asm/bitops.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
 #include <asm/dbdma.h>
 #include <asm/macio.h>
 #include <asm/semaphore.h>
 
-#if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 
@@ -269,27 +259,8 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
                }
 
                ch &= uap->parity_mask;
-               if (ch == 0 && uap->flags & PMACZILOG_FLAG_BREAK) {
-                       uap->flags &= ~PMACZILOG_FLAG_BREAK;
-               }
-
-#if defined(CONFIG_MAGIC_SYSRQ) && defined(CONFIG_SERIAL_CORE_CONSOLE)
-#ifdef USE_CTRL_O_SYSRQ
-               /* Handle the SysRq ^O Hack */
-               if (ch == '\x0f') {
-                       uap->port.sysrq = jiffies + HZ*5;
-                       goto next_char;
-               }
-#endif /* USE_CTRL_O_SYSRQ */
-               if (uap->port.sysrq) {
-                       int swallow;
-                       spin_unlock(&uap->port.lock);
-                       swallow = uart_handle_sysrq_char(&uap->port, ch, regs);
-                       spin_lock(&uap->port.lock);
-                       if (swallow)
-                               goto next_char;
-               }
-#endif /* CONFIG_MAGIC_SYSRQ && CONFIG_SERIAL_CORE_CONSOLE */
+               if (ch == 0 && uap->prev_status & BRK_ABRT)
+                       r1 |= BRK_ABRT;
 
                /* A real serial line, record the character and status.  */
                if (drop)
@@ -305,8 +276,10 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
                                pmz_debug("pmz: got break !\n");
                                r1 &= ~(PAR_ERR | CRC_ERR);
                                uap->port.icount.brk++;
-                               if (uart_handle_break(&uap->port))
+                               if (uart_handle_break(&uap->port)) {
+                                       pmz_debug("pmz: do handle break !\n");
                                        goto next_char;
+                               }
                        }
                        else if (r1 & PAR_ERR)
                                uap->port.icount.parity++;
@@ -322,6 +295,10 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
                        else if (r1 & CRC_ERR)
                                *tty->flip.flag_buf_ptr = TTY_FRAME;
                }
+               if (uart_handle_sysrq_char(&uap->port, ch, regs)) {
+                       pmz_debug("pmz: sysrq swallowed the char\n");
+                       goto next_char;
+               }
 
                if (uap->port.ignore_status_mask == 0xff ||
                    (r1 & uap->port.ignore_status_mask) == 0) {
@@ -387,9 +364,6 @@ static void pmz_status_handle(struct uart_pmac_port *uap, struct pt_regs *regs)
                wake_up_interruptible(&uap->port.info->delta_msr_wait);
        }
 
-       if (status & BRK_ABRT)
-               uap->flags |= PMACZILOG_FLAG_BREAK;
-
        uap->prev_status = status;
 }
 
@@ -898,8 +872,8 @@ static int __pmz_startup(struct uart_pmac_port *uap)
        uap->curregs[R13] = 0;
        uap->curregs[R14] = BRENAB;
 
-       /* Clear handshaking, enable BREAK interrupts */
-       uap->curregs[R15] = BRKIE;
+       /* Clear handshaking */
+       uap->curregs[R15] = 0;
 
        /* Master interrupt enable */
        uap->curregs[R9] |= NV | MIE;
@@ -975,7 +949,8 @@ static int pmz_startup(struct uart_port *port)
         */
        if (pwr_delay != 0) {
                pmz_debug("pmz: delaying %d ms\n", pwr_delay);
-               msleep(pwr_delay);
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout((pwr_delay * HZ)/1000);
        }
 
        /* IrDA reset is done now */
@@ -1334,8 +1309,6 @@ static void __pmz_set_termios(struct uart_port *port, struct termios *termios,
                /* Load registers to the chip */
                pmz_maybe_update_regs(uap);
        }
-       uart_update_timeout(port, termios->c_cflag, baud);
-
        pmz_debug("pmz: set_termios() done.\n");
 }
 
@@ -1439,7 +1412,7 @@ static int __init pmz_init_port(struct uart_pmac_port *uap)
        uap->port.mapbase = np->addrs[0].address;
        uap->port.membase = ioremap(uap->port.mapbase, 0x1000);
       
-       uap->control_reg = uap->port.membase;
+       uap->control_reg = (volatile u8 *)uap->port.membase;
        uap->data_reg = uap->control_reg + 0x10;
        
        /*
@@ -1450,14 +1423,16 @@ static int __init pmz_init_port(struct uart_pmac_port *uap)
                uap->flags |= PMACZILOG_FLAG_HAS_DMA;
 #endif 
        if (ZS_HAS_DMA(uap)) {
-               uap->tx_dma_regs = ioremap(np->addrs[np->n_addrs - 2].address, 0x1000);
+               uap->tx_dma_regs = (volatile struct dbdma_regs *)
+                       ioremap(np->addrs[np->n_addrs - 2].address, 0x1000);
                if (uap->tx_dma_regs == NULL) { 
                        uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
                        goto no_dma;
                }
-               uap->rx_dma_regs = ioremap(np->addrs[np->n_addrs - 1].address, 0x1000);
+               uap->rx_dma_regs = (volatile struct dbdma_regs *)
+                       ioremap(np->addrs[np->n_addrs - 1].address, 0x1000);
                if (uap->rx_dma_regs == NULL) { 
-                       iounmap(uap->tx_dma_regs);
+                       iounmap((void *)uap->tx_dma_regs);
                        uap->tx_dma_regs = NULL;
                        uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
                        goto no_dma;
@@ -1534,9 +1509,9 @@ static void pmz_dispose_port(struct uart_pmac_port *uap)
        struct device_node *np;
 
        np = uap->node;
-       iounmap(uap->rx_dma_regs);
-       iounmap(uap->tx_dma_regs);
-       iounmap(uap->control_reg);
+       iounmap((void *)uap->rx_dma_regs);
+       iounmap((void *)uap->tx_dma_regs);
+       iounmap((void *)uap->control_reg);
        uap->node = NULL;
        of_node_put(np);
        memset(uap, 0, sizeof(struct uart_pmac_port));
@@ -1601,7 +1576,7 @@ static int pmz_suspend(struct macio_dev *mdev, u32 pm_state)
                return 0;
        }
 
-       if (pm_state == mdev->ofdev.dev.power.power_state || pm_state < 2)
+       if (pm_state == mdev->ofdev.dev.power_state || pm_state < 2)
                return 0;
 
        pmz_debug("suspend, switching to state %d\n", pm_state);
@@ -1645,7 +1620,7 @@ static int pmz_suspend(struct macio_dev *mdev, u32 pm_state)
 
        pmz_debug("suspend, switching complete\n");
 
-       mdev->ofdev.dev.power.power_state = pm_state;
+       mdev->ofdev.dev.power_state = pm_state;
 
        return 0;
 }
@@ -1661,7 +1636,7 @@ static int pmz_resume(struct macio_dev *mdev)
        if (uap == NULL)
                return 0;
 
-       if (mdev->ofdev.dev.power.power_state == 0)
+       if (mdev->ofdev.dev.power_state == 0)
                return 0;
        
        pmz_debug("resume, switching to state 0\n");
@@ -1709,12 +1684,13 @@ static int pmz_resume(struct macio_dev *mdev)
         */
        if (pwr_delay != 0) {
                pmz_debug("pmz: delaying %d ms\n", pwr_delay);
-               msleep(pwr_delay);
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout((pwr_delay * HZ)/1000);
        }
 
        pmz_debug("resume, switching complete\n");
 
-       mdev->ofdev.dev.power.power_state = 0;
+       mdev->ofdev.dev.power_state = 0;
 
        return 0;
 }