]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge commit 'v2.6.38-rc4' into imx-for-2.6.39
authorSascha Hauer <s.hauer@pengutronix.de>
Fri, 11 Feb 2011 07:32:18 +0000 (08:32 +0100)
committerSascha Hauer <s.hauer@pengutronix.de>
Fri, 11 Feb 2011 07:33:14 +0000 (08:33 +0100)
Conflicts:
arch/arm/mach-mxs/clock-mx28.c

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
1  2 
arch/arm/mach-imx/mach-mx25_3ds.c
arch/arm/mach-mxs/clock-mx28.c
arch/arm/mach-mxs/gpio.c
arch/arm/plat-mxc/include/mach/uncompress.h
drivers/tty/serial/Kconfig
drivers/tty/serial/Makefile
drivers/tty/serial/mxs-auart.c

index 0c92a80eac46cb9456950cd299166882a27c30db,8382e790207888b7c8255b73beb16c2b3184f713..cd18a0c91b837a491e217b9606949d6eaff60f9a
@@@ -180,7 -180,7 +180,7 @@@ static const uint32_t mx25pdk_keymap[] 
        KEY(3, 3, KEY_POWER),
  };
  
- static const struct matrix_keymap_data mx25pdk_keymap_data __initdata = {
+ static const struct matrix_keymap_data mx25pdk_keymap_data __initconst = {
        .keymap         = mx25pdk_keymap,
        .keymap_size    = ARRAY_SIZE(mx25pdk_keymap),
  };
@@@ -226,10 -226,10 +226,10 @@@ static struct sys_timer mx25pdk_timer 
  
  MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
        /* Maintainer: Freescale Semiconductor, Inc. */
 -      .boot_params    = MX25_PHYS_OFFSET + 0x100,
 -      .map_io         = mx25_map_io,
 -      .init_irq       = mx25_init_irq,
 -      .init_machine   = mx25pdk_init,
 -      .timer          = &mx25pdk_timer,
 +      .boot_params = MX25_PHYS_OFFSET + 0x100,
 +      .map_io = mx25_map_io,
 +      .init_early = imx25_init_early,
 +      .init_irq = mx25_init_irq,
 +      .timer = &mx25pdk_timer,
 +      .init_machine = mx25pdk_init,
  MACHINE_END
 -
index c9d7951e8bfb39c44f33092dc2e1bc5d9a8bd374,fd1c4c54b8e510d76ddbb0b157fc1a9cb5655ac8..febd787f054f7661c2ead686e6bc80733a3e81a8
@@@ -355,12 -355,12 +355,12 @@@ static int name##_set_rate(struct clk *
        } else {                                                        \
                reg &= ~BM_CLKCTRL_##dr##_DIV;                          \
                reg |= div << BP_CLKCTRL_##dr##_DIV;                    \
-               if (reg | (1 << clk->enable_shift)) {                   \
+               if (reg & (1 << clk->enable_shift)) {                   \
                        pr_err("%s: clock is gated\n", __func__);       \
                        return -EINVAL;                                 \
                }                                                       \
        }                                                               \
-       __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);          \
+       __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);         \
                                                                        \
        for (i = 10000; i; i--)                                         \
                if (!(__raw_readl(CLKCTRL_BASE_ADDR +                   \
@@@ -483,7 -483,7 +483,7 @@@ static int name##_set_parent(struct cl
  {                                                                     \
        if (parent != clk->parent) {                                    \
                __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,            \
-                        HW_CLKCTRL_CLKSEQ_TOG);                        \
+                        CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG);    \
                clk->parent = parent;                                   \
        }                                                               \
                                                                        \
@@@ -609,18 -609,12 +609,17 @@@ static struct clk_lookup lookups[] = 
        _REGISTER_CLOCK("duart", NULL, uart_clk)
        _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
        _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
-       _REGISTER_CLOCK("fec.0", NULL, fec_clk)
 +      _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
 +      _REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk)
 +      _REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk)
 +      _REGISTER_CLOCK("mxs-auart.3", NULL, uart_clk)
 +      _REGISTER_CLOCK("mxs-auart.4", NULL, uart_clk)
        _REGISTER_CLOCK("rtc", NULL, rtc_clk)
        _REGISTER_CLOCK("pll2", NULL, pll2_clk)
        _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
        _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
 -      _REGISTER_CLOCK(NULL, "can0", can0_clk)
 -      _REGISTER_CLOCK(NULL, "can1", can1_clk)
 +      _REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
 +      _REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
        _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
        _REGISTER_CLOCK(NULL, "usb1", usb1_clk)
        _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
