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