linux/drivers/tty/serial/msm_serial.c
<<
>>
Prefs
   1/*
   2 * drivers/serial/msm_serial.c - driver for msm7k serial device and console
   3 *
   4 * Copyright (C) 2007 Google, Inc.
   5 * Author: Robert Love <rlove@google.com>
   6 *
   7 * This software is licensed under the terms of the GNU General Public
   8 * License version 2, as published by the Free Software Foundation, and
   9 * may be copied, distributed, and modified under those terms.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 */
  16
  17#if defined(CONFIG_SERIAL_MSM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
  18# define SUPPORT_SYSRQ
  19#endif
  20
  21#include <linux/hrtimer.h>
  22#include <linux/module.h>
  23#include <linux/io.h>
  24#include <linux/ioport.h>
  25#include <linux/irq.h>
  26#include <linux/init.h>
  27#include <linux/console.h>
  28#include <linux/tty.h>
  29#include <linux/tty_flip.h>
  30#include <linux/serial_core.h>
  31#include <linux/serial.h>
  32#include <linux/clk.h>
  33#include <linux/platform_device.h>
  34
  35#include "msm_serial.h"
  36
  37struct msm_port {
  38        struct uart_port        uart;
  39        char                    name[16];
  40        struct clk              *clk;
  41        unsigned int            imr;
  42};
  43
  44static void msm_stop_tx(struct uart_port *port)
  45{
  46        struct msm_port *msm_port = UART_TO_MSM(port);
  47
  48        msm_port->imr &= ~UART_IMR_TXLEV;
  49        msm_write(port, msm_port->imr, UART_IMR);
  50}
  51
  52static void msm_start_tx(struct uart_port *port)
  53{
  54        struct msm_port *msm_port = UART_TO_MSM(port);
  55
  56        msm_port->imr |= UART_IMR_TXLEV;
  57        msm_write(port, msm_port->imr, UART_IMR);
  58}
  59
  60static void msm_stop_rx(struct uart_port *port)
  61{
  62        struct msm_port *msm_port = UART_TO_MSM(port);
  63
  64        msm_port->imr &= ~(UART_IMR_RXLEV | UART_IMR_RXSTALE);
  65        msm_write(port, msm_port->imr, UART_IMR);
  66}
  67
  68static void msm_enable_ms(struct uart_port *port)
  69{
  70        struct msm_port *msm_port = UART_TO_MSM(port);
  71
  72        msm_port->imr |= UART_IMR_DELTA_CTS;
  73        msm_write(port, msm_port->imr, UART_IMR);
  74}
  75
  76static void handle_rx(struct uart_port *port)
  77{
  78        struct tty_struct *tty = port->state->port.tty;
  79        unsigned int sr;
  80
  81        /*
  82         * Handle overrun. My understanding of the hardware is that overrun
  83         * is not tied to the RX buffer, so we handle the case out of band.
  84         */
  85        if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) {
  86                port->icount.overrun++;
  87                tty_insert_flip_char(tty, 0, TTY_OVERRUN);
  88                msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
  89        }
  90
  91        /* and now the main RX loop */
  92        while ((sr = msm_read(port, UART_SR)) & UART_SR_RX_READY) {
  93                unsigned int c;
  94                char flag = TTY_NORMAL;
  95
  96                c = msm_read(port, UART_RF);
  97
  98                if (sr & UART_SR_RX_BREAK) {
  99                        port->icount.brk++;
 100                        if (uart_handle_break(port))
 101                                continue;
 102                } else if (sr & UART_SR_PAR_FRAME_ERR) {
 103                        port->icount.frame++;
 104                } else {
 105                        port->icount.rx++;
 106                }
 107
 108                /* Mask conditions we're ignorning. */
 109                sr &= port->read_status_mask;
 110
 111                if (sr & UART_SR_RX_BREAK) {
 112                        flag = TTY_BREAK;
 113                } else if (sr & UART_SR_PAR_FRAME_ERR) {
 114                        flag = TTY_FRAME;
 115                }
 116
 117                if (!uart_handle_sysrq_char(port, c))
 118                        tty_insert_flip_char(tty, c, flag);
 119        }
 120
 121        tty_flip_buffer_push(tty);
 122}
 123
 124static void handle_tx(struct uart_port *port)
 125{
 126        struct circ_buf *xmit = &port->state->xmit;
 127        struct msm_port *msm_port = UART_TO_MSM(port);
 128        int sent_tx;
 129
 130        if (port->x_char) {
 131                msm_write(port, port->x_char, UART_TF);
 132                port->icount.tx++;
 133                port->x_char = 0;
 134        }
 135
 136        while (msm_read(port, UART_SR) & UART_SR_TX_READY) {
 137                if (uart_circ_empty(xmit)) {
 138                        /* disable tx interrupts */
 139                        msm_port->imr &= ~UART_IMR_TXLEV;
 140                        msm_write(port, msm_port->imr, UART_IMR);
 141                        break;
 142                }
 143
 144                msm_write(port, xmit->buf[xmit->tail], UART_TF);
 145
 146                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 147                port->icount.tx++;
 148                sent_tx = 1;
 149        }
 150
 151        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 152                uart_write_wakeup(port);
 153}
 154
 155static void handle_delta_cts(struct uart_port *port)
 156{
 157        msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
 158        port->icount.cts++;
 159        wake_up_interruptible(&port->state->port.delta_msr_wait);
 160}
 161
 162static irqreturn_t msm_irq(int irq, void *dev_id)
 163{
 164        struct uart_port *port = dev_id;
 165        struct msm_port *msm_port = UART_TO_MSM(port);
 166        unsigned int misr;
 167
 168        spin_lock(&port->lock);
 169        misr = msm_read(port, UART_MISR);
 170        msm_write(port, 0, UART_IMR); /* disable interrupt */
 171
 172        if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE))
 173                handle_rx(port);
 174        if (misr & UART_IMR_TXLEV)
 175                handle_tx(port);
 176        if (misr & UART_IMR_DELTA_CTS)
 177                handle_delta_cts(port);
 178
 179        msm_write(port, msm_port->imr, UART_IMR); /* restore interrupt */
 180        spin_unlock(&port->lock);
 181
 182        return IRQ_HANDLED;
 183}
 184
 185static unsigned int msm_tx_empty(struct uart_port *port)
 186{
 187        return (msm_read(port, UART_SR) & UART_SR_TX_EMPTY) ? TIOCSER_TEMT : 0;
 188}
 189
 190static unsigned int msm_get_mctrl(struct uart_port *port)
 191{
 192        return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR | TIOCM_RTS;
 193}
 194
 195static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl)
 196{
 197        unsigned int mr;
 198
 199        mr = msm_read(port, UART_MR1);
 200
 201        if (!(mctrl & TIOCM_RTS)) {
 202                mr &= ~UART_MR1_RX_RDY_CTL;
 203                msm_write(port, mr, UART_MR1);
 204                msm_write(port, UART_CR_CMD_RESET_RFR, UART_CR);
 205        } else {
 206                mr |= UART_MR1_RX_RDY_CTL;
 207                msm_write(port, mr, UART_MR1);
 208        }
 209}
 210
 211static void msm_break_ctl(struct uart_port *port, int break_ctl)
 212{
 213        if (break_ctl)
 214                msm_write(port, UART_CR_CMD_START_BREAK, UART_CR);
 215        else
 216                msm_write(port, UART_CR_CMD_STOP_BREAK, UART_CR);
 217}
 218
 219static int msm_set_baud_rate(struct uart_port *port, unsigned int baud)
 220{
 221        unsigned int baud_code, rxstale, watermark;
 222
 223        switch (baud) {
 224        case 300:
 225                baud_code = UART_CSR_300;
 226                rxstale = 1;
 227                break;
 228        case 600:
 229                baud_code = UART_CSR_600;
 230                rxstale = 1;
 231                break;
 232        case 1200:
 233                baud_code = UART_CSR_1200;
 234                rxstale = 1;
 235                break;
 236        case 2400:
 237                baud_code = UART_CSR_2400;
 238                rxstale = 1;
 239                break;
 240        case 4800:
 241                baud_code = UART_CSR_4800;
 242                rxstale = 1;
 243                break;
 244        case 9600:
 245                baud_code = UART_CSR_9600;
 246                rxstale = 2;
 247                break;
 248        case 14400:
 249                baud_code = UART_CSR_14400;
 250                rxstale = 3;
 251                break;
 252        case 19200:
 253                baud_code = UART_CSR_19200;
 254                rxstale = 4;
 255                break;
 256        case 28800:
 257                baud_code = UART_CSR_28800;
 258                rxstale = 6;
 259                break;
 260        case 38400:
 261                baud_code = UART_CSR_38400;
 262                rxstale = 8;
 263                break;
 264        case 57600:
 265                baud_code = UART_CSR_57600;
 266                rxstale = 16;
 267                break;
 268        case 115200:
 269        default:
 270                baud_code = UART_CSR_115200;
 271                baud = 115200;
 272                rxstale = 31;
 273                break;
 274        }
 275
 276        msm_write(port, baud_code, UART_CSR);
 277
 278        /* RX stale watermark */
 279        watermark = UART_IPR_STALE_LSB & rxstale;
 280        watermark |= UART_IPR_RXSTALE_LAST;
 281        watermark |= UART_IPR_STALE_TIMEOUT_MSB & (rxstale << 2);
 282        msm_write(port, watermark, UART_IPR);
 283
 284        /* set RX watermark */
 285        watermark = (port->fifosize * 3) / 4;
 286        msm_write(port, watermark, UART_RFWR);
 287
 288        /* set TX watermark */
 289        msm_write(port, 10, UART_TFWR);
 290
 291        return baud;
 292}
 293
 294static void msm_reset(struct uart_port *port)
 295{
 296        /* reset everything */
 297        msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
 298        msm_write(port, UART_CR_CMD_RESET_TX, UART_CR);
 299        msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
 300        msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
 301        msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
 302        msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
 303}
 304
 305static void msm_init_clock(struct uart_port *port)
 306{
 307        struct msm_port *msm_port = UART_TO_MSM(port);
 308
 309        clk_enable(msm_port->clk);
 310        msm_serial_set_mnd_regs(port);
 311}
 312
 313static int msm_startup(struct uart_port *port)
 314{
 315        struct msm_port *msm_port = UART_TO_MSM(port);
 316        unsigned int data, rfr_level;
 317        int ret;
 318
 319        snprintf(msm_port->name, sizeof(msm_port->name),
 320                 "msm_serial%d", port->line);
 321
 322        ret = request_irq(port->irq, msm_irq, IRQF_TRIGGER_HIGH,
 323                          msm_port->name, port);
 324        if (unlikely(ret))
 325                return ret;
 326
 327        msm_init_clock(port);
 328
 329        if (likely(port->fifosize > 12))
 330                rfr_level = port->fifosize - 12;
 331        else
 332                rfr_level = port->fifosize;
 333
 334        /* set automatic RFR level */
 335        data = msm_read(port, UART_MR1);
 336        data &= ~UART_MR1_AUTO_RFR_LEVEL1;
 337        data &= ~UART_MR1_AUTO_RFR_LEVEL0;
 338        data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2);
 339        data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level;
 340        msm_write(port, data, UART_MR1);
 341
 342        /* make sure that RXSTALE count is non-zero */
 343        data = msm_read(port, UART_IPR);
 344        if (unlikely(!data)) {
 345                data |= UART_IPR_RXSTALE_LAST;
 346                data |= UART_IPR_STALE_LSB;
 347                msm_write(port, data, UART_IPR);
 348        }
 349
 350        msm_reset(port);
 351
 352        msm_write(port, 0x05, UART_CR); /* enable TX & RX */
 353
 354        /* turn on RX and CTS interrupts */
 355        msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE |
 356                        UART_IMR_CURRENT_CTS;
 357        msm_write(port, msm_port->imr, UART_IMR);
 358
 359        return 0;
 360}
 361
 362static void msm_shutdown(struct uart_port *port)
 363{
 364        struct msm_port *msm_port = UART_TO_MSM(port);
 365
 366        msm_port->imr = 0;
 367        msm_write(port, 0, UART_IMR); /* disable interrupts */
 368
 369        clk_disable(msm_port->clk);
 370
 371        free_irq(port->irq, port);
 372}
 373
 374static void msm_set_termios(struct uart_port *port, struct ktermios *termios,
 375                            struct ktermios *old)
 376{
 377        unsigned long flags;
 378        unsigned int baud, mr;
 379
 380        spin_lock_irqsave(&port->lock, flags);
 381
 382        /* calculate and set baud rate */
 383        baud = uart_get_baud_rate(port, termios, old, 300, 115200);
 384        baud = msm_set_baud_rate(port, baud);
 385        if (tty_termios_baud_rate(termios))
 386                tty_termios_encode_baud_rate(termios, baud, baud);
 387        
 388        /* calculate parity */
 389        mr = msm_read(port, UART_MR2);
 390        mr &= ~UART_MR2_PARITY_MODE;
 391        if (termios->c_cflag & PARENB) {
 392                if (termios->c_cflag & PARODD)
 393                        mr |= UART_MR2_PARITY_MODE_ODD;
 394                else if (termios->c_cflag & CMSPAR)
 395                        mr |= UART_MR2_PARITY_MODE_SPACE;
 396                else
 397                        mr |= UART_MR2_PARITY_MODE_EVEN;
 398        }
 399
 400        /* calculate bits per char */
 401        mr &= ~UART_MR2_BITS_PER_CHAR;
 402        switch (termios->c_cflag & CSIZE) {
 403        case CS5:
 404                mr |= UART_MR2_BITS_PER_CHAR_5;
 405                break;
 406        case CS6:
 407                mr |= UART_MR2_BITS_PER_CHAR_6;
 408                break;
 409        case CS7:
 410                mr |= UART_MR2_BITS_PER_CHAR_7;
 411                break;
 412        case CS8:
 413        default:
 414                mr |= UART_MR2_BITS_PER_CHAR_8;
 415                break;
 416        }
 417
 418        /* calculate stop bits */
 419        mr &= ~(UART_MR2_STOP_BIT_LEN_ONE | UART_MR2_STOP_BIT_LEN_TWO);
 420        if (termios->c_cflag & CSTOPB)
 421                mr |= UART_MR2_STOP_BIT_LEN_TWO;
 422        else
 423                mr |= UART_MR2_STOP_BIT_LEN_ONE;
 424
 425        /* set parity, bits per char, and stop bit */
 426        msm_write(port, mr, UART_MR2);
 427
 428        /* calculate and set hardware flow control */
 429        mr = msm_read(port, UART_MR1);
 430        mr &= ~(UART_MR1_CTS_CTL | UART_MR1_RX_RDY_CTL);
 431        if (termios->c_cflag & CRTSCTS) {
 432                mr |= UART_MR1_CTS_CTL;
 433                mr |= UART_MR1_RX_RDY_CTL;
 434        }
 435        msm_write(port, mr, UART_MR1);
 436
 437        /* Configure status bits to ignore based on termio flags. */
 438        port->read_status_mask = 0;
 439        if (termios->c_iflag & INPCK)
 440                port->read_status_mask |= UART_SR_PAR_FRAME_ERR;
 441        if (termios->c_iflag & (BRKINT | PARMRK))
 442                port->read_status_mask |= UART_SR_RX_BREAK;
 443
 444        uart_update_timeout(port, termios->c_cflag, baud);
 445
 446        spin_unlock_irqrestore(&port->lock, flags);
 447}
 448
 449static const char *msm_type(struct uart_port *port)
 450{
 451        return "MSM";
 452}
 453
 454static void msm_release_port(struct uart_port *port)
 455{
 456        struct platform_device *pdev = to_platform_device(port->dev);
 457        struct resource *resource;
 458        resource_size_t size;
 459
 460        resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 461        if (unlikely(!resource))
 462                return;
 463        size = resource->end - resource->start + 1;
 464
 465        release_mem_region(port->mapbase, size);
 466        iounmap(port->membase);
 467        port->membase = NULL;
 468}
 469
 470static int msm_request_port(struct uart_port *port)
 471{
 472        struct platform_device *pdev = to_platform_device(port->dev);
 473        struct resource *resource;
 474        resource_size_t size;
 475
 476        resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 477        if (unlikely(!resource))
 478                return -ENXIO;
 479        size = resource->end - resource->start + 1;
 480
 481        if (unlikely(!request_mem_region(port->mapbase, size, "msm_serial")))
 482                return -EBUSY;
 483
 484        port->membase = ioremap(port->mapbase, size);
 485        if (!port->membase) {
 486                release_mem_region(port->mapbase, size);
 487                return -EBUSY;
 488        }
 489
 490        return 0;
 491}
 492
 493static void msm_config_port(struct uart_port *port, int flags)
 494{
 495        if (flags & UART_CONFIG_TYPE) {
 496                port->type = PORT_MSM;
 497                msm_request_port(port);
 498        }
 499}
 500
 501static int msm_verify_port(struct uart_port *port, struct serial_struct *ser)
 502{
 503        if (unlikely(ser->type != PORT_UNKNOWN && ser->type != PORT_MSM))
 504                return -EINVAL;
 505        if (unlikely(port->irq != ser->irq))
 506                return -EINVAL;
 507        return 0;
 508}
 509
 510static void msm_power(struct uart_port *port, unsigned int state,
 511                      unsigned int oldstate)
 512{
 513        struct msm_port *msm_port = UART_TO_MSM(port);
 514
 515        switch (state) {
 516        case 0:
 517                clk_enable(msm_port->clk);
 518                break;
 519        case 3:
 520                clk_disable(msm_port->clk);
 521                break;
 522        default:
 523                printk(KERN_ERR "msm_serial: Unknown PM state %d\n", state);
 524        }
 525}
 526
 527static struct uart_ops msm_uart_pops = {
 528        .tx_empty = msm_tx_empty,
 529        .set_mctrl = msm_set_mctrl,
 530        .get_mctrl = msm_get_mctrl,
 531        .stop_tx = msm_stop_tx,
 532        .start_tx = msm_start_tx,
 533        .stop_rx = msm_stop_rx,
 534        .enable_ms = msm_enable_ms,
 535        .break_ctl = msm_break_ctl,
 536        .startup = msm_startup,
 537        .shutdown = msm_shutdown,
 538        .set_termios = msm_set_termios,
 539        .type = msm_type,
 540        .release_port = msm_release_port,
 541        .request_port = msm_request_port,
 542        .config_port = msm_config_port,
 543        .verify_port = msm_verify_port,
 544        .pm = msm_power,
 545};
 546
 547static struct msm_port msm_uart_ports[] = {
 548        {
 549                .uart = {
 550                        .iotype = UPIO_MEM,
 551                        .ops = &msm_uart_pops,
 552                        .flags = UPF_BOOT_AUTOCONF,
 553                        .fifosize = 512,
 554                        .line = 0,
 555                },
 556        },
 557        {
 558                .uart = {
 559                        .iotype = UPIO_MEM,
 560                        .ops = &msm_uart_pops,
 561                        .flags = UPF_BOOT_AUTOCONF,
 562                        .fifosize = 512,
 563                        .line = 1,
 564                },
 565        },
 566        {
 567                .uart = {
 568                        .iotype = UPIO_MEM,
 569                        .ops = &msm_uart_pops,
 570                        .flags = UPF_BOOT_AUTOCONF,
 571                        .fifosize = 64,
 572                        .line = 2,
 573                },
 574        },
 575};
 576
 577#define UART_NR ARRAY_SIZE(msm_uart_ports)
 578
 579static inline struct uart_port *get_port_from_line(unsigned int line)
 580{
 581        return &msm_uart_ports[line].uart;
 582}
 583
 584#ifdef CONFIG_SERIAL_MSM_CONSOLE
 585
 586static void msm_console_putchar(struct uart_port *port, int c)
 587{
 588        while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
 589                ;
 590        msm_write(port, c, UART_TF);
 591}
 592
 593static void msm_console_write(struct console *co, const char *s,
 594                              unsigned int count)
 595{
 596        struct uart_port *port;
 597        struct msm_port *msm_port;
 598
 599        BUG_ON(co->index < 0 || co->index >= UART_NR);
 600
 601        port = get_port_from_line(co->index);
 602        msm_port = UART_TO_MSM(port);
 603
 604        spin_lock(&port->lock);
 605        uart_console_write(port, s, count, msm_console_putchar);
 606        spin_unlock(&port->lock);
 607}
 608
 609static int __init msm_console_setup(struct console *co, char *options)
 610{
 611        struct uart_port *port;
 612        int baud, flow, bits, parity;
 613
 614        if (unlikely(co->index >= UART_NR || co->index < 0))
 615                return -ENXIO;
 616
 617        port = get_port_from_line(co->index);
 618
 619        if (unlikely(!port->membase))
 620                return -ENXIO;
 621
 622        port->cons = co;
 623
 624        msm_init_clock(port);
 625
 626        if (options)
 627                uart_parse_options(options, &baud, &parity, &bits, &flow);
 628
 629        bits = 8;
 630        parity = 'n';
 631        flow = 'n';
 632        msm_write(port, UART_MR2_BITS_PER_CHAR_8 | UART_MR2_STOP_BIT_LEN_ONE,
 633                  UART_MR2);    /* 8N1 */
 634
 635        if (baud < 300 || baud > 115200)
 636                baud = 115200;
 637        msm_set_baud_rate(port, baud);
 638
 639        msm_reset(port);
 640
 641        printk(KERN_INFO "msm_serial: console setup on port #%d\n", port->line);
 642
 643        return uart_set_options(port, co, baud, parity, bits, flow);
 644}
 645
 646static struct uart_driver msm_uart_driver;
 647
 648static struct console msm_console = {
 649        .name = "ttyMSM",
 650        .write = msm_console_write,
 651        .device = uart_console_device,
 652        .setup = msm_console_setup,
 653        .flags = CON_PRINTBUFFER,
 654        .index = -1,
 655        .data = &msm_uart_driver,
 656};
 657
 658#define MSM_CONSOLE     (&msm_console)
 659
 660#else
 661#define MSM_CONSOLE     NULL
 662#endif
 663
 664static struct uart_driver msm_uart_driver = {
 665        .owner = THIS_MODULE,
 666        .driver_name = "msm_serial",
 667        .dev_name = "ttyMSM",
 668        .nr = UART_NR,
 669        .cons = MSM_CONSOLE,
 670};
 671
 672static int __init msm_serial_probe(struct platform_device *pdev)
 673{
 674        struct msm_port *msm_port;
 675        struct resource *resource;
 676        struct uart_port *port;
 677        int irq;
 678
 679        if (unlikely(pdev->id < 0 || pdev->id >= UART_NR))
 680                return -ENXIO;
 681
 682        printk(KERN_INFO "msm_serial: detected port #%d\n", pdev->id);
 683
 684        port = get_port_from_line(pdev->id);
 685        port->dev = &pdev->dev;
 686        msm_port = UART_TO_MSM(port);
 687
 688        msm_port->clk = clk_get(&pdev->dev, "uart_clk");
 689        if (IS_ERR(msm_port->clk))
 690                return PTR_ERR(msm_port->clk);
 691        port->uartclk = clk_get_rate(msm_port->clk);
 692        printk(KERN_INFO "uartclk = %d\n", port->uartclk);
 693
 694
 695        resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 696        if (unlikely(!resource))
 697                return -ENXIO;
 698        port->mapbase = resource->start;
 699
 700        irq = platform_get_irq(pdev, 0);
 701        if (unlikely(irq < 0))
 702                return -ENXIO;
 703        port->irq = irq;
 704
 705        platform_set_drvdata(pdev, port);
 706
 707        return uart_add_one_port(&msm_uart_driver, port);
 708}
 709
 710static int __devexit msm_serial_remove(struct platform_device *pdev)
 711{
 712        struct msm_port *msm_port = platform_get_drvdata(pdev);
 713
 714        clk_put(msm_port->clk);
 715
 716        return 0;
 717}
 718
 719static struct platform_driver msm_platform_driver = {
 720        .remove = msm_serial_remove,
 721        .driver = {
 722                .name = "msm_serial",
 723                .owner = THIS_MODULE,
 724        },
 725};
 726
 727static int __init msm_serial_init(void)
 728{
 729        int ret;
 730
 731        ret = uart_register_driver(&msm_uart_driver);
 732        if (unlikely(ret))
 733                return ret;
 734
 735        ret = platform_driver_probe(&msm_platform_driver, msm_serial_probe);
 736        if (unlikely(ret))
 737                uart_unregister_driver(&msm_uart_driver);
 738
 739        printk(KERN_INFO "msm_serial: driver initialized\n");
 740
 741        return ret;
 742}
 743
 744static void __exit msm_serial_exit(void)
 745{
 746#ifdef CONFIG_SERIAL_MSM_CONSOLE
 747        unregister_console(&msm_console);
 748#endif
 749        platform_driver_unregister(&msm_platform_driver);
 750        uart_unregister_driver(&msm_uart_driver);
 751}
 752
 753module_init(msm_serial_init);
 754module_exit(msm_serial_exit);
 755
 756MODULE_AUTHOR("Robert Love <rlove@google.com>");
 757MODULE_DESCRIPTION("Driver for msm7x serial device");
 758MODULE_LICENSE("GPL");
 759