diff --combined arch/arm/mach-mxs/gpio.c
index 8bcb340422527451a4bdd7e2ce7c5c4a6a29ed4e,cb0c0e83a527a8d5367e0f2b0ca376d5f86a674f..64848fa3af3be52abd51a66289ab748c27d87cc1
@@@ -139,6 -139,8 +139,8 @@@ static void mxs_gpio_irq_handler(u32 ir
        struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
        u32 gpio_irq_no_base = port->virtual_irq_start;
  
+       desc->irq_data.chip->irq_ack(&desc->irq_data);
        irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
                        __raw_readl(port->base + PINCTRL_IRQEN(port->id));
  
@@@ -287,42 -289,39 +289,42 @@@ int __init mxs_gpio_init(struct mxs_gpi
        return 0;
  }
  
 -#define DEFINE_MXS_GPIO_PORT(soc, _id)                                        \
 +#define MX23_GPIO_BASE        MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR)
 +#define MX28_GPIO_BASE        MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR)
 +
 +#define DEFINE_MXS_GPIO_PORT(_base, _irq, _id)                                \
        {                                                               \
                .chip.label = "gpio-" #_id,                             \
                .id = _id,                                              \
 -              .irq = soc ## _INT_GPIO ## _id,                         \
 -              .base = soc ## _IO_ADDRESS(                             \
 -                              soc ## _PINCTRL ## _BASE_ADDR),         \
 +              .irq = _irq,                                            \
 +              .base = _base,                                          \
                .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32,   \
        }
  
 -#define DEFINE_REGISTER_FUNCTION(prefix)                              \
 -int __init prefix ## _register_gpios(void)                            \
 -{                                                                     \
 -      return mxs_gpio_init(prefix ## _gpio_ports,                     \
 -                      ARRAY_SIZE(prefix ## _gpio_ports));             \
 -}
 -
  #ifdef CONFIG_SOC_IMX23
  static struct mxs_gpio_port mx23_gpio_ports[] = {
 -      DEFINE_MXS_GPIO_PORT(MX23, 0),
 -      DEFINE_MXS_GPIO_PORT(MX23, 1),
 -      DEFINE_MXS_GPIO_PORT(MX23, 2),
 +      DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO0, 0),
 +      DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO1, 1),
 +      DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO2, 2),
  };
 -DEFINE_REGISTER_FUNCTION(mx23)
 +
 +int __init mx23_register_gpios(void)
 +{
 +      return mxs_gpio_init(mx23_gpio_ports, ARRAY_SIZE(mx23_gpio_ports));
 +}
  #endif
  
  #ifdef CONFIG_SOC_IMX28
  static struct mxs_gpio_port mx28_gpio_ports[] = {
 -      DEFINE_MXS_GPIO_PORT(MX28, 0),
 -      DEFINE_MXS_GPIO_PORT(MX28, 1),
 -      DEFINE_MXS_GPIO_PORT(MX28, 2),
 -      DEFINE_MXS_GPIO_PORT(MX28, 3),
 -      DEFINE_MXS_GPIO_PORT(MX28, 4),
 +      DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO0, 0),
 +      DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO1, 1),
 +      DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO2, 2),
 +      DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO3, 3),
 +      DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO4, 4),
  };
 -DEFINE_REGISTER_FUNCTION(mx28)
 +
 +int __init mx28_register_gpios(void)
 +{
 +      return mxs_gpio_init(mx28_gpio_ports, ARRAY_SIZE(mx28_gpio_ports));
 +}
  #endif
index 2315541ac29d06554569786b9658162be517337d,ff469c4f1d76634dbfd77d346e9d8b56881088f8..e634d6c2e7b9f97972a4f2bbbae127ebda4e57ea
@@@ -83,7 -83,6 +83,7 @@@ static __inline__ void __arch_decomp_se
        case MACH_TYPE_MX21ADS:
        case MACH_TYPE_PCA100:
        case MACH_TYPE_MXT_TD60:
 +      case MACH_TYPE_IMX27IPCAM:
                uart_base = MX2X_UART1_BASE_ADDR;
                break;
        case MACH_TYPE_MX31LITE:
@@@ -96,6 -95,7 +96,7 @@@
        case MACH_TYPE_MX35_3DS:
        case MACH_TYPE_PCM043:
        case MACH_TYPE_LILLY1131:
+       case MACH_TYPE_VPR200:
                uart_base = MX3X_UART1_BASE_ADDR;
                break;
        case MACH_TYPE_MAGX_ZN5:
                break;
        case MACH_TYPE_MX51_BABBAGE:
        case MACH_TYPE_EUKREA_CPUIMX51SD:
+       case MACH_TYPE_MX51_3DS:
                uart_base = MX51_UART1_BASE_ADDR;
                break;
        case MACH_TYPE_MX50_RDP:
index b7a4d81e643dda266753a05b126c0207ce144105,2b8334601c8b586b957168906f7eb490c1ee8f57..5c4b3475621fb34eb2b4eb383032bc3df8868d02
@@@ -81,7 -81,7 +81,7 @@@ config SERIAL_8250_GS
        default SERIAL_8250
  
  config SERIAL_8250_PCI
-       tristate "8250/16550 PCI device support" if EMBEDDED
+       tristate "8250/16550 PCI device support" if EXPERT
        depends on SERIAL_8250 && PCI
        default SERIAL_8250
        help
@@@ -90,7 -90,7 +90,7 @@@
          Saves about 9K.
  
  config SERIAL_8250_PNP
-       tristate "8250/16550 PNP device support" if EMBEDDED
+       tristate "8250/16550 PNP device support" if EXPERT
        depends on SERIAL_8250 && PNP
        default SERIAL_8250
        help
