fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / serial / cpm_uart / cpm_uart_cpm2.c
index fd9e53e..787a8f1 100644 (file)
@@ -8,6 +8,8 @@
  * 
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
  *            (C) 2004 Intracom, S.A.
+ *            (C) 2006 MontaVista Software, Inc.
+ *             Vitaly Bordug <vbordug@ru.mvista.com>
  *
  * 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
@@ -25,7 +27,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
@@ -39,6 +40,7 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/fs_pd.h>
 
 #include <linux/serial_core.h>
 #include <linux/kernel.h>
@@ -49,8 +51,9 @@
 
 void cpm_line_cr_cmd(int line, int cmd)
 {
-       volatile cpm_cpm2_t *cp = cpmp;
        ulong val;
+       volatile cpm_cpm2_t *cp = cpm2_map(im_cpm);
+
 
        switch (line) {
        case UART_SMC1:
@@ -83,11 +86,14 @@ void cpm_line_cr_cmd(int line, int cmd)
        }
        cp->cp_cpcr = val;
        while (cp->cp_cpcr & CPM_CR_FLG) ;
+
+       cpm2_unmap(cp);
 }
 
 void smc1_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
        /* SMC1 is only on port D */
        io->iop_ppard |= 0x00c00000;
@@ -96,13 +102,17 @@ void smc1_lineif(struct uart_cpm_port *pinfo)
        io->iop_psord &= ~0x00c00000;
 
        /* Wire BRG1 to SMC1 */
-       cpm2_immr->im_cpmux.cmx_smr &= 0x0f;
+       cpmux->cmx_smr &= 0x0f;
        pinfo->brg = 1;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void smc2_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
        /* SMC2 is only on port A */
        io->iop_ppara |= 0x00c00000;
@@ -111,13 +121,17 @@ void smc2_lineif(struct uart_cpm_port *pinfo)
        io->iop_psora &= ~0x00c00000;
 
        /* Wire BRG2 to SMC2 */
-       cpm2_immr->im_cpmux.cmx_smr &= 0xf0;
+       cpmux->cmx_smr &= 0xf0;
        pinfo->brg = 2;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void scc1_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
        /* Use Port D for SCC1 instead of other functions.  */
        io->iop_ppard |= 0x00000003;
@@ -127,9 +141,12 @@ void scc1_lineif(struct uart_cpm_port *pinfo)
        io->iop_pdird |= 0x00000002;    /* Tx */
 
        /* Wire BRG1 to SCC1 */
-       cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff;
-       cpm2_immr->im_cpmux.cmx_scr |= 0x00000000;
+       cpmux->cmx_scr &= 0x00ffffff;
+       cpmux->cmx_scr |= 0x00000000;
        pinfo->brg = 1;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void scc2_lineif(struct uart_cpm_port *pinfo)
@@ -142,52 +159,57 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
         * be supported in a sane fashion.
         */
 #ifndef CONFIG_STX_GP3
-#ifdef CONFIG_MPC8560_ADS
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
-       io->iop_ppard |= 0x00000018;
-       io->iop_psord &= ~0x00000008;   /* Rx */
-       io->iop_psord &= ~0x00000010;   /* Tx */
-       io->iop_pdird &= ~0x00000008;   /* Rx */
-       io->iop_pdird |= 0x00000010;    /* Tx */
-#else
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
        io->iop_pparb |= 0x008b0000;
        io->iop_pdirb |= 0x00880000;
        io->iop_psorb |= 0x00880000;
        io->iop_pdirb &= ~0x00030000;
        io->iop_psorb &= ~0x00030000;
 #endif
-#endif
-       cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
-       cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
+       cpmux->cmx_scr &= 0xff00ffff;
+       cpmux->cmx_scr |= 0x00090000;
        pinfo->brg = 2;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void scc3_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
+
        io->iop_pparb |= 0x008b0000;
        io->iop_pdirb |= 0x00880000;
        io->iop_psorb |= 0x00880000;
        io->iop_pdirb &= ~0x00030000;
        io->iop_psorb &= ~0x00030000;
