Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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