@@@ -1518,6 -1518,7 +1518,7 @@@ config SERIAL_BCM63XX_CONSOL
  config SERIAL_GRLIB_GAISLER_APBUART
        tristate "GRLIB APBUART serial support"
        depends on OF
+       select SERIAL_CORE
        ---help---
        Add support for the GRLIB APBUART serial port.
  
@@@ -1595,19 -1596,4 +1596,19 @@@ config SERIAL_PCH_UAR
          This driver is for PCH(Platform controller Hub) UART of Intel EG20T
          which is an IOH(Input/Output Hub) for x86 embedded processor.
          Enabling PCH_DMA, this PCH UART works as DMA mode.
 +
 +config SERIAL_MXS_AUART
 +      depends on ARCH_MXS
 +      tristate "MXS AUART support"
 +      select SERIAL_CORE
 +      help
 +        This driver supports the MXS Application UART (AUART) port.
 +
 +config SERIAL_MXS_AUART_CONSOLE
 +      bool "MXS AUART console support"
 +      depends on SERIAL_MXS_AUART=y
 +      select SERIAL_CORE_CONSOLE
 +      help
 +        Enable a MXS AUART port to be the system console.
 +
  endmenu
index c8550719de5ac26f27635241e1046a6ae84fbb98,8ea92e9c73b046cb66cb43ee3d6daa9ddd3049ab..c8550719de5ac26f27635241e1046a6ae84fbb98
@@@ -92,4 -92,3 +92,4 @@@ obj-$(CONFIG_SERIAL_MRST_MAX3110)     += mr
  obj-$(CONFIG_SERIAL_MFD_HSU)  += mfd.o
  obj-$(CONFIG_SERIAL_IFX6X60)          += ifx6x60.o
  obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o
 +obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o
