mcf.c revision 2545cf6e94b4eb5a2c48dd55751aa9a70ff1ff9d
149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/* 449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * mcf.c -- Freescale ColdFire UART driver 549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * 649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com> 749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * 849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * This program is free software; you can redistribute it and/or modify 949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * it under the terms of the GNU General Public License as published by 1049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * the Free Software Foundation; either version 2 of the License, or 1149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * (at your option) any later version. 1249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer */ 1349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 1449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 1549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 1649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/kernel.h> 1749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/init.h> 1849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/interrupt.h> 1949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/module.h> 2049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/console.h> 2149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/tty.h> 2249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/tty_flip.h> 2349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/serial.h> 2449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/serial_core.h> 2549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <linux/io.h> 2649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <asm/coldfire.h> 2749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <asm/mcfsim.h> 2849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <asm/mcfuart.h> 2949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#include <asm/nettel.h> 3049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 3149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 3249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 3349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/* 3449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * Some boards implement the DTR/DCD lines using GPIO lines, most 3549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * don't. Dummy out the access macros for those that don't. Those 3649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * that do should define these macros somewhere in there board 3749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * specific inlude files. 3849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer */ 3949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#if !defined(mcf_getppdcd) 4049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#define mcf_getppdcd(p) (1) 4149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#endif 4249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#if !defined(mcf_getppdtr) 4349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#define mcf_getppdtr(p) (1) 4449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#endif 4549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#if !defined(mcf_setppdtr) 4649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#define mcf_setppdtr(p, v) do { } while (0) 4749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#endif 4849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 4949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 5049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 5149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/* 5249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * Local per-uart structure. 5349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer */ 5449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstruct mcf_uart { 5549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer struct uart_port port; 5649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned int sigs; /* Local copy of line sigs */ 5749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned char imr; /* Local IMR mirror */ 5849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer}; 5949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 6049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 6149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 6249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic unsigned int mcf_tx_empty(struct uart_port *port) 6349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 6449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXEMPTY) ? 6549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer TIOCSER_TEMT : 0; 6649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 6749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 6849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 6949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 7049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic unsigned int mcf_get_mctrl(struct uart_port *port) 7149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 729f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 7349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned long flags; 7449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned int sigs; 7549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 7649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_lock_irqsave(&port->lock, flags); 7749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ? 7849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 0 : TIOCM_CTS; 7949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer sigs |= (pp->sigs & TIOCM_RTS); 8049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0); 8149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0); 8249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_unlock_irqrestore(&port->lock, flags); 8349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return sigs; 8449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 8549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 8649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 8749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 8849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_set_mctrl(struct uart_port *port, unsigned int sigs) 8949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 909f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 9149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned long flags; 9249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 9349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_lock_irqsave(&port->lock, flags); 9449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer pp->sigs = sigs; 9549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mcf_setppdtr(port->line, (sigs & TIOCM_DTR)); 9649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (sigs & TIOCM_RTS) 9749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); 9849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer else 9949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0); 10049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_unlock_irqrestore(&port->lock, flags); 10149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 10249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 10349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 10449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 10549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_start_tx(struct uart_port *port) 10649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 1079f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 10849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned long flags; 10949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 11049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_lock_irqsave(&port->lock, flags); 11149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer pp->imr |= MCFUART_UIR_TXREADY; 11249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(pp->imr, port->membase + MCFUART_UIMR); 11349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_unlock_irqrestore(&port->lock, flags); 11449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 11549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 11649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 11749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 11849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_stop_tx(struct uart_port *port) 11949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 1209f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 12149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned long flags; 12249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 12349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_lock_irqsave(&port->lock, flags); 12449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer pp->imr &= ~MCFUART_UIR_TXREADY; 12549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(pp->imr, port->membase + MCFUART_UIMR); 12649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_unlock_irqrestore(&port->lock, flags); 12749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 12849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 12949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 13049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 13149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_stop_rx(struct uart_port *port) 13249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 1339f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 13449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned long flags; 13549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 13649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_lock_irqsave(&port->lock, flags); 13749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer pp->imr &= ~MCFUART_UIR_RXREADY; 13849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(pp->imr, port->membase + MCFUART_UIMR); 13949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_unlock_irqrestore(&port->lock, flags); 14049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 14149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 14249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 14349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 14449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_break_ctl(struct uart_port *port, int break_state) 14549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 14649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned long flags; 14749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 14849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_lock_irqsave(&port->lock, flags); 14949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (break_state == -1) 15049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDBREAKSTART, port->membase + MCFUART_UCR); 15149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer else 15249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDBREAKSTOP, port->membase + MCFUART_UCR); 15349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_unlock_irqrestore(&port->lock, flags); 15449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 15549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 15649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 15749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 15849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_enable_ms(struct uart_port *port) 15949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 16049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 16149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 16249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 16349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 16449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic int mcf_startup(struct uart_port *port) 16549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 1669f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 16749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned long flags; 16849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 16949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_lock_irqsave(&port->lock, flags); 17049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 17149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer /* Reset UART, get it into known state... */ 17249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); 17349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); 17449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 17549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer /* Enable the UART transmitter and receiver */ 17649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE, 17749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->membase + MCFUART_UCR); 17849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 17949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer /* Enable RX interrupts now */ 18049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer pp->imr = MCFUART_UIR_RXREADY; 18149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(pp->imr, port->membase + MCFUART_UIMR); 18249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 18349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_unlock_irqrestore(&port->lock, flags); 18449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 18549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return 0; 18649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 18749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 18849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 18949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 19049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_shutdown(struct uart_port *port) 19149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 1929f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 19349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned long flags; 19449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 19549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_lock_irqsave(&port->lock, flags); 19649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 19749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer /* Disable all interrupts now */ 19849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer pp->imr = 0; 19949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(pp->imr, port->membase + MCFUART_UIMR); 20049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 20149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer /* Disable UART transmitter and receiver */ 20249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); 20349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); 20449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 20549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_unlock_irqrestore(&port->lock, flags); 20649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 20749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 20849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 20949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 21049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_set_termios(struct uart_port *port, struct ktermios *termios, 21149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer struct ktermios *old) 21249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 21349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned long flags; 21449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned int baud, baudclk; 21526a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson#if defined(CONFIG_M5272) 21626a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson unsigned int baudfr; 21726a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson#endif 21849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned char mr1, mr2; 21949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 22049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer baud = uart_get_baud_rate(port, termios, old, 0, 230400); 22126a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson#if defined(CONFIG_M5272) 22226a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson baudclk = (MCF_BUSCLK / baud) / 32; 22326a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson baudfr = (((MCF_BUSCLK / baud) + 1) / 2) % 16; 22426a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson#else 22549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer baudclk = ((MCF_BUSCLK / baud) + 16) / 32; 22626a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson#endif 22749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 22849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR; 22949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr2 = 0; 23049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 23149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer switch (termios->c_cflag & CSIZE) { 23249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer case CS5: mr1 |= MCFUART_MR1_CS5; break; 23349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer case CS6: mr1 |= MCFUART_MR1_CS6; break; 23449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer case CS7: mr1 |= MCFUART_MR1_CS7; break; 23549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer case CS8: 23649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer default: mr1 |= MCFUART_MR1_CS8; break; 23749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 23849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 23949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (termios->c_cflag & PARENB) { 24049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (termios->c_cflag & CMSPAR) { 24149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (termios->c_cflag & PARODD) 24249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr1 |= MCFUART_MR1_PARITYMARK; 24349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer else 24449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr1 |= MCFUART_MR1_PARITYSPACE; 24549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } else { 24649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (termios->c_cflag & PARODD) 24749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr1 |= MCFUART_MR1_PARITYODD; 24849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer else 24949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr1 |= MCFUART_MR1_PARITYEVEN; 25049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 25149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } else { 25249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr1 |= MCFUART_MR1_PARITYNONE; 25349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 25449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 25549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (termios->c_cflag & CSTOPB) 25649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr2 |= MCFUART_MR2_STOP2; 25749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer else 25849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr2 |= MCFUART_MR2_STOP1; 25949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 26049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (termios->c_cflag & CRTSCTS) { 26149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr1 |= MCFUART_MR1_RXRTS; 26249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mr2 |= MCFUART_MR2_TXCTS; 26349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 26449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 26549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_lock_irqsave(&port->lock, flags); 2663732b68f22857201fa09cb82b128f295096a2375Philippe De Muyter uart_update_timeout(port, termios->c_cflag, baud); 26749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); 26849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); 26949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR); 27049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(mr1, port->membase + MCFUART_UMR); 27149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(mr2, port->membase + MCFUART_UMR); 27249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1); 27349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb((baudclk & 0xff), port->membase + MCFUART_UBG2); 27426a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson#if defined(CONFIG_M5272) 27526a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson writeb((baudfr & 0x0f), port->membase + MCFUART_UFPD); 27626a4bc66a6f57299027e04d90b14fe56a44c6d2bJohn Adamson#endif 27749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER, 27849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->membase + MCFUART_UCSR); 27949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE, 28049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->membase + MCFUART_UCR); 28149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer spin_unlock_irqrestore(&port->lock, flags); 28249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 28349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 28449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 28549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 28649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_rx_chars(struct mcf_uart *pp) 28749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 2889f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct uart_port *port = &pp->port; 28949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned char status, ch, flag; 29049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 29149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer while ((status = readb(port->membase + MCFUART_USR)) & MCFUART_USR_RXREADY) { 29249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer ch = readb(port->membase + MCFUART_URB); 29349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer flag = TTY_NORMAL; 29449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->icount.rx++; 29549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 29649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (status & MCFUART_USR_RXERR) { 29749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(MCFUART_UCR_CMDRESETERR, 29849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->membase + MCFUART_UCR); 29949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 30049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (status & MCFUART_USR_RXBREAK) { 30149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->icount.brk++; 30249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (uart_handle_break(port)) 30349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer continue; 30449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } else if (status & MCFUART_USR_RXPARITY) { 30549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->icount.parity++; 30649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } else if (status & MCFUART_USR_RXOVERRUN) { 30749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->icount.overrun++; 30849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } else if (status & MCFUART_USR_RXFRAMING) { 30949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->icount.frame++; 31049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 31149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 31249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer status &= port->read_status_mask; 31349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 31449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (status & MCFUART_USR_RXBREAK) 31549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer flag = TTY_BREAK; 31649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer else if (status & MCFUART_USR_RXPARITY) 31749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer flag = TTY_PARITY; 31849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer else if (status & MCFUART_USR_RXFRAMING) 31949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer flag = TTY_FRAME; 32049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 32149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 32249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (uart_handle_sysrq_char(port, ch)) 32349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer continue; 32449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); 32549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 32649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 327ebd2c8f6d2ec4012c267ecb95e72a57b8355a705Alan Cox tty_flip_buffer_push(port->state->port.tty); 32849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 32949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 33049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 33149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 33249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_tx_chars(struct mcf_uart *pp) 33349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 3349f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct uart_port *port = &pp->port; 335ebd2c8f6d2ec4012c267ecb95e72a57b8355a705Alan Cox struct circ_buf *xmit = &port->state->xmit; 33649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 33749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (port->x_char) { 33849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer /* Send special char - probably flow control */ 33949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(port->x_char, port->membase + MCFUART_UTB); 34049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->x_char = 0; 34149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->icount.tx++; 34249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return; 34349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 34449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 34549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) { 34649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (xmit->head == xmit->tail) 34749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer break; 34849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB); 34949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1); 35049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->icount.tx++; 35149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 35249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 35349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 35449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer uart_write_wakeup(port); 35549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 35649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (xmit->head == xmit->tail) { 35749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer pp->imr &= ~MCFUART_UIR_TXREADY; 35849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(pp->imr, port->membase + MCFUART_UIMR); 35949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 36049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 36149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 36249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 36349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 36449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic irqreturn_t mcf_interrupt(int irq, void *data) 36549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 36649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer struct uart_port *port = data; 3679f69ba86d66297189916ceae401fe0944a207714Greg Ungerer struct mcf_uart *pp = container_of(port, struct mcf_uart, port); 36849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer unsigned int isr; 36949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 37049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer isr = readb(port->membase + MCFUART_UISR) & pp->imr; 37149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (isr & MCFUART_UIR_RXREADY) 37249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mcf_rx_chars(pp); 37349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (isr & MCFUART_UIR_TXREADY) 37449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mcf_tx_chars(pp); 37549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return IRQ_HANDLED; 37649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 37749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 37849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 37949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 38049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_config_port(struct uart_port *port, int flags) 38149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 38249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->type = PORT_MCF; 3833732b68f22857201fa09cb82b128f295096a2375Philippe De Muyter port->fifosize = MCFUART_TXFIFOSIZE; 38449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 38549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer /* Clear mask, so no surprise interrupts. */ 38649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(0, port->membase + MCFUART_UIMR); 38749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 38849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (request_irq(port->irq, mcf_interrupt, IRQF_DISABLED, "UART", port)) 38949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer printk(KERN_ERR "MCF: unable to attach ColdFire UART %d " 39049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer "interrupt vector=%d\n", port->line, port->irq); 39149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 39249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 39349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 39449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 39549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic const char *mcf_type(struct uart_port *port) 39649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 39749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return (port->type == PORT_MCF) ? "ColdFire UART" : NULL; 39849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 39949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 40049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 40149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 40249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic int mcf_request_port(struct uart_port *port) 40349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 40449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer /* UARTs always present */ 40549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return 0; 40649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 40749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 40849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 40949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 41049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_release_port(struct uart_port *port) 41149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 41249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer /* Nothing to release... */ 41349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 41449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 41549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 41649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 41749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) 41849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 41949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_MCF)) 42049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return -EINVAL; 42149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return 0; 42249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 42349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 42449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 42549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 42649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/* 42749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * Define the basic serial functions we support. 42849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer */ 4293732b68f22857201fa09cb82b128f295096a2375Philippe De Muyterstatic const struct uart_ops mcf_uart_ops = { 43049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .tx_empty = mcf_tx_empty, 43149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .get_mctrl = mcf_get_mctrl, 43249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .set_mctrl = mcf_set_mctrl, 43349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .start_tx = mcf_start_tx, 43449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .stop_tx = mcf_stop_tx, 43549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .stop_rx = mcf_stop_rx, 43649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .enable_ms = mcf_enable_ms, 43749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .break_ctl = mcf_break_ctl, 43849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .startup = mcf_startup, 43949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .shutdown = mcf_shutdown, 44049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .set_termios = mcf_set_termios, 44149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .type = mcf_type, 44249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .request_port = mcf_request_port, 44349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .release_port = mcf_release_port, 44449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .config_port = mcf_config_port, 44549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .verify_port = mcf_verify_port, 44649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer}; 44749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 4482545cf6e94b4eb5a2c48dd55751aa9a70ff1ff9dPhilippe De Muyterstatic struct mcf_uart mcf_ports[4]; 44949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 45016791963ff7dd6a108251f5fa4b273cf1ffe531fGreg Ungerer#define MCF_MAXPORTS ARRAY_SIZE(mcf_ports) 45149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 45249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 45349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#if defined(CONFIG_SERIAL_MCF_CONSOLE) 45449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 45549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 45649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererint __init early_mcf_setup(struct mcf_platform_uart *platp) 45749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 45849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer struct uart_port *port; 45949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer int i; 46049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 46149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) { 46249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port = &mcf_ports[i].port; 46349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 46449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->line = i; 46549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->type = PORT_MCF; 46649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->mapbase = platp[i].mapbase; 46749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->membase = (platp[i].membase) ? platp[i].membase : 46849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer (unsigned char __iomem *) port->mapbase; 46949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->iotype = SERIAL_IO_MEM; 47049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->irq = platp[i].irq; 47149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->uartclk = MCF_BUSCLK; 47249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->flags = ASYNC_BOOT_AUTOCONF; 47349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->ops = &mcf_uart_ops; 47449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 47549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 47649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return 0; 47749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 47849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 47949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 48049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 48149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_console_putc(struct console *co, const char c) 48249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 48349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer struct uart_port *port = &(mcf_ports + co->index)->port; 48449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer int i; 48549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 48649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer for (i = 0; (i < 0x10000); i++) { 48749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) 48849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer break; 48949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 49049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer writeb(c, port->membase + MCFUART_UTB); 49149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer for (i = 0; (i < 0x10000); i++) { 49249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) 49349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer break; 49449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 49549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 49649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 49749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 49849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 49949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void mcf_console_write(struct console *co, const char *s, unsigned int count) 50049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 50149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer for (; (count); count--, s++) { 50249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mcf_console_putc(co, *s); 50349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (*s == '\n') 50449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer mcf_console_putc(co, '\r'); 50549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 50649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 50749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 50849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 50949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 51049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic int __init mcf_console_setup(struct console *co, char *options) 51149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 51249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer struct uart_port *port; 51349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer int baud = CONFIG_SERIAL_MCF_BAUDRATE; 51449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer int bits = 8; 51549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer int parity = 'n'; 51649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer int flow = 'n'; 51749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 5184330e179a96bc9310d36e9b858bc8f275f329312Len Sorensen if ((co->index < 0) || (co->index >= MCF_MAXPORTS)) 51949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer co->index = 0; 52049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port = &mcf_ports[co->index].port; 52149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (port->membase == 0) 52249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return -ENODEV; 52349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 52449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (options) 52549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer uart_parse_options(options, &baud, &parity, &bits, &flow); 52649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 52749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return uart_set_options(port, co, baud, parity, bits, flow); 52849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 52949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 53049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 53149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 53249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic struct uart_driver mcf_driver; 53349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 53449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic struct console mcf_console = { 53549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .name = "ttyS", 53649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .write = mcf_console_write, 53749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .device = uart_console_device, 53849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .setup = mcf_console_setup, 53949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .flags = CON_PRINTBUFFER, 54049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .index = -1, 54149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .data = &mcf_driver, 54249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer}; 54349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 54449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic int __init mcf_console_init(void) 54549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 54649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer register_console(&mcf_console); 54749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return 0; 54849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 54949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 55049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererconsole_initcall(mcf_console_init); 55149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 55249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#define MCF_CONSOLE &mcf_console 55349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 55449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 55549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#else 55649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 55749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 55849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#define MCF_CONSOLE NULL 55949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 56049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 56149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer#endif /* CONFIG_MCF_CONSOLE */ 56249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 56349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 56449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/* 56549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer * Define the mcf UART driver structure. 56649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer */ 56749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic struct uart_driver mcf_driver = { 56849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .owner = THIS_MODULE, 56949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .driver_name = "mcf", 57049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .dev_name = "ttyS", 57149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .major = TTY_MAJOR, 57249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .minor = 64, 57349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .nr = MCF_MAXPORTS, 57449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .cons = MCF_CONSOLE, 57549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer}; 57649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 57749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 57849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 57949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic int __devinit mcf_probe(struct platform_device *pdev) 58049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 58149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer struct mcf_platform_uart *platp = pdev->dev.platform_data; 58249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer struct uart_port *port; 58349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer int i; 58449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 58549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) { 58649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port = &mcf_ports[i].port; 58749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 58849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->line = i; 58949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->type = PORT_MCF; 59049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->mapbase = platp[i].mapbase; 59149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->membase = (platp[i].membase) ? platp[i].membase : 59249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer (unsigned char __iomem *) platp[i].mapbase; 59349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->iotype = SERIAL_IO_MEM; 59449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->irq = platp[i].irq; 59549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->uartclk = MCF_BUSCLK; 59649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->ops = &mcf_uart_ops; 59749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port->flags = ASYNC_BOOT_AUTOCONF; 59849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 59949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer uart_add_one_port(&mcf_driver, port); 60049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 60149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 60249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return 0; 60349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 60449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 60549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 60649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 607d6f80e3a2a8c49f3e9c350b15f510c6eb8c1770dUwe Kleine-Königstatic int __devexit mcf_remove(struct platform_device *pdev) 60849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 60949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer struct uart_port *port; 61049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer int i; 61149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 61249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer for (i = 0; (i < MCF_MAXPORTS); i++) { 61349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer port = &mcf_ports[i].port; 61449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (port) 61549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer uart_remove_one_port(&mcf_driver, port); 61649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer } 61749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 61849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return 0; 61949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 62049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 62149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 62249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 62349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic struct platform_driver mcf_platform_driver = { 62449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .probe = mcf_probe, 62549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .remove = __devexit_p(mcf_remove), 62649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .driver = { 62749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .name = "mcfuart", 62849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer .owner = THIS_MODULE, 62949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer }, 63049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer}; 63149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 63249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 63349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 63449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic int __init mcf_init(void) 63549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 63649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer int rc; 63749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 63849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer printk("ColdFire internal UART serial driver\n"); 63949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 64049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer rc = uart_register_driver(&mcf_driver); 64149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (rc) 64249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return rc; 64349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer rc = platform_driver_register(&mcf_platform_driver); 64449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer if (rc) 64549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return rc; 64649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer return 0; 64749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 64849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 64949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 65049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 65149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungererstatic void __exit mcf_exit(void) 65249aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer{ 65349aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer platform_driver_unregister(&mcf_platform_driver); 65449aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer uart_unregister_driver(&mcf_driver); 65549aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer} 65649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 65749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 65849aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 65949aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerermodule_init(mcf_init); 66049aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerermodule_exit(mcf_exit); 66149aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 66249aa49bfd40d718095669c1c70c9d167b814e29bGreg UngererMODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>"); 66349aa49bfd40d718095669c1c70c9d167b814e29bGreg UngererMODULE_DESCRIPTION("Freescale ColdFire UART driver"); 66449aa49bfd40d718095669c1c70c9d167b814e29bGreg UngererMODULE_LICENSE("GPL"); 665e169c139642fb4c682ec12a409725508dbefa520Kay SieversMODULE_ALIAS("platform:mcfuart"); 66649aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer 66749aa49bfd40d718095669c1c70c9d167b814e29bGreg Ungerer/****************************************************************************/ 668