-       cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff;
-       cpm2_immr->im_cpmux.cmx_scr |= 0x00001200;
+       cpmux->cmx_scr &= 0xffff00ff;
+       cpmux->cmx_scr |= 0x00001200;
        pinfo->brg = 3;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 void scc4_lineif(struct uart_cpm_port *pinfo)
 {
-       volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+       volatile iop_cpm2_t *io = cpm2_map(im_ioport);
+       volatile cpmux_t *cpmux = cpm2_map(im_cpmux);
 
        io->iop_ppard |= 0x00000600;
        io->iop_psord &= ~0x00000600;   /* Tx/Rx */
        io->iop_pdird &= ~0x00000200;   /* Rx */
        io->iop_pdird |= 0x00000400;    /* Tx */
 
-       cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00;
-       cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b;
+       cpmux->cmx_scr &= 0xffffff00;
+       cpmux->cmx_scr |= 0x0000001b;
        pinfo->brg = 4;
+
+       cpm2_unmap(cpmux);
+       cpm2_unmap(io);
 }
 
 /*
@@ -218,8 +240,10 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
 
        memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
            L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
-       if (is_con)
+       if (is_con) {
                mem_addr = alloc_bootmem(memsz);
+               dma_addr = virt_to_bus(mem_addr);
+       }
        else
                mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
                                              GFP_KERNEL);
@@ -234,6 +258,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
        pinfo->dp_addr = dp_offset;
        pinfo->mem_addr = mem_addr;
        pinfo->dma_addr = dma_addr;
+       pinfo->mem_size = memsz;
 
        pinfo->rx_buf = mem_addr;
        pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
@@ -257,90 +282,105 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
 }
 
 /* Setup any dynamic params in the uart desc */
-int cpm_uart_init_portdesc(void)
+int __init cpm_uart_init_portdesc(void)
 {
+#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
+       u32 addr;
+#endif
        pr_debug("CPM uart[-]:init portdesc\n");
 
        cpm_uart_nr = 0;
 #ifdef CONFIG_SERIAL_CPM_SMC1
-       cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0];
-       cpm_uart_ports[UART_SMC1].smcup =
-           (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC1];
-       *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+       cpm_uart_ports[UART_SMC1].smcp = (smc_t *) cpm2_map(im_smc[0]);
        cpm_uart_ports[UART_SMC1].port.mapbase =
-           (unsigned long)&cpm2_immr->im_smc[0];
+           (unsigned long)cpm_uart_ports[UART_SMC1].smcp;
+
+       cpm_uart_ports[UART_SMC1].smcup =
+           (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC1], PROFF_SMC_SIZE);
+       addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC1_BASE], 2);
+       *addr = PROFF_SMC1;
+       cpm2_unmap(addr);
+
        cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
        cpm_uart_ports[UART_SMC1].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-       cpm_uart_ports[UART_SMC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SMC1].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SMC2
-       cpm_uart_ports[UART_SMC2].smcp = (smc_t *) & cpm2_immr->im_smc[1];
-       cpm_uart_ports[UART_SMC2].smcup =
-           (smc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SMC2];
-       *(u16 *)(&cpm2_immr->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2;
+       cpm_uart_ports[UART_SMC2].smcp = (smc_t *) cpm2_map(im_smc[1]);
        cpm_uart_ports[UART_SMC2].port.mapbase =
-           (unsigned long)&cpm2_immr->im_smc[1];
+           (unsigned long)cpm_uart_ports[UART_SMC2].smcp;
+
+       cpm_uart_ports[UART_SMC2].smcup =
+           (smc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SMC2], PROFF_SMC_SIZE);
+       addr = (u16 *)cpm2_map_size(im_dprambase[PROFF_SMC2_BASE], 2);
+       *addr = PROFF_SMC2;
+       cpm2_unmap(addr);
+
        cpm_uart_ports[UART_SMC2].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
        cpm_uart_ports[UART_SMC2].smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-       cpm_uart_ports[UART_SMC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SMC2].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC1
