Path: blob/master/arch/mn10300/kernel/mn10300-serial.c
10817 views
/* MN10300 On-chip serial port UART driver1*2* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.3* Written by David Howells ([email protected])4*5* This program is free software; you can redistribute it and/or6* modify it under the terms of the GNU General Public Licence7* as published by the Free Software Foundation; either version8* 2 of the Licence, or (at your option) any later version.9*/1011static const char serial_name[] = "MN10300 Serial driver";12static const char serial_version[] = "mn10300_serial-1.0";13static const char serial_revdate[] = "2007-11-06";1415#if defined(CONFIG_MN10300_TTYSM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)16#define SUPPORT_SYSRQ17#endif1819#include <linux/module.h>20#include <linux/serial.h>21#include <linux/circ_buf.h>22#include <linux/errno.h>23#include <linux/signal.h>24#include <linux/sched.h>25#include <linux/timer.h>26#include <linux/interrupt.h>27#include <linux/tty.h>28#include <linux/tty_flip.h>29#include <linux/major.h>30#include <linux/string.h>31#include <linux/ioport.h>32#include <linux/mm.h>33#include <linux/slab.h>34#include <linux/init.h>35#include <linux/console.h>36#include <linux/sysrq.h>3738#include <asm/system.h>39#include <asm/io.h>40#include <asm/irq.h>41#include <asm/bitops.h>42#include <asm/serial-regs.h>43#include <unit/timex.h>44#include "mn10300-serial.h"4546#ifdef CONFIG_SMP47#undef GxICR48#define GxICR(X) CROSS_GxICR(X, 0)49#endif /* CONFIG_SMP */5051#define kenter(FMT, ...) \52printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__)53#define _enter(FMT, ...) \54no_printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__)55#define kdebug(FMT, ...) \56printk(KERN_DEBUG "--- " FMT "\n", ##__VA_ARGS__)57#define _debug(FMT, ...) \58no_printk(KERN_DEBUG "--- " FMT "\n", ##__VA_ARGS__)59#define kproto(FMT, ...) \60printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__)61#define _proto(FMT, ...) \62no_printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__)6364#ifndef CODMSB65/* c_cflag bit meaning */66#define CODMSB 004000000000 /* change Transfer bit-order */67#endif6869#define NR_UARTS 37071#ifdef CONFIG_MN10300_TTYSM_CONSOLE72static void mn10300_serial_console_write(struct console *co,73const char *s, unsigned count);74static int __init mn10300_serial_console_setup(struct console *co,75char *options);7677static struct uart_driver mn10300_serial_driver;78static struct console mn10300_serial_console = {79.name = "ttySM",80.write = mn10300_serial_console_write,81.device = uart_console_device,82.setup = mn10300_serial_console_setup,83.flags = CON_PRINTBUFFER,84.index = -1,85.data = &mn10300_serial_driver,86};87#endif8889static struct uart_driver mn10300_serial_driver = {90.owner = NULL,91.driver_name = "mn10300-serial",92.dev_name = "ttySM",93.major = TTY_MAJOR,94.minor = 128,95.nr = NR_UARTS,96#ifdef CONFIG_MN10300_TTYSM_CONSOLE97.cons = &mn10300_serial_console,98#endif99};100101static unsigned int mn10300_serial_tx_empty(struct uart_port *);102static void mn10300_serial_set_mctrl(struct uart_port *, unsigned int mctrl);103static unsigned int mn10300_serial_get_mctrl(struct uart_port *);104static void mn10300_serial_stop_tx(struct uart_port *);105static void mn10300_serial_start_tx(struct uart_port *);106static void mn10300_serial_send_xchar(struct uart_port *, char ch);107static void mn10300_serial_stop_rx(struct uart_port *);108static void mn10300_serial_enable_ms(struct uart_port *);109static void mn10300_serial_break_ctl(struct uart_port *, int ctl);110static int mn10300_serial_startup(struct uart_port *);111static void mn10300_serial_shutdown(struct uart_port *);112static void mn10300_serial_set_termios(struct uart_port *,113struct ktermios *new,114struct ktermios *old);115static const char *mn10300_serial_type(struct uart_port *);116static void mn10300_serial_release_port(struct uart_port *);117static int mn10300_serial_request_port(struct uart_port *);118static void mn10300_serial_config_port(struct uart_port *, int);119static int mn10300_serial_verify_port(struct uart_port *,120struct serial_struct *);121#ifdef CONFIG_CONSOLE_POLL122static void mn10300_serial_poll_put_char(struct uart_port *, unsigned char);123static int mn10300_serial_poll_get_char(struct uart_port *);124#endif125126static const struct uart_ops mn10300_serial_ops = {127.tx_empty = mn10300_serial_tx_empty,128.set_mctrl = mn10300_serial_set_mctrl,129.get_mctrl = mn10300_serial_get_mctrl,130.stop_tx = mn10300_serial_stop_tx,131.start_tx = mn10300_serial_start_tx,132.send_xchar = mn10300_serial_send_xchar,133.stop_rx = mn10300_serial_stop_rx,134.enable_ms = mn10300_serial_enable_ms,135.break_ctl = mn10300_serial_break_ctl,136.startup = mn10300_serial_startup,137.shutdown = mn10300_serial_shutdown,138.set_termios = mn10300_serial_set_termios,139.type = mn10300_serial_type,140.release_port = mn10300_serial_release_port,141.request_port = mn10300_serial_request_port,142.config_port = mn10300_serial_config_port,143.verify_port = mn10300_serial_verify_port,144#ifdef CONFIG_CONSOLE_POLL145.poll_put_char = mn10300_serial_poll_put_char,146.poll_get_char = mn10300_serial_poll_get_char,147#endif148};149150static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id);151152/*153* the first on-chip serial port: ttySM0 (aka SIF0)154*/155#ifdef CONFIG_MN10300_TTYSM0156struct mn10300_serial_port mn10300_serial_port_sif0 = {157.uart.ops = &mn10300_serial_ops,158.uart.membase = (void __iomem *) &SC0CTR,159.uart.mapbase = (unsigned long) &SC0CTR,160.uart.iotype = UPIO_MEM,161.uart.irq = 0,162.uart.uartclk = 0, /* MN10300_IOCLK, */163.uart.fifosize = 1,164.uart.flags = UPF_BOOT_AUTOCONF,165.uart.line = 0,166.uart.type = PORT_MN10300,167.uart.lock =168__SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif0.uart.lock),169.name = "ttySM0",170._iobase = &SC0CTR,171._control = &SC0CTR,172._status = (volatile u8 *)&SC0STR,173._intr = &SC0ICR,174._rxb = &SC0RXB,175._txb = &SC0TXB,176.rx_name = "ttySM0:Rx",177.tx_name = "ttySM0:Tx",178#if defined(CONFIG_MN10300_TTYSM0_TIMER8)179.tm_name = "ttySM0:Timer8",180._tmxmd = &TM8MD,181._tmxbr = &TM8BR,182._tmicr = &TM8ICR,183.tm_irq = TM8IRQ,184.div_timer = MNSCx_DIV_TIMER_16BIT,185#elif defined(CONFIG_MN10300_TTYSM0_TIMER0)186.tm_name = "ttySM0:Timer0",187._tmxmd = &TM0MD,188._tmxbr = (volatile u16 *)&TM0BR,189._tmicr = &TM0ICR,190.tm_irq = TM0IRQ,191.div_timer = MNSCx_DIV_TIMER_8BIT,192#elif defined(CONFIG_MN10300_TTYSM0_TIMER2)193.tm_name = "ttySM0:Timer2",194._tmxmd = &TM2MD,195._tmxbr = (volatile u16 *)&TM2BR,196._tmicr = &TM2ICR,197.tm_irq = TM2IRQ,198.div_timer = MNSCx_DIV_TIMER_8BIT,199#else200#error "Unknown config for ttySM0"201#endif202.rx_irq = SC0RXIRQ,203.tx_irq = SC0TXIRQ,204.rx_icr = &GxICR(SC0RXIRQ),205.tx_icr = &GxICR(SC0TXIRQ),206.clock_src = MNSCx_CLOCK_SRC_IOCLK,207.options = 0,208#ifdef CONFIG_GDBSTUB_ON_TTYSM0209.gdbstub = 1,210#endif211};212#endif /* CONFIG_MN10300_TTYSM0 */213214/*215* the second on-chip serial port: ttySM1 (aka SIF1)216*/217#ifdef CONFIG_MN10300_TTYSM1218struct mn10300_serial_port mn10300_serial_port_sif1 = {219.uart.ops = &mn10300_serial_ops,220.uart.membase = (void __iomem *) &SC1CTR,221.uart.mapbase = (unsigned long) &SC1CTR,222.uart.iotype = UPIO_MEM,223.uart.irq = 0,224.uart.uartclk = 0, /* MN10300_IOCLK, */225.uart.fifosize = 1,226.uart.flags = UPF_BOOT_AUTOCONF,227.uart.line = 1,228.uart.type = PORT_MN10300,229.uart.lock =230__SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif1.uart.lock),231.name = "ttySM1",232._iobase = &SC1CTR,233._control = &SC1CTR,234._status = (volatile u8 *)&SC1STR,235._intr = &SC1ICR,236._rxb = &SC1RXB,237._txb = &SC1TXB,238.rx_name = "ttySM1:Rx",239.tx_name = "ttySM1:Tx",240#if defined(CONFIG_MN10300_TTYSM1_TIMER9)241.tm_name = "ttySM1:Timer9",242._tmxmd = &TM9MD,243._tmxbr = &TM9BR,244._tmicr = &TM9ICR,245.tm_irq = TM9IRQ,246.div_timer = MNSCx_DIV_TIMER_16BIT,247#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)248.tm_name = "ttySM1:Timer3",249._tmxmd = &TM3MD,250._tmxbr = (volatile u16 *)&TM3BR,251._tmicr = &TM3ICR,252.tm_irq = TM3IRQ,253.div_timer = MNSCx_DIV_TIMER_8BIT,254#elif defined(CONFIG_MN10300_TTYSM1_TIMER12)255.tm_name = "ttySM1/Timer12",256._tmxmd = &TM12MD,257._tmxbr = &TM12BR,258._tmicr = &TM12ICR,259.tm_irq = TM12IRQ,260.div_timer = MNSCx_DIV_TIMER_16BIT,261#else262#error "Unknown config for ttySM1"263#endif264.rx_irq = SC1RXIRQ,265.tx_irq = SC1TXIRQ,266.rx_icr = &GxICR(SC1RXIRQ),267.tx_icr = &GxICR(SC1TXIRQ),268.clock_src = MNSCx_CLOCK_SRC_IOCLK,269.options = 0,270#ifdef CONFIG_GDBSTUB_ON_TTYSM1271.gdbstub = 1,272#endif273};274#endif /* CONFIG_MN10300_TTYSM1 */275276/*277* the third on-chip serial port: ttySM2 (aka SIF2)278*/279#ifdef CONFIG_MN10300_TTYSM2280struct mn10300_serial_port mn10300_serial_port_sif2 = {281.uart.ops = &mn10300_serial_ops,282.uart.membase = (void __iomem *) &SC2CTR,283.uart.mapbase = (unsigned long) &SC2CTR,284.uart.iotype = UPIO_MEM,285.uart.irq = 0,286.uart.uartclk = 0, /* MN10300_IOCLK, */287.uart.fifosize = 1,288.uart.flags = UPF_BOOT_AUTOCONF,289.uart.line = 2,290#ifdef CONFIG_MN10300_TTYSM2_CTS291.uart.type = PORT_MN10300_CTS,292#else293.uart.type = PORT_MN10300,294#endif295.uart.lock =296__SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock),297.name = "ttySM2",298._iobase = &SC2CTR,299._control = &SC2CTR,300._status = (volatile u8 *)&SC2STR,301._intr = &SC2ICR,302._rxb = &SC2RXB,303._txb = &SC2TXB,304.rx_name = "ttySM2:Rx",305.tx_name = "ttySM2:Tx",306#if defined(CONFIG_MN10300_TTYSM2_TIMER10)307.tm_name = "ttySM2/Timer10",308._tmxmd = &TM10MD,309._tmxbr = &TM10BR,310._tmicr = &TM10ICR,311.tm_irq = TM10IRQ,312.div_timer = MNSCx_DIV_TIMER_16BIT,313#elif defined(CONFIG_MN10300_TTYSM2_TIMER9)314.tm_name = "ttySM2/Timer9",315._tmxmd = &TM9MD,316._tmxbr = &TM9BR,317._tmicr = &TM9ICR,318.tm_irq = TM9IRQ,319.div_timer = MNSCx_DIV_TIMER_16BIT,320#elif defined(CONFIG_MN10300_TTYSM2_TIMER1)321.tm_name = "ttySM2/Timer1",322._tmxmd = &TM1MD,323._tmxbr = (volatile u16 *)&TM1BR,324._tmicr = &TM1ICR,325.tm_irq = TM1IRQ,326.div_timer = MNSCx_DIV_TIMER_8BIT,327#elif defined(CONFIG_MN10300_TTYSM2_TIMER3)328.tm_name = "ttySM2/Timer3",329._tmxmd = &TM3MD,330._tmxbr = (volatile u16 *)&TM3BR,331._tmicr = &TM3ICR,332.tm_irq = TM3IRQ,333.div_timer = MNSCx_DIV_TIMER_8BIT,334#else335#error "Unknown config for ttySM2"336#endif337.rx_irq = SC2RXIRQ,338.tx_irq = SC2TXIRQ,339.rx_icr = &GxICR(SC2RXIRQ),340.tx_icr = &GxICR(SC2TXIRQ),341.clock_src = MNSCx_CLOCK_SRC_IOCLK,342#ifdef CONFIG_MN10300_TTYSM2_CTS343.options = MNSCx_OPT_CTS,344#else345.options = 0,346#endif347#ifdef CONFIG_GDBSTUB_ON_TTYSM2348.gdbstub = 1,349#endif350};351#endif /* CONFIG_MN10300_TTYSM2 */352353354/*355* list of available serial ports356*/357struct mn10300_serial_port *mn10300_serial_ports[NR_UARTS + 1] = {358#ifdef CONFIG_MN10300_TTYSM0359[0] = &mn10300_serial_port_sif0,360#endif361#ifdef CONFIG_MN10300_TTYSM1362[1] = &mn10300_serial_port_sif1,363#endif364#ifdef CONFIG_MN10300_TTYSM2365[2] = &mn10300_serial_port_sif2,366#endif367[NR_UARTS] = NULL,368};369370371/*372* we abuse the serial ports' baud timers' interrupt lines to get the ability373* to deliver interrupts to userspace as we use the ports' interrupt lines to374* do virtual DMA on account of the ports having no hardware FIFOs375*376* we can generate an interrupt manually in the assembly stubs by writing to377* the enable and detect bits in the interrupt control register, so all we need378* to do here is disable the interrupt line379*380* note that we can't just leave the line enabled as the baud rate timer *also*381* generates interrupts382*/383static void mn10300_serial_mask_ack(unsigned int irq)384{385unsigned long flags;386u16 tmp;387388flags = arch_local_cli_save();389GxICR(irq) = GxICR_LEVEL_6;390tmp = GxICR(irq); /* flush write buffer */391arch_local_irq_restore(flags);392}393394static void mn10300_serial_chip_mask_ack(struct irq_data *d)395{396mn10300_serial_mask_ack(d->irq);397}398399static void mn10300_serial_nop(struct irq_data *d)400{401}402403static struct irq_chip mn10300_serial_pic = {404.name = "mnserial",405.irq_ack = mn10300_serial_chip_mask_ack,406.irq_mask = mn10300_serial_chip_mask_ack,407.irq_mask_ack = mn10300_serial_chip_mask_ack,408.irq_unmask = mn10300_serial_nop,409};410411412/*413* serial virtual DMA interrupt jump table414*/415struct mn10300_serial_int mn10300_serial_int_tbl[NR_IRQS];416417static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port)418{419unsigned long flags;420u16 x;421422flags = arch_local_cli_save();423*port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);424x = *port->tx_icr;425arch_local_irq_restore(flags);426}427428static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port)429{430unsigned long flags;431u16 x;432433flags = arch_local_cli_save();434*port->tx_icr =435NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | GxICR_ENABLE;436x = *port->tx_icr;437arch_local_irq_restore(flags);438}439440static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port)441{442unsigned long flags;443u16 x;444445flags = arch_local_cli_save();446*port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);447x = *port->rx_icr;448arch_local_irq_restore(flags);449}450451/*452* multi-bit equivalent of test_and_clear_bit()453*/454static int mask_test_and_clear(volatile u8 *ptr, u8 mask)455{456u32 epsw;457asm volatile(" bclr %1,(%2) \n"458" mov epsw,%0 \n"459: "=d"(epsw) : "d"(mask), "a"(ptr)460: "cc", "memory");461return !(epsw & EPSW_FLAG_Z);462}463464/*465* receive chars from the ring buffer for this serial port466* - must do break detection here (not done in the UART)467*/468static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port)469{470struct uart_icount *icount = &port->uart.icount;471struct tty_struct *tty = port->uart.state->port.tty;472unsigned ix;473int count;474u8 st, ch, push, status, overrun;475476_enter("%s", port->name);477478push = 0;479480count = CIRC_CNT(port->rx_inp, port->rx_outp, MNSC_BUFFER_SIZE);481count = tty_buffer_request_room(tty, count);482if (count == 0) {483if (!tty->low_latency)484tty_flip_buffer_push(tty);485return;486}487488try_again:489/* pull chars out of the hat */490ix = port->rx_outp;491if (ix == port->rx_inp) {492if (push && !tty->low_latency)493tty_flip_buffer_push(tty);494return;495}496497ch = port->rx_buffer[ix++];498st = port->rx_buffer[ix++];499smp_rmb();500port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);501port->uart.icount.rx++;502503st &= SC01STR_FEF | SC01STR_PEF | SC01STR_OEF;504status = 0;505overrun = 0;506507/* the UART doesn't detect BREAK, so we have to do that ourselves508* - it starts as a framing error on a NUL character509* - then we count another two NUL characters before issuing TTY_BREAK510* - then we end on a normal char or one that has all the bottom bits511* zero and the top bits set512*/513switch (port->rx_brk) {514case 0:515/* not breaking at the moment */516break;517518case 1:519if (st & SC01STR_FEF && ch == 0) {520port->rx_brk = 2;521goto try_again;522}523goto not_break;524525case 2:526if (st & SC01STR_FEF && ch == 0) {527port->rx_brk = 3;528_proto("Rx Break Detected");529icount->brk++;530if (uart_handle_break(&port->uart))531goto ignore_char;532status |= 1 << TTY_BREAK;533goto insert;534}535goto not_break;536537default:538if (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF))539goto try_again; /* still breaking */540541port->rx_brk = 0; /* end of the break */542543switch (ch) {544case 0xFF:545case 0xFE:546case 0xFC:547case 0xF8:548case 0xF0:549case 0xE0:550case 0xC0:551case 0x80:552case 0x00:553/* discard char at probable break end */554goto try_again;555}556break;557}558559process_errors:560/* handle framing error */561if (st & SC01STR_FEF) {562if (ch == 0) {563/* framing error with NUL char is probably a BREAK */564port->rx_brk = 1;565goto try_again;566}567568_proto("Rx Framing Error");569icount->frame++;570status |= 1 << TTY_FRAME;571}572573/* handle parity error */574if (st & SC01STR_PEF) {575_proto("Rx Parity Error");576icount->parity++;577status = TTY_PARITY;578}579580/* handle normal char */581if (status == 0) {582if (uart_handle_sysrq_char(&port->uart, ch))583goto ignore_char;584status = (1 << TTY_NORMAL);585}586587/* handle overrun error */588if (st & SC01STR_OEF) {589if (port->rx_brk)590goto try_again;591592_proto("Rx Overrun Error");593icount->overrun++;594overrun = 1;595}596597insert:598status &= port->uart.read_status_mask;599600if (!overrun && !(status & port->uart.ignore_status_mask)) {601int flag;602603if (status & (1 << TTY_BREAK))604flag = TTY_BREAK;605else if (status & (1 << TTY_PARITY))606flag = TTY_PARITY;607else if (status & (1 << TTY_FRAME))608flag = TTY_FRAME;609else610flag = TTY_NORMAL;611612tty_insert_flip_char(tty, ch, flag);613}614615/* overrun is special, since it's reported immediately, and doesn't616* affect the current character617*/618if (overrun)619tty_insert_flip_char(tty, 0, TTY_OVERRUN);620621count--;622if (count <= 0) {623if (!tty->low_latency)624tty_flip_buffer_push(tty);625return;626}627628ignore_char:629push = 1;630goto try_again;631632not_break:633port->rx_brk = 0;634goto process_errors;635}636637/*638* handle an interrupt from the serial transmission "virtual DMA" driver639* - note: the interrupt routine will disable its own interrupts when the Tx640* buffer is empty641*/642static void mn10300_serial_transmit_interrupt(struct mn10300_serial_port *port)643{644_enter("%s", port->name);645646if (!port->uart.state || !port->uart.state->port.tty) {647mn10300_serial_dis_tx_intr(port);648return;649}650651if (uart_tx_stopped(&port->uart) ||652uart_circ_empty(&port->uart.state->xmit))653mn10300_serial_dis_tx_intr(port);654655if (uart_circ_chars_pending(&port->uart.state->xmit) < WAKEUP_CHARS)656uart_write_wakeup(&port->uart);657}658659/*660* deal with a change in the status of the CTS line661*/662static void mn10300_serial_cts_changed(struct mn10300_serial_port *port, u8 st)663{664u16 ctr;665666port->tx_cts = st;667port->uart.icount.cts++;668669/* flip the CTS state selector flag to interrupt when it changes670* back */671ctr = *port->_control;672ctr ^= SC2CTR_TWS;673*port->_control = ctr;674675uart_handle_cts_change(&port->uart, st & SC2STR_CTS);676wake_up_interruptible(&port->uart.state->port.delta_msr_wait);677}678679/*680* handle a virtual interrupt generated by the lower level "virtual DMA"681* routines (irq is the baud timer interrupt)682*/683static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id)684{685struct mn10300_serial_port *port = dev_id;686u8 st;687688spin_lock(&port->uart.lock);689690if (port->intr_flags) {691_debug("INT %s: %x", port->name, port->intr_flags);692693if (mask_test_and_clear(&port->intr_flags, MNSCx_RX_AVAIL))694mn10300_serial_receive_interrupt(port);695696if (mask_test_and_clear(&port->intr_flags,697MNSCx_TX_SPACE | MNSCx_TX_EMPTY))698mn10300_serial_transmit_interrupt(port);699}700701/* the only modem control line amongst the whole lot is CTS on702* serial port 2 */703if (port->type == PORT_MN10300_CTS) {704st = *port->_status;705if ((port->tx_cts ^ st) & SC2STR_CTS)706mn10300_serial_cts_changed(port, st);707}708709spin_unlock(&port->uart.lock);710711return IRQ_HANDLED;712}713714/*715* return indication of whether the hardware transmit buffer is empty716*/717static unsigned int mn10300_serial_tx_empty(struct uart_port *_port)718{719struct mn10300_serial_port *port =720container_of(_port, struct mn10300_serial_port, uart);721722_enter("%s", port->name);723724return (*port->_status & (SC01STR_TXF | SC01STR_TBF)) ?7250 : TIOCSER_TEMT;726}727728/*729* set the modem control lines (we don't have any)730*/731static void mn10300_serial_set_mctrl(struct uart_port *_port,732unsigned int mctrl)733{734struct mn10300_serial_port *port __attribute__ ((unused)) =735container_of(_port, struct mn10300_serial_port, uart);736737_enter("%s,%x", port->name, mctrl);738}739740/*741* get the modem control line statuses742*/743static unsigned int mn10300_serial_get_mctrl(struct uart_port *_port)744{745struct mn10300_serial_port *port =746container_of(_port, struct mn10300_serial_port, uart);747748_enter("%s", port->name);749750if (port->type == PORT_MN10300_CTS && !(*port->_status & SC2STR_CTS))751return TIOCM_CAR | TIOCM_DSR;752753return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR;754}755756/*757* stop transmitting characters758*/759static void mn10300_serial_stop_tx(struct uart_port *_port)760{761struct mn10300_serial_port *port =762container_of(_port, struct mn10300_serial_port, uart);763764_enter("%s", port->name);765766/* disable the virtual DMA */767mn10300_serial_dis_tx_intr(port);768}769770/*771* start transmitting characters772* - jump-start transmission if it has stalled773* - enable the serial Tx interrupt (used by the virtual DMA controller)774* - force an interrupt to happen if necessary775*/776static void mn10300_serial_start_tx(struct uart_port *_port)777{778struct mn10300_serial_port *port =779container_of(_port, struct mn10300_serial_port, uart);780781u16 x;782783_enter("%s{%lu}",784port->name,785CIRC_CNT(&port->uart.state->xmit.head,786&port->uart.state->xmit.tail,787UART_XMIT_SIZE));788789/* kick the virtual DMA controller */790arch_local_cli();791x = *port->tx_icr;792x |= GxICR_ENABLE;793794if (*port->_status & SC01STR_TBF)795x &= ~(GxICR_REQUEST | GxICR_DETECT);796else797x |= GxICR_REQUEST | GxICR_DETECT;798799_debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx",800*port->_control, *port->_intr, *port->_status,801*port->_tmxmd,802(port->div_timer == MNSCx_DIV_TIMER_8BIT) ?803*(volatile u8 *)port->_tmxbr : *port->_tmxbr,804*port->tx_icr);805806*port->tx_icr = x;807x = *port->tx_icr;808arch_local_sti();809}810811/*812* transmit a high-priority XON/XOFF character813*/814static void mn10300_serial_send_xchar(struct uart_port *_port, char ch)815{816struct mn10300_serial_port *port =817container_of(_port, struct mn10300_serial_port, uart);818819_enter("%s,%02x", port->name, ch);820821if (likely(port->gdbstub)) {822port->tx_xchar = ch;823if (ch)824mn10300_serial_en_tx_intr(port);825}826}827828/*829* stop receiving characters830* - called whilst the port is being closed831*/832static void mn10300_serial_stop_rx(struct uart_port *_port)833{834struct mn10300_serial_port *port =835container_of(_port, struct mn10300_serial_port, uart);836837u16 ctr;838839_enter("%s", port->name);840841ctr = *port->_control;842ctr &= ~SC01CTR_RXE;843*port->_control = ctr;844845mn10300_serial_dis_rx_intr(port);846}847848/*849* enable modem status interrupts850*/851static void mn10300_serial_enable_ms(struct uart_port *_port)852{853struct mn10300_serial_port *port =854container_of(_port, struct mn10300_serial_port, uart);855856u16 ctr, cts;857858_enter("%s", port->name);859860if (port->type == PORT_MN10300_CTS) {861/* want to interrupt when CTS goes low if CTS is now high and862* vice versa863*/864port->tx_cts = *port->_status;865866cts = (port->tx_cts & SC2STR_CTS) ?867SC2CTR_TWE : SC2CTR_TWE | SC2CTR_TWS;868869ctr = *port->_control;870ctr &= ~SC2CTR_TWS;871ctr |= cts;872*port->_control = ctr;873874mn10300_serial_en_tx_intr(port);875}876}877878/*879* transmit or cease transmitting a break signal880*/881static void mn10300_serial_break_ctl(struct uart_port *_port, int ctl)882{883struct mn10300_serial_port *port =884container_of(_port, struct mn10300_serial_port, uart);885886_enter("%s,%d", port->name, ctl);887888if (ctl) {889/* tell the virtual DMA handler to assert BREAK */890port->tx_break = 1;891mn10300_serial_en_tx_intr(port);892} else {893port->tx_break = 0;894*port->_control &= ~SC01CTR_BKE;895mn10300_serial_en_tx_intr(port);896}897}898899/*900* grab the interrupts and enable the port for reception901*/902static int mn10300_serial_startup(struct uart_port *_port)903{904struct mn10300_serial_port *port =905container_of(_port, struct mn10300_serial_port, uart);906struct mn10300_serial_int *pint;907908_enter("%s{%d}", port->name, port->gdbstub);909910if (unlikely(port->gdbstub))911return -EBUSY;912913/* allocate an Rx buffer for the virtual DMA handler */914port->rx_buffer = kmalloc(MNSC_BUFFER_SIZE, GFP_KERNEL);915if (!port->rx_buffer)916return -ENOMEM;917918port->rx_inp = port->rx_outp = 0;919920/* finally, enable the device */921*port->_intr = SC01ICR_TI;922*port->_control |= SC01CTR_TXE | SC01CTR_RXE;923924pint = &mn10300_serial_int_tbl[port->rx_irq];925pint->port = port;926pint->vdma = mn10300_serial_vdma_rx_handler;927pint = &mn10300_serial_int_tbl[port->tx_irq];928pint->port = port;929pint->vdma = mn10300_serial_vdma_tx_handler;930931set_intr_level(port->rx_irq,932NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));933set_intr_level(port->tx_irq,934NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));935irq_set_chip(port->tm_irq, &mn10300_serial_pic);936937if (request_irq(port->rx_irq, mn10300_serial_interrupt,938IRQF_DISABLED, port->rx_name, port) < 0)939goto error;940941if (request_irq(port->tx_irq, mn10300_serial_interrupt,942IRQF_DISABLED, port->tx_name, port) < 0)943goto error2;944945if (request_irq(port->tm_irq, mn10300_serial_interrupt,946IRQF_DISABLED, port->tm_name, port) < 0)947goto error3;948mn10300_serial_mask_ack(port->tm_irq);949950return 0;951952error3:953free_irq(port->tx_irq, port);954error2:955free_irq(port->rx_irq, port);956error:957kfree(port->rx_buffer);958port->rx_buffer = NULL;959return -EBUSY;960}961962/*963* shutdown the port and release interrupts964*/965static void mn10300_serial_shutdown(struct uart_port *_port)966{967u16 x;968struct mn10300_serial_port *port =969container_of(_port, struct mn10300_serial_port, uart);970971_enter("%s", port->name);972973/* disable the serial port and its baud rate timer */974port->tx_break = 0;975*port->_control &= ~(SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE);976*port->_tmxmd = 0;977978if (port->rx_buffer) {979void *buf = port->rx_buffer;980port->rx_buffer = NULL;981kfree(buf);982}983984/* disable all intrs */985free_irq(port->tm_irq, port);986free_irq(port->rx_irq, port);987free_irq(port->tx_irq, port);988989arch_local_cli();990*port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);991x = *port->rx_icr;992*port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);993x = *port->tx_icr;994arch_local_sti();995}996997/*998* this routine is called to set the UART divisor registers to match the999* specified baud rate for a serial port.1000*/1001static void mn10300_serial_change_speed(struct mn10300_serial_port *port,1002struct ktermios *new,1003struct ktermios *old)1004{1005unsigned long flags;1006unsigned long ioclk = port->ioclk;1007unsigned cflag;1008int baud, bits, xdiv, tmp;1009u16 tmxbr, scxctr;1010u8 tmxmd, battempt;1011u8 div_timer = port->div_timer;10121013_enter("%s{%lu}", port->name, ioclk);10141015/* byte size and parity */1016cflag = new->c_cflag;1017switch (cflag & CSIZE) {1018case CS7: scxctr = SC01CTR_CLN_7BIT; bits = 9; break;1019case CS8: scxctr = SC01CTR_CLN_8BIT; bits = 10; break;1020default: scxctr = SC01CTR_CLN_8BIT; bits = 10; break;1021}10221023if (cflag & CSTOPB) {1024scxctr |= SC01CTR_STB_2BIT;1025bits++;1026}10271028if (cflag & PARENB) {1029bits++;1030if (cflag & PARODD)1031scxctr |= SC01CTR_PB_ODD;1032#ifdef CMSPAR1033else if (cflag & CMSPAR)1034scxctr |= SC01CTR_PB_FIXED0;1035#endif1036else1037scxctr |= SC01CTR_PB_EVEN;1038}10391040/* Determine divisor based on baud rate */1041battempt = 0;10421043switch (port->uart.line) {1044#ifdef CONFIG_MN10300_TTYSM01045case 0: /* ttySM0 */1046#if defined(CONFIG_MN10300_TTYSM0_TIMER8)1047scxctr |= SC0CTR_CK_TM8UFLOW_8;1048#elif defined(CONFIG_MN10300_TTYSM0_TIMER0)1049scxctr |= SC0CTR_CK_TM0UFLOW_8;1050#elif defined(CONFIG_MN10300_TTYSM0_TIMER2)1051scxctr |= SC0CTR_CK_TM2UFLOW_8;1052#else1053#error "Unknown config for ttySM0"1054#endif1055break;1056#endif /* CONFIG_MN10300_TTYSM0 */10571058#ifdef CONFIG_MN10300_TTYSM11059case 1: /* ttySM1 */1060#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)1061#if defined(CONFIG_MN10300_TTYSM1_TIMER9)1062scxctr |= SC1CTR_CK_TM9UFLOW_8;1063#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)1064scxctr |= SC1CTR_CK_TM3UFLOW_8;1065#else1066#error "Unknown config for ttySM1"1067#endif1068#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */1069#if defined(CONFIG_MN10300_TTYSM1_TIMER12)1070scxctr |= SC1CTR_CK_TM12UFLOW_8;1071#else1072#error "Unknown config for ttySM1"1073#endif1074#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */1075break;1076#endif /* CONFIG_MN10300_TTYSM1 */10771078#ifdef CONFIG_MN10300_TTYSM21079case 2: /* ttySM2 */1080#if defined(CONFIG_AM33_2)1081#if defined(CONFIG_MN10300_TTYSM2_TIMER10)1082scxctr |= SC2CTR_CK_TM10UFLOW;1083#else1084#error "Unknown config for ttySM2"1085#endif1086#else /* CONFIG_AM33_2 */1087#if defined(CONFIG_MN10300_TTYSM2_TIMER9)1088scxctr |= SC2CTR_CK_TM9UFLOW_8;1089#elif defined(CONFIG_MN10300_TTYSM2_TIMER1)1090scxctr |= SC2CTR_CK_TM1UFLOW_8;1091#elif defined(CONFIG_MN10300_TTYSM2_TIMER3)1092scxctr |= SC2CTR_CK_TM3UFLOW_8;1093#else1094#error "Unknown config for ttySM2"1095#endif1096#endif /* CONFIG_AM33_2 */1097break;1098#endif /* CONFIG_MN10300_TTYSM2 */10991100default:1101break;1102}11031104try_alternative:1105baud = uart_get_baud_rate(&port->uart, new, old, 0,1106port->ioclk / 8);11071108_debug("ALT %d [baud %d]", battempt, baud);11091110if (!baud)1111baud = 9600; /* B0 transition handled in rs_set_termios */1112xdiv = 1;1113if (baud == 134) {1114baud = 269; /* 134 is really 134.5 */1115xdiv = 2;1116}11171118if (baud == 38400 &&1119(port->uart.flags & UPF_SPD_MASK) == UPF_SPD_CUST1120) {1121_debug("CUSTOM %u", port->uart.custom_divisor);11221123if (div_timer == MNSCx_DIV_TIMER_16BIT) {1124if (port->uart.custom_divisor <= 65535) {1125tmxmd = TM8MD_SRC_IOCLK;1126tmxbr = port->uart.custom_divisor;1127port->uart.uartclk = ioclk;1128goto timer_okay;1129}1130if (port->uart.custom_divisor / 8 <= 65535) {1131tmxmd = TM8MD_SRC_IOCLK_8;1132tmxbr = port->uart.custom_divisor / 8;1133port->uart.custom_divisor = tmxbr * 8;1134port->uart.uartclk = ioclk / 8;1135goto timer_okay;1136}1137if (port->uart.custom_divisor / 32 <= 65535) {1138tmxmd = TM8MD_SRC_IOCLK_32;1139tmxbr = port->uart.custom_divisor / 32;1140port->uart.custom_divisor = tmxbr * 32;1141port->uart.uartclk = ioclk / 32;1142goto timer_okay;1143}11441145} else if (div_timer == MNSCx_DIV_TIMER_8BIT) {1146if (port->uart.custom_divisor <= 255) {1147tmxmd = TM2MD_SRC_IOCLK;1148tmxbr = port->uart.custom_divisor;1149port->uart.uartclk = ioclk;1150goto timer_okay;1151}1152if (port->uart.custom_divisor / 8 <= 255) {1153tmxmd = TM2MD_SRC_IOCLK_8;1154tmxbr = port->uart.custom_divisor / 8;1155port->uart.custom_divisor = tmxbr * 8;1156port->uart.uartclk = ioclk / 8;1157goto timer_okay;1158}1159if (port->uart.custom_divisor / 32 <= 255) {1160tmxmd = TM2MD_SRC_IOCLK_32;1161tmxbr = port->uart.custom_divisor / 32;1162port->uart.custom_divisor = tmxbr * 32;1163port->uart.uartclk = ioclk / 32;1164goto timer_okay;1165}1166}1167}11681169switch (div_timer) {1170case MNSCx_DIV_TIMER_16BIT:1171port->uart.uartclk = ioclk;1172tmxmd = TM8MD_SRC_IOCLK;1173tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;1174if (tmp > 0 && tmp <= 65535)1175goto timer_okay;11761177port->uart.uartclk = ioclk / 8;1178tmxmd = TM8MD_SRC_IOCLK_8;1179tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;1180if (tmp > 0 && tmp <= 65535)1181goto timer_okay;11821183port->uart.uartclk = ioclk / 32;1184tmxmd = TM8MD_SRC_IOCLK_32;1185tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;1186if (tmp > 0 && tmp <= 65535)1187goto timer_okay;1188break;11891190case MNSCx_DIV_TIMER_8BIT:1191port->uart.uartclk = ioclk;1192tmxmd = TM2MD_SRC_IOCLK;1193tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;1194if (tmp > 0 && tmp <= 255)1195goto timer_okay;11961197port->uart.uartclk = ioclk / 8;1198tmxmd = TM2MD_SRC_IOCLK_8;1199tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;1200if (tmp > 0 && tmp <= 255)1201goto timer_okay;12021203port->uart.uartclk = ioclk / 32;1204tmxmd = TM2MD_SRC_IOCLK_32;1205tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;1206if (tmp > 0 && tmp <= 255)1207goto timer_okay;1208break;12091210default:1211BUG();1212return;1213}12141215/* refuse to change to a baud rate we can't support */1216_debug("CAN'T SUPPORT");12171218switch (battempt) {1219case 0:1220if (old) {1221new->c_cflag &= ~CBAUD;1222new->c_cflag |= (old->c_cflag & CBAUD);1223battempt = 1;1224goto try_alternative;1225}12261227case 1:1228/* as a last resort, if the quotient is zero, default to 96001229* bps */1230new->c_cflag &= ~CBAUD;1231new->c_cflag |= B9600;1232battempt = 2;1233goto try_alternative;12341235default:1236/* hmmm... can't seem to support 9600 either1237* - we could try iterating through the speeds we know about to1238* find the lowest1239*/1240new->c_cflag &= ~CBAUD;1241new->c_cflag |= B0;12421243if (div_timer == MNSCx_DIV_TIMER_16BIT)1244tmxmd = TM8MD_SRC_IOCLK_32;1245else if (div_timer == MNSCx_DIV_TIMER_8BIT)1246tmxmd = TM2MD_SRC_IOCLK_32;1247tmxbr = 1;12481249port->uart.uartclk = ioclk / 32;1250break;1251}1252timer_okay:12531254_debug("UARTCLK: %u / %hu", port->uart.uartclk, tmxbr);12551256/* make the changes */1257spin_lock_irqsave(&port->uart.lock, flags);12581259uart_update_timeout(&port->uart, new->c_cflag, baud);12601261/* set the timer to produce the required baud rate */1262switch (div_timer) {1263case MNSCx_DIV_TIMER_16BIT:1264*port->_tmxmd = 0;1265*port->_tmxbr = tmxbr;1266*port->_tmxmd = TM8MD_INIT_COUNTER;1267*port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE;1268break;12691270case MNSCx_DIV_TIMER_8BIT:1271*port->_tmxmd = 0;1272*(volatile u8 *) port->_tmxbr = (u8) tmxbr;1273*port->_tmxmd = TM2MD_INIT_COUNTER;1274*port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE;1275break;1276}12771278/* CTS flow control flag and modem status interrupts */1279scxctr &= ~(SC2CTR_TWE | SC2CTR_TWS);12801281if (port->type == PORT_MN10300_CTS && cflag & CRTSCTS) {1282/* want to interrupt when CTS goes low if CTS is now1283* high and vice versa1284*/1285port->tx_cts = *port->_status;12861287if (port->tx_cts & SC2STR_CTS)1288scxctr |= SC2CTR_TWE;1289else1290scxctr |= SC2CTR_TWE | SC2CTR_TWS;1291}12921293/* set up parity check flag */1294port->uart.read_status_mask = (1 << TTY_NORMAL) | (1 << TTY_OVERRUN);1295if (new->c_iflag & INPCK)1296port->uart.read_status_mask |=1297(1 << TTY_PARITY) | (1 << TTY_FRAME);1298if (new->c_iflag & (BRKINT | PARMRK))1299port->uart.read_status_mask |= (1 << TTY_BREAK);13001301/* characters to ignore */1302port->uart.ignore_status_mask = 0;1303if (new->c_iflag & IGNPAR)1304port->uart.ignore_status_mask |=1305(1 << TTY_PARITY) | (1 << TTY_FRAME);1306if (new->c_iflag & IGNBRK) {1307port->uart.ignore_status_mask |= (1 << TTY_BREAK);1308/*1309* If we're ignoring parity and break indicators,1310* ignore overruns to (for real raw support).1311*/1312if (new->c_iflag & IGNPAR)1313port->uart.ignore_status_mask |= (1 << TTY_OVERRUN);1314}13151316/* Ignore all characters if CREAD is not set */1317if ((new->c_cflag & CREAD) == 0)1318port->uart.ignore_status_mask |= (1 << TTY_NORMAL);13191320scxctr |= *port->_control & (SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE);1321*port->_control = scxctr;13221323spin_unlock_irqrestore(&port->uart.lock, flags);1324}13251326/*1327* set the terminal I/O parameters1328*/1329static void mn10300_serial_set_termios(struct uart_port *_port,1330struct ktermios *new,1331struct ktermios *old)1332{1333struct mn10300_serial_port *port =1334container_of(_port, struct mn10300_serial_port, uart);13351336_enter("%s,%p,%p", port->name, new, old);13371338mn10300_serial_change_speed(port, new, old);13391340/* handle turning off CRTSCTS */1341if (!(new->c_cflag & CRTSCTS)) {1342u16 ctr = *port->_control;1343ctr &= ~SC2CTR_TWE;1344*port->_control = ctr;1345}13461347/* change Transfer bit-order (LSB/MSB) */1348if (new->c_cflag & CODMSB)1349*port->_control |= SC01CTR_OD_MSBFIRST; /* MSB MODE */1350else1351*port->_control &= ~SC01CTR_OD_MSBFIRST; /* LSB MODE */1352}13531354/*1355* return description of port type1356*/1357static const char *mn10300_serial_type(struct uart_port *_port)1358{1359struct mn10300_serial_port *port =1360container_of(_port, struct mn10300_serial_port, uart);13611362if (port->uart.type == PORT_MN10300_CTS)1363return "MN10300 SIF_CTS";13641365return "MN10300 SIF";1366}13671368/*1369* release I/O and memory regions in use by port1370*/1371static void mn10300_serial_release_port(struct uart_port *_port)1372{1373struct mn10300_serial_port *port =1374container_of(_port, struct mn10300_serial_port, uart);13751376_enter("%s", port->name);13771378release_mem_region((unsigned long) port->_iobase, 16);1379}13801381/*1382* request I/O and memory regions for port1383*/1384static int mn10300_serial_request_port(struct uart_port *_port)1385{1386struct mn10300_serial_port *port =1387container_of(_port, struct mn10300_serial_port, uart);13881389_enter("%s", port->name);13901391request_mem_region((unsigned long) port->_iobase, 16, port->name);1392return 0;1393}13941395/*1396* configure the type and reserve the ports1397*/1398static void mn10300_serial_config_port(struct uart_port *_port, int type)1399{1400struct mn10300_serial_port *port =1401container_of(_port, struct mn10300_serial_port, uart);14021403_enter("%s", port->name);14041405port->uart.type = PORT_MN10300;14061407if (port->options & MNSCx_OPT_CTS)1408port->uart.type = PORT_MN10300_CTS;14091410mn10300_serial_request_port(_port);1411}14121413/*1414* verify serial parameters are suitable for this port type1415*/1416static int mn10300_serial_verify_port(struct uart_port *_port,1417struct serial_struct *ss)1418{1419struct mn10300_serial_port *port =1420container_of(_port, struct mn10300_serial_port, uart);1421void *mapbase = (void *) (unsigned long) port->uart.mapbase;14221423_enter("%s", port->name);14241425/* these things may not be changed */1426if (ss->irq != port->uart.irq ||1427ss->port != port->uart.iobase ||1428ss->io_type != port->uart.iotype ||1429ss->iomem_base != mapbase ||1430ss->iomem_reg_shift != port->uart.regshift ||1431ss->hub6 != port->uart.hub6 ||1432ss->xmit_fifo_size != port->uart.fifosize)1433return -EINVAL;14341435/* type may be changed on a port that supports CTS */1436if (ss->type != port->uart.type) {1437if (!(port->options & MNSCx_OPT_CTS))1438return -EINVAL;14391440if (ss->type != PORT_MN10300 &&1441ss->type != PORT_MN10300_CTS)1442return -EINVAL;1443}14441445return 0;1446}14471448/*1449* initialise the MN10300 on-chip UARTs1450*/1451static int __init mn10300_serial_init(void)1452{1453struct mn10300_serial_port *port;1454int ret, i;14551456printk(KERN_INFO "%s version %s (%s)\n",1457serial_name, serial_version, serial_revdate);14581459#if defined(CONFIG_MN10300_TTYSM2) && defined(CONFIG_AM33_2)1460{1461int tmp;1462SC2TIM = 8; /* make the baud base of timer 2 IOCLK/8 */1463tmp = SC2TIM;1464}1465#endif14661467set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL),1468mn10300_serial_vdma_interrupt);14691470ret = uart_register_driver(&mn10300_serial_driver);1471if (!ret) {1472for (i = 0 ; i < NR_PORTS ; i++) {1473port = mn10300_serial_ports[i];1474if (!port || port->gdbstub)1475continue;14761477switch (port->clock_src) {1478case MNSCx_CLOCK_SRC_IOCLK:1479port->ioclk = MN10300_IOCLK;1480break;14811482#ifdef MN10300_IOBCLK1483case MNSCx_CLOCK_SRC_IOBCLK:1484port->ioclk = MN10300_IOBCLK;1485break;1486#endif1487default:1488BUG();1489}14901491ret = uart_add_one_port(&mn10300_serial_driver,1492&port->uart);14931494if (ret < 0) {1495_debug("ERROR %d", -ret);1496break;1497}1498}14991500if (ret)1501uart_unregister_driver(&mn10300_serial_driver);1502}15031504return ret;1505}15061507__initcall(mn10300_serial_init);150815091510#ifdef CONFIG_MN10300_TTYSM_CONSOLE15111512/*1513* print a string to the serial port without disturbing the real user of the1514* port too much1515* - the console must be locked by the caller1516*/1517static void mn10300_serial_console_write(struct console *co,1518const char *s, unsigned count)1519{1520struct mn10300_serial_port *port;1521unsigned i;1522u16 scxctr, txicr, tmp;1523u8 tmxmd;15241525port = mn10300_serial_ports[co->index];15261527/* firstly hijack the serial port from the "virtual DMA" controller */1528arch_local_cli();1529txicr = *port->tx_icr;1530*port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);1531tmp = *port->tx_icr;1532arch_local_sti();15331534/* the transmitter may be disabled */1535scxctr = *port->_control;1536if (!(scxctr & SC01CTR_TXE)) {1537/* restart the UART clock */1538tmxmd = *port->_tmxmd;15391540switch (port->div_timer) {1541case MNSCx_DIV_TIMER_16BIT:1542*port->_tmxmd = 0;1543*port->_tmxmd = TM8MD_INIT_COUNTER;1544*port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE;1545break;15461547case MNSCx_DIV_TIMER_8BIT:1548*port->_tmxmd = 0;1549*port->_tmxmd = TM2MD_INIT_COUNTER;1550*port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE;1551break;1552}15531554/* enable the transmitter */1555*port->_control = (scxctr & ~SC01CTR_BKE) | SC01CTR_TXE;15561557} else if (scxctr & SC01CTR_BKE) {1558/* stop transmitting BREAK */1559*port->_control = (scxctr & ~SC01CTR_BKE);1560}15611562/* send the chars into the serial port (with LF -> LFCR conversion) */1563for (i = 0; i < count; i++) {1564char ch = *s++;15651566while (*port->_status & SC01STR_TBF)1567continue;1568*(u8 *) port->_txb = ch;15691570if (ch == 0x0a) {1571while (*port->_status & SC01STR_TBF)1572continue;1573*(u8 *) port->_txb = 0xd;1574}1575}15761577/* can't let the transmitter be turned off if it's actually1578* transmitting */1579while (*port->_status & (SC01STR_TXF | SC01STR_TBF))1580continue;15811582/* disable the transmitter if we re-enabled it */1583if (!(scxctr & SC01CTR_TXE))1584*port->_control = scxctr;15851586arch_local_cli();1587*port->tx_icr = txicr;1588tmp = *port->tx_icr;1589arch_local_sti();1590}15911592/*1593* set up a serial port as a console1594* - construct a cflag setting for the first rs_open()1595* - initialize the serial port1596* - return non-zero if we didn't find a serial port.1597*/1598static int __init mn10300_serial_console_setup(struct console *co,1599char *options)1600{1601struct mn10300_serial_port *port;1602int i, parity = 'n', baud = 9600, bits = 8, flow = 0;16031604for (i = 0 ; i < NR_PORTS ; i++) {1605port = mn10300_serial_ports[i];1606if (port && !port->gdbstub && port->uart.line == co->index)1607goto found_device;1608}16091610return -ENODEV;16111612found_device:1613switch (port->clock_src) {1614case MNSCx_CLOCK_SRC_IOCLK:1615port->ioclk = MN10300_IOCLK;1616break;16171618#ifdef MN10300_IOBCLK1619case MNSCx_CLOCK_SRC_IOBCLK:1620port->ioclk = MN10300_IOBCLK;1621break;1622#endif1623default:1624BUG();1625}16261627if (options)1628uart_parse_options(options, &baud, &parity, &bits, &flow);16291630return uart_set_options(&port->uart, co, baud, parity, bits, flow);1631}16321633/*1634* register console1635*/1636static int __init mn10300_serial_console_init(void)1637{1638register_console(&mn10300_serial_console);1639return 0;1640}16411642console_initcall(mn10300_serial_console_init);1643#endif16441645#ifdef CONFIG_CONSOLE_POLL1646/*1647* Polled character reception for the kernel debugger1648*/1649static int mn10300_serial_poll_get_char(struct uart_port *_port)1650{1651struct mn10300_serial_port *port =1652container_of(_port, struct mn10300_serial_port, uart);1653unsigned ix;1654u8 st, ch;16551656_enter("%s", port->name);16571658do {1659/* pull chars out of the hat */1660ix = port->rx_outp;1661if (ix == port->rx_inp)1662return NO_POLL_CHAR;16631664ch = port->rx_buffer[ix++];1665st = port->rx_buffer[ix++];1666smp_rmb();1667port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);16681669} while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));16701671return ch;1672}167316741675/*1676* Polled character transmission for the kernel debugger1677*/1678static void mn10300_serial_poll_put_char(struct uart_port *_port,1679unsigned char ch)1680{1681struct mn10300_serial_port *port =1682container_of(_port, struct mn10300_serial_port, uart);1683u8 intr, tmp;16841685/* wait for the transmitter to finish anything it might be doing (and1686* this includes the virtual DMA handler, so it might take a while) */1687while (*port->_status & (SC01STR_TBF | SC01STR_TXF))1688continue;16891690/* disable the Tx ready interrupt */1691intr = *port->_intr;1692*port->_intr = intr & ~SC01ICR_TI;1693tmp = *port->_intr;16941695if (ch == 0x0a) {1696*(u8 *) port->_txb = 0x0d;1697while (*port->_status & SC01STR_TBF)1698continue;1699}17001701*(u8 *) port->_txb = ch;1702while (*port->_status & SC01STR_TBF)1703continue;17041705/* restore the Tx interrupt flag */1706*port->_intr = intr;1707tmp = *port->_intr;1708}17091710#endif /* CONFIG_CONSOLE_POLL */171117121713