index 6d01ac9681032201c41f435176a4357d938a1c65,0000000000000000000000000000000000000000..6d01ac9681032201c41f435176a4357d938a1c65
mode 100644,000000..100644
--- /dev/null
@@@ -1,799 -1,0 +1,799 @@@
 +/*
 + * Freescale STMP37XX/STMP378X Application UART driver
 + *
 + * Author: dmitry pervushin <dimka@embeddedalley.com>
 + *
 + * Copyright 2008-2010 Freescale Semiconductor, Inc.
 + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
 + *
 + * The code contained herein is licensed under the GNU General Public
 + * License. You may obtain a copy of the GNU General Public License
 + * Version 2 or later at the following locations:
 + *
 + * http://www.opensource.org/licenses/gpl-license.html
 + * http://www.gnu.org/copyleft/gpl.html
 + */
 +
 +#include <linux/kernel.h>
 +#include <linux/device.h>
 +#include <linux/errno.h>
 +#include <linux/init.h>
 +#include <linux/console.h>
 +#include <linux/interrupt.h>
 +#include <linux/module.h>
 +#include <linux/slab.h>
 +#include <linux/wait.h>
 +#include <linux/tty.h>
 +#include <linux/tty_driver.h>
 +#include <linux/tty_flip.h>
 +#include <linux/serial.h>
 +#include <linux/serial_core.h>
 +#include <linux/platform_device.h>
 +#include <linux/device.h>
 +#include <linux/clk.h>
 +#include <linux/delay.h>
 +#include <linux/io.h>
 +
 +#include <asm/cacheflush.h>
 +
 +#define MXS_AUART_PORTS 5
 +
 +#define AUART_CTRL0                   0x00000000
 +#define AUART_CTRL0_SET                       0x00000004
 +#define AUART_CTRL0_CLR                       0x00000008
 +#define AUART_CTRL0_TOG                       0x0000000c
 +#define AUART_CTRL1                   0x00000010
 +#define AUART_CTRL1_SET                       0x00000014
 +#define AUART_CTRL1_CLR                       0x00000018
 +#define AUART_CTRL1_TOG                       0x0000001c
 +#define AUART_CTRL2                   0x00000020
 +#define AUART_CTRL2_SET                       0x00000024
 +#define AUART_CTRL2_CLR                       0x00000028
 +#define AUART_CTRL2_TOG                       0x0000002c
 +#define AUART_LINECTRL                        0x00000030
 +#define AUART_LINECTRL_SET            0x00000034
 +#define AUART_LINECTRL_CLR            0x00000038
 +#define AUART_LINECTRL_TOG            0x0000003c
 +#define AUART_LINECTRL2                       0x00000040
 +#define AUART_LINECTRL2_SET           0x00000044
 +#define AUART_LINECTRL2_CLR           0x00000048
 +#define AUART_LINECTRL2_TOG           0x0000004c
 +#define AUART_INTR                    0x00000050
 +#define AUART_INTR_SET                        0x00000054
 +#define AUART_INTR_CLR                        0x00000058
 +#define AUART_INTR_TOG                        0x0000005c
 +#define AUART_DATA                    0x00000060
 +#define AUART_STAT                    0x00000070
 +#define AUART_DEBUG                   0x00000080
 +#define AUART_VERSION                 0x00000090
 +#define AUART_AUTOBAUD                        0x000000a0
 +
 +#define AUART_CTRL0_SFTRST                    (1 << 31)
 +#define AUART_CTRL0_CLKGATE                   (1 << 30)
 +
 +#define AUART_CTRL2_CTSEN                     (1 << 15)
 +#define AUART_CTRL2_RTS                               (1 << 11)
 +#define AUART_CTRL2_RXE                               (1 << 9)
 +#define AUART_CTRL2_TXE                               (1 << 8)
 +#define AUART_CTRL2_UARTEN                    (1 << 0)
 +
 +#define AUART_LINECTRL_BAUD_DIVINT_SHIFT      16
 +#define AUART_LINECTRL_BAUD_DIVINT_MASK               0xffff0000
 +#define AUART_LINECTRL_BAUD_DIVINT(v)         (((v) & 0xffff) << 16)
 +#define AUART_LINECTRL_BAUD_DIVFRAC_SHIFT     8
 +#define AUART_LINECTRL_BAUD_DIVFRAC_MASK      0x00003f00
 +#define AUART_LINECTRL_BAUD_DIVFRAC(v)                (((v) & 0x3f) << 8)
 +#define AUART_LINECTRL_WLEN_MASK              0x00000060
 +#define AUART_LINECTRL_WLEN(v)                        (((v) & 0x3) << 5)
 +#define AUART_LINECTRL_FEN                    (1 << 4)
 +#define AUART_LINECTRL_STP2                   (1 << 3)
 +#define AUART_LINECTRL_EPS                    (1 << 2)
 +#define AUART_LINECTRL_PEN                    (1 << 1)
 +#define AUART_LINECTRL_BRK                    (1 << 0)
 +
 +#define AUART_INTR_RTIEN                      (1 << 22)
 +#define AUART_INTR_TXIEN                      (1 << 21)
 +#define AUART_INTR_RXIEN                      (1 << 20)
 +#define AUART_INTR_CTSMIEN                    (1 << 17)
 +#define AUART_INTR_RTIS                               (1 << 6)
 +#define AUART_INTR_TXIS                               (1 << 5)
 +#define AUART_INTR_RXIS                               (1 << 4)
 +#define AUART_INTR_CTSMIS                     (1 << 1)
 +
 +#define AUART_STAT_BUSY                               (1 << 29)
 +#define AUART_STAT_CTS                                (1 << 28)
 +#define AUART_STAT_TXFE                               (1 << 27)
 +#define AUART_STAT_TXFF                               (1 << 25)
 +#define AUART_STAT_RXFE                               (1 << 24)
 +#define AUART_STAT_OERR                               (1 << 19)
 +#define AUART_STAT_BERR                               (1 << 18)
 +#define AUART_STAT_PERR                               (1 << 17)
 +#define AUART_STAT_FERR                               (1 << 16)
 +
 +static struct uart_driver auart_driver;
 +
 +struct mxs_auart_port {
 +      struct uart_port port;
 +
 +      unsigned int flags;
 +      unsigned int ctrl;
 +
 +      unsigned int irq;
 +
 +      struct clk *clk;
 +      struct device *dev;
 +};
 +
 +static void mxs_auart_stop_tx(struct uart_port *u);
 +
 +#define to_auart_port(u) container_of(u, struct mxs_auart_port, port)
 +
 +static inline void mxs_auart_tx_chars(struct mxs_auart_port *s)
 +{
 +      struct circ_buf *xmit = &s->port.state->xmit;
 +
 +      while (!(readl(s->port.membase + AUART_STAT) &
 +               AUART_STAT_TXFF)) {
 +              if (s->port.x_char) {
 +                      s->port.icount.tx++;
 +                      writel(s->port.x_char,
 +                                   s->port.membase + AUART_DATA);
 +                      s->port.x_char = 0;
 +                      continue;
 +              }
 +              if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
 +                      s->port.icount.tx++;
 +                      writel(xmit->buf[xmit->tail],
 +                                   s->port.membase + AUART_DATA);
 +                      xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 +                      if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 +                              uart_write_wakeup(&s->port);
 +              } else
 +                      break;
 +      }
 +      if (uart_circ_empty(&(s->port.state->xmit)))
 +              writel(AUART_INTR_TXIEN,
 +                           s->port.membase + AUART_INTR_CLR);
 +      else
 +              writel(AUART_INTR_TXIEN,
 +                           s->port.membase + AUART_INTR_SET);
 +
 +      if (uart_tx_stopped(&s->port))
 +              mxs_auart_stop_tx(&s->port);
 +}
 +
 +static void mxs_auart_rx_char(struct mxs_auart_port *s)
 +{
 +      int flag;
 +      u32 stat;
 +      u8 c;
 +
 +      c = readl(s->port.membase + AUART_DATA);
 +      stat = readl(s->port.membase + AUART_STAT);
 +
 +      flag = TTY_NORMAL;
 +      s->port.icount.rx++;
 +
 +      if (stat & AUART_STAT_BERR) {
 +              s->port.icount.brk++;
 +              if (uart_handle_break(&s->port))
 +                      goto out;
 +      } else if (stat & AUART_STAT_PERR) {
 +              s->port.icount.parity++;
 +      } else if (stat & AUART_STAT_FERR) {
 +              s->port.icount.frame++;
 +      }
 +
 +      /*
 +       * Mask off conditions which should be ingored.
 +       */
 +      stat &= s->port.read_status_mask;
 +
 +      if (stat & AUART_STAT_BERR) {
 +              flag = TTY_BREAK;
 +      } else if (stat & AUART_STAT_PERR)
 +              flag = TTY_PARITY;
 +      else if (stat & AUART_STAT_FERR)
 +              flag = TTY_FRAME;
 +
 +      if (stat & AUART_STAT_OERR)
 +              s->port.icount.overrun++;
 +
 +      if (uart_handle_sysrq_char(&s->port, c))
 +              goto out;
 +
 +      uart_insert_char(&s->port, stat, AUART_STAT_OERR, c, flag);
 +out:
 +      writel(stat, s->port.membase + AUART_STAT);
 +}
 +
 +static void mxs_auart_rx_chars(struct mxs_auart_port *s)
 +{
 +      struct tty_struct *tty = s->port.state->port.tty;
 +      u32 stat = 0;
 +
 +      for (;;) {
 +              stat = readl(s->port.membase + AUART_STAT);
 +              if (stat & AUART_STAT_RXFE)
 +                      break;
 +              mxs_auart_rx_char(s);
 +      }
 +
 +      writel(stat, s->port.membase + AUART_STAT);
 +      tty_flip_buffer_push(tty);
 +}
 +
 +static int mxs_auart_request_port(struct uart_port *u)
 +{
 +      return 0;
 +}
 +
 +static int mxs_auart_verify_port(struct uart_port *u,
 +                                  struct serial_struct *ser)
 +{
 +      if (u->type != PORT_UNKNOWN && u->type != PORT_IMX)
 +              return -EINVAL;
 +      return 0;
 +}
 +
 +static void mxs_auart_config_port(struct uart_port *u, int flags)
 +{
 +}
 +
 +static const char *mxs_auart_type(struct uart_port *u)
 +{
 +      struct mxs_auart_port *s = to_auart_port(u);
 +
 +      return dev_name(s->dev);
 +}
 +
 +static void mxs_auart_release_port(struct uart_port *u)
 +{
 +}
 +
 +static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl)
 +{
 +      struct mxs_auart_port *s = to_auart_port(u);
 +
 +      u32 ctrl = readl(u->membase + AUART_CTRL2);
 +
 +      ctrl &= ~AUART_CTRL2_RTS;
 +      if (mctrl & TIOCM_RTS)
 +              ctrl |= AUART_CTRL2_RTS;
 +      s->ctrl = mctrl;
 +      writel(ctrl, u->membase + AUART_CTRL2);
 +}
 +
 +static u32 mxs_auart_get_mctrl(struct uart_port *u)
 +{
 +      struct mxs_auart_port *s = to_auart_port(u);
 +      u32 stat = readl(u->membase + AUART_STAT);
 +      int ctrl2 = readl(u->membase + AUART_CTRL2);
 +      u32 mctrl = s->ctrl;
 +
 +      mctrl &= ~TIOCM_CTS;
 +      if (stat & AUART_STAT_CTS)
 +              mctrl |= TIOCM_CTS;
 +
 +      if (ctrl2 & AUART_CTRL2_RTS)
 +              mctrl |= TIOCM_RTS;
 +
 +      return mctrl;
 +}
 +
 +static void mxs_auart_settermios(struct uart_port *u,
 +                               struct ktermios *termios,
 +                               struct ktermios *old)
 +{
 +      u32 bm, ctrl, ctrl2, div;
 +      unsigned int cflag, baud;
 +
 +      cflag = termios->c_cflag;
 +
 +      ctrl = AUART_LINECTRL_FEN;
 +      ctrl2 = readl(u->membase + AUART_CTRL2);
 +
 +      /* byte size */
 +      switch (cflag & CSIZE) {
 +      case CS5:
 +              bm = 0;
 +              break;
 +      case CS6:
 +              bm = 1;
 +              break;
 +      case CS7:
 +              bm = 2;
 +              break;
 +      case CS8:
 +              bm = 3;
 +              break;
 +      default:
 +              return;
 +      }
 +
 +      ctrl |= AUART_LINECTRL_WLEN(bm);
 +
 +      /* parity */
 +      if (cflag & PARENB) {
 +              ctrl |= AUART_LINECTRL_PEN;
 +              if ((cflag & PARODD) == 0)
 +                      ctrl |= AUART_LINECTRL_EPS;
 +      }
 +
 +      u->read_status_mask = 0;
 +
 +      if (termios->c_iflag & INPCK)
 +              u->read_status_mask |= AUART_STAT_PERR;
 +      if (termios->c_iflag & (BRKINT | PARMRK))
 +              u->read_status_mask |= AUART_STAT_BERR;
 +
 +      /*
 +       * Characters to ignore
 +       */
 +      u->ignore_status_mask = 0;
 +      if (termios->c_iflag & IGNPAR)
 +              u->ignore_status_mask |= AUART_STAT_PERR;
 +      if (termios->c_iflag & IGNBRK) {
 +              u->ignore_status_mask |= AUART_STAT_BERR;
 +              /*
 +               * If we're ignoring parity and break indicators,
 +               * ignore overruns too (for real raw support).
 +               */
 +              if (termios->c_iflag & IGNPAR)
 +                      u->ignore_status_mask |= AUART_STAT_OERR;
 +      }
 +
 +      /*
 +       * ignore all characters if CREAD is not set
 +       */
 +      if (cflag & CREAD)
 +              ctrl2 |= AUART_CTRL2_RXE;
 +      else
 +              ctrl2 &= ~AUART_CTRL2_RXE;
 +
 +      /* figure out the stop bits requested */
 +      if (cflag & CSTOPB)
 +              ctrl |= AUART_LINECTRL_STP2;
 +
 +      /* figure out the hardware flow control settings */
 +      if (cflag & CRTSCTS)
 +              ctrl2 |= AUART_CTRL2_CTSEN;
 +      else
 +              ctrl2 &= ~AUART_CTRL2_CTSEN;
 +
 +      /* set baud rate */
 +      baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk);
 +      div = u->uartclk * 32 / baud;
 +      ctrl |= AUART_LINECTRL_BAUD_DIVFRAC(div & 0x3F);
 +      ctrl |= AUART_LINECTRL_BAUD_DIVINT(div >> 6);
 +
 +      writel(ctrl, u->membase + AUART_LINECTRL);
 +      writel(ctrl2, u->membase + AUART_CTRL2);
 +}
 +
 +static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
 +{
 +      u32 istatus, istat;
 +      struct mxs_auart_port *s = context;
 +      u32 stat = readl(s->port.membase + AUART_STAT);
 +
 +      istatus = istat = readl(s->port.membase + AUART_INTR);
 +
 +      if (istat & AUART_INTR_CTSMIS) {
 +              uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS);
 +              writel(AUART_INTR_CTSMIS,
 +                              s->port.membase + AUART_INTR_CLR);
 +              istat &= ~AUART_INTR_CTSMIS;
 +      }
 +
 +      if (istat & (AUART_INTR_RTIS | AUART_INTR_RXIS)) {
 +              mxs_auart_rx_chars(s);
 +              istat &= ~(AUART_INTR_RTIS | AUART_INTR_RXIS);
 +      }
 +
 +      if (istat & AUART_INTR_TXIS) {
 +              mxs_auart_tx_chars(s);
 +              istat &= ~AUART_INTR_TXIS;
 +      }
 +
 +      writel(istatus & (AUART_INTR_RTIS
 +              | AUART_INTR_TXIS
 +              | AUART_INTR_RXIS
 +              | AUART_INTR_CTSMIS),
 +                      s->port.membase + AUART_INTR_CLR);
 +
 +      return IRQ_HANDLED;
 +}
 +
 +static void mxs_auart_reset(struct uart_port *u)
 +{
 +      int i;
 +      unsigned int reg;
 +
 +      writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_CLR);
 +
 +      for (i = 0; i < 10000; i++) {
 +              reg = readl(u->membase + AUART_CTRL0);
 +              if (!(reg & AUART_CTRL0_SFTRST))
 +                      break;
 +              udelay(3);
 +      }
 +      writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
 +}
 +
 +static int mxs_auart_startup(struct uart_port *u)
 +{
 +      struct mxs_auart_port *s = to_auart_port(u);
 +
 +      clk_enable(s->clk);
 +
 +      writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
 +
 +      writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_SET);
 +
 +      writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
 +                      u->membase + AUART_INTR);
 +
 +      /*
 +       * Enable fifo so all four bytes of a DMA word are written to
 +       * output (otherwise, only the LSB is written, ie. 1 in 4 bytes)
 +       */
 +      writel(AUART_LINECTRL_FEN, u->membase + AUART_LINECTRL_SET);
 +
 +      return 0;
 +}
 +
 +static void mxs_auart_shutdown(struct uart_port *u)
 +{
 +      struct mxs_auart_port *s = to_auart_port(u);
 +
 +      writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
 +
 +      writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET);
 +
 +      writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
 +                      u->membase + AUART_INTR_CLR);
 +
 +      clk_disable(s->clk);
 +}
 +
 +static unsigned int mxs_auart_tx_empty(struct uart_port *u)
 +{
 +      if (readl(u->membase + AUART_STAT) & AUART_STAT_TXFE)
 +              return TIOCSER_TEMT;
 +      else
 +              return 0;
 +}
 +
 +static void mxs_auart_start_tx(struct uart_port *u)
 +{
 +      struct mxs_auart_port *s = to_auart_port(u);
 +
 +      /* enable transmitter */
 +      writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_SET);
 +
 +      mxs_auart_tx_chars(s);
 +}
 +
 +static void mxs_auart_stop_tx(struct uart_port *u)
 +{
 +      writel(AUART_CTRL2_TXE, u->membase + AUART_CTRL2_CLR);
 +}
 +
 +static void mxs_auart_stop_rx(struct uart_port *u)
 +{
 +      writel(AUART_CTRL2_RXE, u->membase + AUART_CTRL2_CLR);
 +}
 +
 +static void mxs_auart_break_ctl(struct uart_port *u, int ctl)
 +{
 +      if (ctl)
 +              writel(AUART_LINECTRL_BRK,
 +                           u->membase + AUART_LINECTRL_SET);
 +      else
 +              writel(AUART_LINECTRL_BRK,
 +                           u->membase + AUART_LINECTRL_CLR);
 +}
 +
 +static void mxs_auart_enable_ms(struct uart_port *port)
 +{
 +      /* just empty */
 +}
 +
 +static struct uart_ops mxs_auart_ops = {
 +      .tx_empty       = mxs_auart_tx_empty,
 +      .start_tx       = mxs_auart_start_tx,
 +      .stop_tx        = mxs_auart_stop_tx,
 +      .stop_rx        = mxs_auart_stop_rx,
 +      .enable_ms      = mxs_auart_enable_ms,
 +      .break_ctl      = mxs_auart_break_ctl,
 +      .set_mctrl      = mxs_auart_set_mctrl,
 +      .get_mctrl      = mxs_auart_get_mctrl,
 +      .startup        = mxs_auart_startup,
 +      .shutdown       = mxs_auart_shutdown,
 +      .set_termios    = mxs_auart_settermios,
 +      .type           = mxs_auart_type,
 +      .release_port   = mxs_auart_release_port,
 +      .request_port   = mxs_auart_request_port,
 +      .config_port    = mxs_auart_config_port,
 +      .verify_port    = mxs_auart_verify_port,
 +};
 +
 +static struct mxs_auart_port *auart_port[MXS_AUART_PORTS];
 +
 +#ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE
 +static void mxs_auart_console_putchar(struct uart_port *port, int ch)
 +{
 +      unsigned int to = 1000;
 +
 +      while (readl(port->membase + AUART_STAT) & AUART_STAT_TXFF) {
 +              if (!to--)
 +                      break;
 +              udelay(1);
 +      }
 +
 +      writel(ch, port->membase + AUART_DATA);
 +}
 +
 +static void
 +auart_console_write(struct console *co, const char *str, unsigned int count)
 +{
 +      struct mxs_auart_port *s;
 +      struct uart_port *port;
 +      unsigned int old_ctrl0, old_ctrl2;
 +      unsigned int to = 1000;
 +
 +      if (co->index > MXS_AUART_PORTS || co->index < 0)
 +              return;
 +
 +      s = auart_port[co->index];
 +      port = &s->port;
 +
 +      clk_enable(s->clk);
 +
 +      /* First save the CR then disable the interrupts */
 +      old_ctrl2 = readl(port->membase + AUART_CTRL2);
 +      old_ctrl0 = readl(port->membase + AUART_CTRL0);
 +
 +      writel(AUART_CTRL0_CLKGATE,
 +                   port->membase + AUART_CTRL0_CLR);
 +      writel(AUART_CTRL2_UARTEN | AUART_CTRL2_TXE,
 +                   port->membase + AUART_CTRL2_SET);
 +
 +      uart_console_write(port, str, count, mxs_auart_console_putchar);
 +
 +      /*
 +       * Finally, wait for transmitter to become empty
 +       * and restore the TCR
 +       */
 +      while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) {
 +              if (!to--)
 +                      break;
 +              udelay(1);
 +      }
 +
 +      writel(old_ctrl0, port->membase + AUART_CTRL0);
 +      writel(old_ctrl2, port->membase + AUART_CTRL2);
 +
 +      clk_disable(s->clk);
 +}
 +
 +static void __init
 +auart_console_get_options(struct uart_port *port, int *baud,
 +                        int *parity, int *bits)
 +{
 +      unsigned int lcr_h, quot;
 +
 +      if (!(readl(port->membase + AUART_CTRL2) & AUART_CTRL2_UARTEN))
 +              return;
 +
 +      lcr_h = readl(port->membase + AUART_LINECTRL);
 +
 +      *parity = 'n';
 +      if (lcr_h & AUART_LINECTRL_PEN) {
 +              if (lcr_h & AUART_LINECTRL_EPS)
 +                      *parity = 'e';
 +              else
 +                      *parity = 'o';
 +      }
 +
 +      if ((lcr_h & AUART_LINECTRL_WLEN_MASK) == AUART_LINECTRL_WLEN(2))
 +              *bits = 7;
 +      else
 +              *bits = 8;
 +
 +      quot = ((readl(port->membase + AUART_LINECTRL)
 +                      & AUART_LINECTRL_BAUD_DIVINT_MASK))
 +                          >> (AUART_LINECTRL_BAUD_DIVINT_SHIFT - 6);
 +      quot |= ((readl(port->membase + AUART_LINECTRL)
 +                      & AUART_LINECTRL_BAUD_DIVFRAC_MASK))
 +                              >> AUART_LINECTRL_BAUD_DIVFRAC_SHIFT;
 +      if (quot == 0)
 +              quot = 1;
 +
 +      *baud = (port->uartclk << 2) / quot;
 +}
 +
 +static int __init
 +auart_console_setup(struct console *co, char *options)
 +{
 +      struct mxs_auart_port *s;
 +      int baud = 9600;
 +      int bits = 8;
 +      int parity = 'n';
 +      int flow = 'n';
 +      int ret;
 +
 +      /*
 +       * Check whether an invalid uart number has been specified, and
 +       * if so, search for the first available port that does have
 +       * console support.
 +       */
 +      if (co->index == -1 || co->index >= ARRAY_SIZE(auart_port))
 +              co->index = 0;
 +      s = auart_port[co->index];
 +      if (!s)
 +              return -ENODEV;
 +
 +      clk_enable(s->clk);
 +
 +      if (options)
 +              uart_parse_options(options, &baud, &parity, &bits, &flow);
 +      else
 +              auart_console_get_options(&s->port, &baud, &parity, &bits);
 +
 +      ret = uart_set_options(&s->port, co, baud, parity, bits, flow);
 +
 +      clk_disable(s->clk);
 +
 +      return ret;
 +}
 +
 +static struct console auart_console = {
 +      .name           = "ttyAPP",
 +      .write          = auart_console_write,
 +      .device         = uart_console_device,
 +      .setup          = auart_console_setup,
 +      .flags          = CON_PRINTBUFFER,
 +      .index          = -1,
 +      .data           = &auart_driver,
 +};
 +#endif
 +
 +static struct uart_driver auart_driver = {
 +      .owner          = THIS_MODULE,
 +      .driver_name    = "ttyAPP",
 +      .dev_name       = "ttyAPP",
 +      .major          = 0,
 +      .minor          = 0,
 +      .nr             = MXS_AUART_PORTS,
 +#ifdef CONFIG_SERIAL_MXS_AUART_CONSOLE
 +      .cons =         &auart_console,
 +#endif
 +};
 +
 +static int __devinit mxs_auart_probe(struct platform_device *pdev)
 +{
 +      struct mxs_auart_port *s;
 +      u32 version;
 +      int ret = 0;
 +      struct resource *r;
 +
 +      s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL);
 +      if (!s) {
 +              ret = -ENOMEM;
 +              goto out;
 +      }
 +
 +      s->clk = clk_get(&pdev->dev, NULL);
 +      if (IS_ERR(s->clk)) {
 +              ret = PTR_ERR(s->clk);
 +              goto out_free;
 +      }
 +
 +      r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 +      if (!r) {
 +              ret = -ENXIO;
 +              goto out_free_clk;
 +      }
 +
 +      s->port.mapbase = r->start;
 +      s->port.membase = ioremap(r->start, resource_size(r));
 +      s->port.ops = &mxs_auart_ops;
 +      s->port.iotype = UPIO_MEM;
 +      s->port.line = pdev->id < 0 ? 0 : pdev->id;
 +      s->port.fifosize = 16;
 +      s->port.uartclk = clk_get_rate(s->clk);
 +      s->port.type = PORT_IMX;
 +      s->port.dev = s->dev = get_device(&pdev->dev);
 +
 +      s->flags = 0;
 +      s->ctrl = 0;
 +
 +      s->irq = platform_get_irq(pdev, 0);
 +      s->port.irq = s->irq;
 +      ret = request_irq(s->irq, mxs_auart_irq_handle, 0, dev_name(&pdev->dev), s);
 +      if (ret)
 +              goto out_free_clk;
 +
 +      platform_set_drvdata(pdev, s);
 +
 +      auart_port[pdev->id] = s;
 +
 +      mxs_auart_reset(&s->port);
 +
 +      ret = uart_add_one_port(&auart_driver, &s->port);
 +      if (ret)
 +              goto out_free_irq;
 +
 +      version = readl(s->port.membase + AUART_VERSION);
 +      dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n",
 +             (version >> 24) & 0xff,
 +             (version >> 16) & 0xff, version & 0xffff);
 +
 +      return 0;
 +
 +out_free_irq:
 +      auart_port[pdev->id] = NULL;
 +      free_irq(s->irq, s);
 +out_free_clk:
 +      clk_put(s->clk);
 +out_free:
 +      kfree(s);
 +out:
 +      return ret;
 +}
 +
 +static int __devexit mxs_auart_remove(struct platform_device *pdev)
 +{
 +      struct mxs_auart_port *s = platform_get_drvdata(pdev);
 +
 +      uart_remove_one_port(&auart_driver, &s->port);
 +
 +      auart_port[pdev->id] = NULL;
 +
 +      clk_put(s->clk);
 +      free_irq(s->irq, s);
 +      kfree(s);
 +
 +      return 0;
 +}
 +
 +static struct platform_driver mxs_auart_driver = {
 +      .probe = mxs_auart_probe,
 +      .remove = __devexit_p(mxs_auart_remove),
 +      .driver = {
 +              .name = "mxs-auart",
 +              .owner = THIS_MODULE,
 +      },
 +};
 +
 +static int __init mxs_auart_init(void)
 +{
 +      int r;
 +
 +      r = uart_register_driver(&auart_driver);
 +      if (r)
 +              goto out;
 +
 +      r = platform_driver_register(&mxs_auart_driver);
 +      if (r)
 +              goto out_err;
 +
 +      return 0;
 +out_err:
 +      uart_unregister_driver(&auart_driver);
 +out:
 +      return r;
 +}
 +
 +static void __exit mxs_auart_exit(void)
 +{
 +      platform_driver_unregister(&mxs_auart_driver);
 +      uart_unregister_driver(&auart_driver);
 +}
 +
 +module_init(mxs_auart_init);
 +module_exit(mxs_auart_exit);
 +MODULE_LICENSE("GPL");
 +MODULE_DESCRIPTION("Freescale MXS application uart driver");