~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Driver for CPM (SCC/SMC) serial ports; CPM2 definitions
 
3
 *
 
4
 *  Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
 
5
 *              Pantelis Antoniou (panto@intracom.gr) (CPM1)
 
6
 *
 
7
 *  Copyright (C) 2004 Freescale Semiconductor, Inc.
 
8
 *            (C) 2004 Intracom, S.A.
 
9
 *            (C) 2006 MontaVista Software, Inc.
 
10
 *              Vitaly Bordug <vbordug@ru.mvista.com>
 
11
 *
 
12
 * This program is free software; you can redistribute it and/or modify
 
13
 * it under the terms of the GNU General Public License as published by
 
14
 * the Free Software Foundation; either version 2 of the License, or
 
15
 * (at your option) any later version.
 
16
 *
 
17
 * This program is distributed in the hope that it will be useful,
 
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 * GNU General Public License for more details.
 
21
 *
 
22
 * You should have received a copy of the GNU General Public License
 
23
 * along with this program; if not, write to the Free Software
 
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
25
 *
 
26
 */
 
27
 
 
28
#include <linux/module.h>
 
29
#include <linux/tty.h>
 
30
#include <linux/ioport.h>
 
31
#include <linux/slab.h>
 
32
#include <linux/init.h>
 
33
#include <linux/serial.h>
 
34
#include <linux/console.h>
 
35
#include <linux/sysrq.h>
 
36
#include <linux/device.h>
 
37
#include <linux/bootmem.h>
 
38
#include <linux/dma-mapping.h>
 
39
 
 
40
#include <asm/io.h>
 
41
#include <asm/irq.h>
 
42
#include <asm/fs_pd.h>
 
43
#include <asm/prom.h>
 
44
 
 
45
#include <linux/serial_core.h>
 
46
#include <linux/kernel.h>
 
47
 
 
48
#include "cpm_uart.h"
 
49
 
 
50
/**************************************************************/
 
51
 
 
52
void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
 
53
{
 
54
        cpm_command(port->command, cmd);
 
55
}
 
56
 
 
57
void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
 
58
                                struct device_node *np)
 
59
{
 
60
        void __iomem *pram;
 
61
        unsigned long offset;
 
62
        struct resource res;
 
63
        resource_size_t len;
 
64
 
 
65
        /* Don't remap parameter RAM if it has already been initialized
 
66
         * during console setup.
 
67
         */
 
68
        if (IS_SMC(port) && port->smcup)
 
69
                return port->smcup;
 
70
        else if (!IS_SMC(port) && port->sccup)
 
71
                return port->sccup;
 
72
 
 
73
        if (of_address_to_resource(np, 1, &res))
 
74
                return NULL;
 
75
 
 
76
        len = resource_size(&res);
 
77
        pram = ioremap(res.start, len);
 
78
        if (!pram)
 
79
                return NULL;
 
80
 
 
81
        if (!IS_SMC(port))
 
82
                return pram;
 
83
 
 
84
        if (len != 2) {
 
85
                printk(KERN_WARNING "cpm_uart[%d]: device tree references "
 
86
                        "SMC pram, using boot loader/wrapper pram mapping. "
 
87
                        "Please fix your device tree to reference the pram "
 
88
                        "base register instead.\n",
 
89
                        port->port.line);
 
90
                return pram;
 
91
        }
 
92
 
 
93
        offset = cpm_dpalloc(PROFF_SMC_SIZE, 64);
 
94
        out_be16(pram, offset);
 
95
        iounmap(pram);
 
96
        return cpm_muram_addr(offset);
 
97
}
 
98
 
 
99
void cpm_uart_unmap_pram(struct uart_cpm_port *port, void __iomem *pram)
 
100
{
 
101
        if (!IS_SMC(port))
 
102
                iounmap(pram);
 
103
}
 
104
 
 
105
/*
 
106
 * Allocate DP-Ram and memory buffers. We need to allocate a transmit and
 
107
 * receive buffer descriptors from dual port ram, and a character
 
108
 * buffer area from host mem. If we are allocating for the console we need
 
109
 * to do it from bootmem
 
110
 */
 
111
int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
 
112
{
 
113
        int dpmemsz, memsz;
 
114
        u8 __iomem *dp_mem;
 
115
        unsigned long dp_offset;
 
116
        u8 *mem_addr;
 
117
        dma_addr_t dma_addr = 0;
 
118
 
 
119
        pr_debug("CPM uart[%d]:allocbuf\n", pinfo->port.line);
 
120
 
 
121
        dpmemsz = sizeof(cbd_t) * (pinfo->rx_nrfifos + pinfo->tx_nrfifos);
 
122
        dp_offset = cpm_dpalloc(dpmemsz, 8);
 
123
        if (IS_ERR_VALUE(dp_offset)) {
 
124
                printk(KERN_ERR
 
125
                       "cpm_uart_cpm.c: could not allocate buffer descriptors\n");
 
126
                return -ENOMEM;
 
127
        }
 
128
 
 
129
        dp_mem = cpm_dpram_addr(dp_offset);
 
130
 
 
131
        memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
 
132
            L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
 
133
        if (is_con) {
 
134
                mem_addr = kzalloc(memsz, GFP_NOWAIT);
 
135
                dma_addr = virt_to_bus(mem_addr);
 
136
        }
 
137
        else
 
138
                mem_addr = dma_alloc_coherent(pinfo->port.dev, memsz, &dma_addr,
 
139
                                              GFP_KERNEL);
 
140
 
 
141
        if (mem_addr == NULL) {
 
142
                cpm_dpfree(dp_offset);
 
143
                printk(KERN_ERR
 
144
                       "cpm_uart_cpm.c: could not allocate coherent memory\n");
 
145
                return -ENOMEM;
 
146
        }
 
147
 
 
148
        pinfo->dp_addr = dp_offset;
 
149
        pinfo->mem_addr = mem_addr;
 
150
        pinfo->dma_addr = dma_addr;
 
151
        pinfo->mem_size = memsz;
 
152
 
 
153
        pinfo->rx_buf = mem_addr;
 
154
        pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
 
155
                                                       * pinfo->rx_fifosize);
 
156
 
 
157
        pinfo->rx_bd_base = (cbd_t __iomem *)dp_mem;
 
158
        pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos;
 
159
 
 
160
        return 0;
 
161
}
 
162
 
 
163
void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
 
164
{
 
165
        dma_free_coherent(pinfo->port.dev, L1_CACHE_ALIGN(pinfo->rx_nrfifos *
 
166
                                                          pinfo->rx_fifosize) +
 
167
                          L1_CACHE_ALIGN(pinfo->tx_nrfifos *
 
168
                                         pinfo->tx_fifosize), (void __force *)pinfo->mem_addr,
 
169
                          pinfo->dma_addr);
 
170
 
 
171
        cpm_dpfree(pinfo->dp_addr);
 
172
}