-       cpm_uart_ports[UART_SCC1].sccp = (scc_t *) & cpm2_immr->im_scc[0];
-       cpm_uart_ports[UART_SCC1].sccup =
-           (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC1];
+       cpm_uart_ports[UART_SCC1].sccp = (scc_t *) cpm2_map(im_scc[0]);
        cpm_uart_ports[UART_SCC1].port.mapbase =
-           (unsigned long)&cpm2_immr->im_scc[0];
+           (unsigned long)cpm_uart_ports[UART_SCC1].sccp;
+       cpm_uart_ports[UART_SCC1].sccup =
+           (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC1], PROFF_SCC_SIZE);
+
        cpm_uart_ports[UART_SCC1].sccp->scc_sccm &=
            ~(UART_SCCM_TX | UART_SCCM_RX);
        cpm_uart_ports[UART_SCC1].sccp->scc_gsmrl &=
            ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-       cpm_uart_ports[UART_SCC1].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SCC1].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC2
-       cpm_uart_ports[UART_SCC2].sccp = (scc_t *) & cpm2_immr->im_scc[1];
-       cpm_uart_ports[UART_SCC2].sccup =
-           (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC2];
+       cpm_uart_ports[UART_SCC2].sccp = (scc_t *) cpm2_map(im_scc[1]);
        cpm_uart_ports[UART_SCC2].port.mapbase =
-           (unsigned long)&cpm2_immr->im_scc[1];
+           (unsigned long)cpm_uart_ports[UART_SCC2].sccp;
+       cpm_uart_ports[UART_SCC2].sccup =
+           (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC2], PROFF_SCC_SIZE);
+
        cpm_uart_ports[UART_SCC2].sccp->scc_sccm &=
            ~(UART_SCCM_TX | UART_SCCM_RX);
        cpm_uart_ports[UART_SCC2].sccp->scc_gsmrl &=
            ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-       cpm_uart_ports[UART_SCC2].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SCC2].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC3
-       cpm_uart_ports[UART_SCC3].sccp = (scc_t *) & cpm2_immr->im_scc[2];
-       cpm_uart_ports[UART_SCC3].sccup =
-           (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC3];
+       cpm_uart_ports[UART_SCC3].sccp = (scc_t *) cpm2_map(im_scc[2]);
        cpm_uart_ports[UART_SCC3].port.mapbase =
-           (unsigned long)&cpm2_immr->im_scc[2];
+           (unsigned long)cpm_uart_ports[UART_SCC3].sccp;
+       cpm_uart_ports[UART_SCC3].sccup =
+           (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC3], PROFF_SCC_SIZE);
+
        cpm_uart_ports[UART_SCC3].sccp->scc_sccm &=
            ~(UART_SCCM_TX | UART_SCCM_RX);
        cpm_uart_ports[UART_SCC3].sccp->scc_gsmrl &=
            ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-       cpm_uart_ports[UART_SCC3].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SCC3].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
 #endif
 
 #ifdef CONFIG_SERIAL_CPM_SCC4
-       cpm_uart_ports[UART_SCC4].sccp = (scc_t *) & cpm2_immr->im_scc[3];
-       cpm_uart_ports[UART_SCC4].sccup =
-           (scc_uart_t *) & cpm2_immr->im_dprambase[PROFF_SCC4];
+       cpm_uart_ports[UART_SCC4].sccp = (scc_t *) cpm2_map(im_scc[3]);
        cpm_uart_ports[UART_SCC4].port.mapbase =
-           (unsigned long)&cpm2_immr->im_scc[3];
+           (unsigned long)cpm_uart_ports[UART_SCC4].sccp;
+       cpm_uart_ports[UART_SCC4].sccup =
+           (scc_uart_t *) cpm2_map_size(im_dprambase[PROFF_SCC4], PROFF_SCC_SIZE);
+
        cpm_uart_ports[UART_SCC4].sccp->scc_sccm &=
            ~(UART_SCCM_TX | UART_SCCM_RX);
        cpm_uart_ports[UART_SCC4].sccp->scc_gsmrl &=
            ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
-       cpm_uart_ports[UART_SCC4].port.uartclk = (((bd_t *) __res)->bi_intfreq);
+       cpm_uart_ports[UART_SCC4].port.uartclk = uart_clock();
        cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
 #endif