[ARM] 3571/1: netX: serial driver for Hilscher netX

Patch from Sascha Hauer

This patch adds the serial driver for Hilscher's netX network
processors.

Signed-off-by: Robert Schwebel <r.schwebel@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Sascha Hauer and committed by Russell King f8441e13 14228a49

+769
+19
drivers/serial/Kconfig
··· 936 936 If you have an SGI Altix with an IOC3 serial card, 937 937 say Y or M. Otherwise, say N. 938 938 939 + config SERIAL_NETX 940 + bool "NetX serial port support" 941 + depends on ARM && ARCH_NETX 942 + select SERIAL_CORE 943 + help 944 + If you have a machine based on a Hilscher NetX SoC you 945 + can enable its onboard serial port by enabling this option. 946 + 947 + To compile this driver as a module, choose M here: the 948 + module will be called netx-serial. 949 + 950 + config SERIAL_NETX_CONSOLE 951 + bool "Console on NetX serial port" 952 + depends on SERIAL_NETX 953 + select SERIAL_CORE_CONSOLE 954 + help 955 + If you have enabled the serial port on the Motorola IMX 956 + CPU you can make it the console by answering Y to this option. 957 + 939 958 endmenu
+1
drivers/serial/Makefile
··· 55 55 obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o 56 56 obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o 57 57 obj-$(CONFIG_SERIAL_AT91) += at91_serial.o 58 + obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
+749
drivers/serial/netx-serial.c
··· 1 + /* 2 + * drivers/serial/netx-serial.c 3 + * 4 + * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 8 + * as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program; if not, write to the Free Software 17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 + */ 19 + 20 + #include <linux/config.h> 21 + 22 + #if defined(CONFIG_SERIAL_NETX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 23 + #define SUPPORT_SYSRQ 24 + #endif 25 + 26 + #include <linux/device.h> 27 + #include <linux/module.h> 28 + #include <linux/ioport.h> 29 + #include <linux/init.h> 30 + #include <linux/console.h> 31 + #include <linux/sysrq.h> 32 + #include <linux/platform_device.h> 33 + #include <linux/tty.h> 34 + #include <linux/tty_flip.h> 35 + #include <linux/serial_core.h> 36 + #include <linux/serial.h> 37 + 38 + #include <asm/io.h> 39 + #include <asm/irq.h> 40 + #include <asm/hardware.h> 41 + #include <asm/arch/netx-regs.h> 42 + 43 + /* We've been assigned a range on the "Low-density serial ports" major */ 44 + #define SERIAL_NX_MAJOR 204 45 + #define MINOR_START 170 46 + 47 + #ifdef CONFIG_SERIAL_NETX_CONSOLE 48 + 49 + enum uart_regs { 50 + UART_DR = 0x00, 51 + UART_SR = 0x04, 52 + UART_LINE_CR = 0x08, 53 + UART_BAUDDIV_MSB = 0x0c, 54 + UART_BAUDDIV_LSB = 0x10, 55 + UART_CR = 0x14, 56 + UART_FR = 0x18, 57 + UART_IIR = 0x1c, 58 + UART_ILPR = 0x20, 59 + UART_RTS_CR = 0x24, 60 + UART_RTS_LEAD = 0x28, 61 + UART_RTS_TRAIL = 0x2c, 62 + UART_DRV_ENABLE = 0x30, 63 + UART_BRM_CR = 0x34, 64 + UART_RXFIFO_IRQLEVEL = 0x38, 65 + UART_TXFIFO_IRQLEVEL = 0x3c, 66 + }; 67 + 68 + #define SR_FE (1<<0) 69 + #define SR_PE (1<<1) 70 + #define SR_BE (1<<2) 71 + #define SR_OE (1<<3) 72 + 73 + #define LINE_CR_BRK (1<<0) 74 + #define LINE_CR_PEN (1<<1) 75 + #define LINE_CR_EPS (1<<2) 76 + #define LINE_CR_STP2 (1<<3) 77 + #define LINE_CR_FEN (1<<4) 78 + #define LINE_CR_5BIT (0<<5) 79 + #define LINE_CR_6BIT (1<<5) 80 + #define LINE_CR_7BIT (2<<5) 81 + #define LINE_CR_8BIT (3<<5) 82 + #define LINE_CR_BITS_MASK (3<<5) 83 + 84 + #define CR_UART_EN (1<<0) 85 + #define CR_SIREN (1<<1) 86 + #define CR_SIRLP (1<<2) 87 + #define CR_MSIE (1<<3) 88 + #define CR_RIE (1<<4) 89 + #define CR_TIE (1<<5) 90 + #define CR_RTIE (1<<6) 91 + #define CR_LBE (1<<7) 92 + 93 + #define FR_CTS (1<<0) 94 + #define FR_DSR (1<<1) 95 + #define FR_DCD (1<<2) 96 + #define FR_BUSY (1<<3) 97 + #define FR_RXFE (1<<4) 98 + #define FR_TXFF (1<<5) 99 + #define FR_RXFF (1<<6) 100 + #define FR_TXFE (1<<7) 101 + 102 + #define IIR_MIS (1<<0) 103 + #define IIR_RIS (1<<1) 104 + #define IIR_TIS (1<<2) 105 + #define IIR_RTIS (1<<3) 106 + #define IIR_MASK 0xf 107 + 108 + #define RTS_CR_AUTO (1<<0) 109 + #define RTS_CR_RTS (1<<1) 110 + #define RTS_CR_COUNT (1<<2) 111 + #define RTS_CR_MOD2 (1<<3) 112 + #define RTS_CR_RTS_POL (1<<4) 113 + #define RTS_CR_CTS_CTR (1<<5) 114 + #define RTS_CR_CTS_POL (1<<6) 115 + #define RTS_CR_STICK (1<<7) 116 + 117 + #define UART_PORT_SIZE 0x40 118 + #define DRIVER_NAME "netx-uart" 119 + 120 + struct netx_port { 121 + struct uart_port port; 122 + }; 123 + 124 + static void netx_stop_tx(struct uart_port *port) 125 + { 126 + unsigned int val; 127 + val = readl(port->membase + UART_CR); 128 + writel(val & ~CR_TIE, port->membase + UART_CR); 129 + } 130 + 131 + static void netx_stop_rx(struct uart_port *port) 132 + { 133 + unsigned int val; 134 + val = readl(port->membase + UART_CR); 135 + writel(val & ~CR_RIE, port->membase + UART_CR); 136 + } 137 + 138 + static void netx_enable_ms(struct uart_port *port) 139 + { 140 + unsigned int val; 141 + val = readl(port->membase + UART_CR); 142 + writel(val | CR_MSIE, port->membase + UART_CR); 143 + } 144 + 145 + static inline void netx_transmit_buffer(struct uart_port *port) 146 + { 147 + struct circ_buf *xmit = &port->info->xmit; 148 + 149 + if (port->x_char) { 150 + writel(port->x_char, port->membase + UART_DR); 151 + port->icount.tx++; 152 + port->x_char = 0; 153 + return; 154 + } 155 + 156 + if (uart_tx_stopped(port) || uart_circ_empty(xmit)) { 157 + netx_stop_tx(port); 158 + return; 159 + } 160 + 161 + do { 162 + /* send xmit->buf[xmit->tail] 163 + * out the port here */ 164 + writel(xmit->buf[xmit->tail], port->membase + UART_DR); 165 + xmit->tail = (xmit->tail + 1) & 166 + (UART_XMIT_SIZE - 1); 167 + port->icount.tx++; 168 + if (uart_circ_empty(xmit)) 169 + break; 170 + } while (!(readl(port->membase + UART_FR) & FR_TXFF)); 171 + 172 + if (uart_circ_empty(xmit)) 173 + netx_stop_tx(port); 174 + } 175 + 176 + static void netx_start_tx(struct uart_port *port) 177 + { 178 + writel( 179 + readl(port->membase + UART_CR) | CR_TIE, port->membase + UART_CR); 180 + 181 + if (!(readl(port->membase + UART_FR) & FR_TXFF)) 182 + netx_transmit_buffer(port); 183 + } 184 + 185 + static unsigned int netx_tx_empty(struct uart_port *port) 186 + { 187 + return readl(port->membase + UART_FR) & FR_BUSY ? 0 : TIOCSER_TEMT; 188 + } 189 + 190 + static void netx_txint(struct uart_port *port) 191 + { 192 + struct circ_buf *xmit = &port->info->xmit; 193 + 194 + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 195 + netx_stop_tx(port); 196 + return; 197 + } 198 + 199 + netx_transmit_buffer(port); 200 + 201 + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 202 + uart_write_wakeup(port); 203 + } 204 + 205 + static void netx_rxint(struct uart_port *port, struct pt_regs *regs) 206 + { 207 + unsigned char rx, flg, status; 208 + struct tty_struct *tty = port->info->tty; 209 + 210 + while (!(readl(port->membase + UART_FR) & FR_RXFE)) { 211 + rx = readl(port->membase + UART_DR); 212 + flg = TTY_NORMAL; 213 + port->icount.rx++; 214 + status = readl(port->membase + UART_SR); 215 + if (status & SR_BE) { 216 + writel(0, port->membase + UART_SR); 217 + if (uart_handle_break(port)) 218 + continue; 219 + } 220 + 221 + if (unlikely(status & (SR_FE | SR_PE | SR_OE))) { 222 + 223 + if (status & SR_PE) 224 + port->icount.parity++; 225 + else if (status & SR_FE) 226 + port->icount.frame++; 227 + if (status & SR_OE) 228 + port->icount.overrun++; 229 + 230 + status &= port->read_status_mask; 231 + 232 + if (status & SR_BE) 233 + flg = TTY_BREAK; 234 + else if (status & SR_PE) 235 + flg = TTY_PARITY; 236 + else if (status & SR_FE) 237 + flg = TTY_FRAME; 238 + } 239 + 240 + if (uart_handle_sysrq_char(port, rx, regs)) 241 + continue; 242 + 243 + uart_insert_char(port, status, SR_OE, rx, flg); 244 + } 245 + 246 + tty_flip_buffer_push(tty); 247 + return; 248 + } 249 + 250 + static irqreturn_t netx_int(int irq, void *dev_id, struct pt_regs *regs) 251 + { 252 + struct uart_port *port = (struct uart_port *)dev_id; 253 + unsigned long flags; 254 + unsigned char status; 255 + 256 + spin_lock_irqsave(&port->lock,flags); 257 + 258 + status = readl(port->membase + UART_IIR) & IIR_MASK; 259 + while (status) { 260 + if (status & IIR_RIS) 261 + netx_rxint(port, regs); 262 + if (status & IIR_TIS) 263 + netx_txint(port); 264 + if (status & IIR_MIS) { 265 + if (readl(port->membase + UART_FR) & FR_CTS) 266 + uart_handle_cts_change(port, 1); 267 + else 268 + uart_handle_cts_change(port, 0); 269 + } 270 + writel(0, port->membase + UART_IIR); 271 + status = readl(port->membase + UART_IIR) & IIR_MASK; 272 + } 273 + 274 + spin_unlock_irqrestore(&port->lock,flags); 275 + return IRQ_HANDLED; 276 + } 277 + 278 + static unsigned int netx_get_mctrl(struct uart_port *port) 279 + { 280 + unsigned int ret = TIOCM_DSR | TIOCM_CAR; 281 + 282 + if (readl(port->membase + UART_FR) & FR_CTS) 283 + ret |= TIOCM_CTS; 284 + 285 + return ret; 286 + } 287 + 288 + static void netx_set_mctrl(struct uart_port *port, unsigned int mctrl) 289 + { 290 + unsigned int val; 291 + 292 + if (mctrl & TIOCM_RTS) { 293 + val = readl(port->membase + UART_RTS_CR); 294 + writel(val | RTS_CR_RTS, port->membase + UART_RTS_CR); 295 + } 296 + } 297 + 298 + static void netx_break_ctl(struct uart_port *port, int break_state) 299 + { 300 + unsigned int line_cr; 301 + spin_lock_irq(&port->lock); 302 + 303 + line_cr = readl(port->membase + UART_LINE_CR); 304 + if (break_state != 0) 305 + line_cr |= LINE_CR_BRK; 306 + else 307 + line_cr &= ~LINE_CR_BRK; 308 + writel(line_cr, port->membase + UART_LINE_CR); 309 + 310 + spin_unlock_irq(&port->lock); 311 + } 312 + 313 + static int netx_startup(struct uart_port *port) 314 + { 315 + int ret; 316 + 317 + ret = request_irq(port->irq, netx_int, 0, 318 + DRIVER_NAME, port); 319 + if (ret) { 320 + dev_err(port->dev, "unable to grab irq%d\n",port->irq); 321 + goto exit; 322 + } 323 + 324 + writel(readl(port->membase + UART_LINE_CR) | LINE_CR_FEN, 325 + port->membase + UART_LINE_CR); 326 + 327 + writel(CR_MSIE | CR_RIE | CR_TIE | CR_RTIE | CR_UART_EN, 328 + port->membase + UART_CR); 329 + 330 + exit: 331 + return ret; 332 + } 333 + 334 + static void netx_shutdown(struct uart_port *port) 335 + { 336 + writel(0, port->membase + UART_CR) ; 337 + 338 + free_irq(port->irq, port); 339 + } 340 + 341 + static void 342 + netx_set_termios(struct uart_port *port, struct termios *termios, 343 + struct termios *old) 344 + { 345 + unsigned int baud, quot; 346 + unsigned char old_cr; 347 + unsigned char line_cr = LINE_CR_FEN; 348 + unsigned char rts_cr = 0; 349 + 350 + switch (termios->c_cflag & CSIZE) { 351 + case CS5: 352 + line_cr |= LINE_CR_5BIT; 353 + break; 354 + case CS6: 355 + line_cr |= LINE_CR_6BIT; 356 + break; 357 + case CS7: 358 + line_cr |= LINE_CR_7BIT; 359 + break; 360 + case CS8: 361 + line_cr |= LINE_CR_8BIT; 362 + break; 363 + } 364 + 365 + if (termios->c_cflag & CSTOPB) 366 + line_cr |= LINE_CR_STP2; 367 + 368 + if (termios->c_cflag & PARENB) { 369 + line_cr |= LINE_CR_PEN; 370 + if (!(termios->c_cflag & PARODD)) 371 + line_cr |= LINE_CR_EPS; 372 + } 373 + 374 + if (termios->c_cflag & CRTSCTS) 375 + rts_cr = RTS_CR_AUTO | RTS_CR_CTS_CTR | RTS_CR_RTS_POL; 376 + 377 + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 378 + quot = baud * 4096; 379 + quot /= 1000; 380 + quot *= 256; 381 + quot /= 100000; 382 + 383 + spin_lock_irq(&port->lock); 384 + 385 + uart_update_timeout(port, termios->c_cflag, baud); 386 + 387 + old_cr = readl(port->membase + UART_CR); 388 + 389 + /* disable interrupts */ 390 + writel(old_cr & ~(CR_MSIE | CR_RIE | CR_TIE | CR_RTIE), 391 + port->membase + UART_CR); 392 + 393 + /* drain transmitter */ 394 + while (readl(port->membase + UART_FR) & FR_BUSY); 395 + 396 + /* disable UART */ 397 + writel(old_cr & ~CR_UART_EN, port->membase + UART_CR); 398 + 399 + /* modem status interrupts */ 400 + old_cr &= ~CR_MSIE; 401 + if (UART_ENABLE_MS(port, termios->c_cflag)) 402 + old_cr |= CR_MSIE; 403 + 404 + writel((quot>>8) & 0xff, port->membase + UART_BAUDDIV_MSB); 405 + writel(quot & 0xff, port->membase + UART_BAUDDIV_LSB); 406 + writel(line_cr, port->membase + UART_LINE_CR); 407 + 408 + writel(rts_cr, port->membase + UART_RTS_CR); 409 + 410 + /* 411 + * Characters to ignore 412 + */ 413 + port->ignore_status_mask = 0; 414 + if (termios->c_iflag & IGNPAR) 415 + port->ignore_status_mask |= SR_PE; 416 + if (termios->c_iflag & IGNBRK) { 417 + port->ignore_status_mask |= SR_BE; 418 + /* 419 + * If we're ignoring parity and break indicators, 420 + * ignore overruns too (for real raw support). 421 + */ 422 + if (termios->c_iflag & IGNPAR) 423 + port->ignore_status_mask |= SR_PE; 424 + } 425 + 426 + port->read_status_mask = 0; 427 + if (termios->c_iflag & (BRKINT | PARMRK)) 428 + port->read_status_mask |= SR_BE; 429 + if (termios->c_iflag & INPCK) 430 + port->read_status_mask |= SR_PE | SR_FE; 431 + 432 + writel(old_cr, port->membase + UART_CR); 433 + 434 + spin_unlock_irq(&port->lock); 435 + } 436 + 437 + static const char *netx_type(struct uart_port *port) 438 + { 439 + return port->type == PORT_NETX ? "NETX" : NULL; 440 + } 441 + 442 + static void netx_release_port(struct uart_port *port) 443 + { 444 + release_mem_region(port->mapbase, UART_PORT_SIZE); 445 + } 446 + 447 + static int netx_request_port(struct uart_port *port) 448 + { 449 + return request_mem_region(port->mapbase, UART_PORT_SIZE, 450 + DRIVER_NAME) != NULL ? 0 : -EBUSY; 451 + } 452 + 453 + static void netx_config_port(struct uart_port *port, int flags) 454 + { 455 + if (flags & UART_CONFIG_TYPE && netx_request_port(port) == 0) 456 + port->type = PORT_NETX; 457 + } 458 + 459 + static int 460 + netx_verify_port(struct uart_port *port, struct serial_struct *ser) 461 + { 462 + int ret = 0; 463 + 464 + if (ser->type != PORT_UNKNOWN && ser->type != PORT_NETX) 465 + ret = -EINVAL; 466 + 467 + return ret; 468 + } 469 + 470 + static struct uart_ops netx_pops = { 471 + .tx_empty = netx_tx_empty, 472 + .set_mctrl = netx_set_mctrl, 473 + .get_mctrl = netx_get_mctrl, 474 + .stop_tx = netx_stop_tx, 475 + .start_tx = netx_start_tx, 476 + .stop_rx = netx_stop_rx, 477 + .enable_ms = netx_enable_ms, 478 + .break_ctl = netx_break_ctl, 479 + .startup = netx_startup, 480 + .shutdown = netx_shutdown, 481 + .set_termios = netx_set_termios, 482 + .type = netx_type, 483 + .release_port = netx_release_port, 484 + .request_port = netx_request_port, 485 + .config_port = netx_config_port, 486 + .verify_port = netx_verify_port, 487 + }; 488 + 489 + static struct netx_port netx_ports[] = { 490 + { 491 + .port = { 492 + .type = PORT_NETX, 493 + .iotype = UPIO_MEM, 494 + .membase = (char __iomem *)io_p2v(NETX_PA_UART0), 495 + .mapbase = NETX_PA_UART0, 496 + .irq = NETX_IRQ_UART0, 497 + .uartclk = 100000000, 498 + .fifosize = 16, 499 + .flags = UPF_BOOT_AUTOCONF, 500 + .ops = &netx_pops, 501 + .line = 0, 502 + }, 503 + }, { 504 + .port = { 505 + .type = PORT_NETX, 506 + .iotype = UPIO_MEM, 507 + .membase = (char __iomem *)io_p2v(NETX_PA_UART1), 508 + .mapbase = NETX_PA_UART1, 509 + .irq = NETX_IRQ_UART1, 510 + .uartclk = 100000000, 511 + .fifosize = 16, 512 + .flags = UPF_BOOT_AUTOCONF, 513 + .ops = &netx_pops, 514 + .line = 1, 515 + }, 516 + }, { 517 + .port = { 518 + .type = PORT_NETX, 519 + .iotype = UPIO_MEM, 520 + .membase = (char __iomem *)io_p2v(NETX_PA_UART2), 521 + .mapbase = NETX_PA_UART2, 522 + .irq = NETX_IRQ_UART2, 523 + .uartclk = 100000000, 524 + .fifosize = 16, 525 + .flags = UPF_BOOT_AUTOCONF, 526 + .ops = &netx_pops, 527 + .line = 2, 528 + }, 529 + } 530 + }; 531 + 532 + static void netx_console_putchar(struct uart_port *port, int ch) 533 + { 534 + while (readl(port->membase + UART_FR) & FR_BUSY); 535 + writel(ch, port->membase + UART_DR); 536 + } 537 + 538 + static void 539 + netx_console_write(struct console *co, const char *s, unsigned int count) 540 + { 541 + struct uart_port *port = &netx_ports[co->index].port; 542 + unsigned char cr_save; 543 + 544 + cr_save = readl(port->membase + UART_CR); 545 + writel(cr_save | CR_UART_EN, port->membase + UART_CR); 546 + 547 + uart_console_write(port, s, count, netx_console_putchar); 548 + 549 + while (readl(port->membase + UART_FR) & FR_BUSY); 550 + writel(cr_save, port->membase + UART_CR); 551 + } 552 + 553 + static void __init 554 + netx_console_get_options(struct uart_port *port, int *baud, 555 + int *parity, int *bits, int *flow) 556 + { 557 + unsigned char line_cr; 558 + 559 + *baud = (readl(port->membase + UART_BAUDDIV_MSB) << 8) | 560 + readl(port->membase + UART_BAUDDIV_LSB); 561 + *baud *= 1000; 562 + *baud /= 4096; 563 + *baud *= 1000; 564 + *baud /= 256; 565 + *baud *= 100; 566 + 567 + line_cr = readl(port->membase + UART_LINE_CR); 568 + *parity = 'n'; 569 + if (line_cr & LINE_CR_PEN) { 570 + if (line_cr & LINE_CR_EPS) 571 + *parity = 'e'; 572 + else 573 + *parity = 'o'; 574 + } 575 + 576 + switch (line_cr & LINE_CR_BITS_MASK) { 577 + case LINE_CR_8BIT: 578 + *bits = 8; 579 + break; 580 + case LINE_CR_7BIT: 581 + *bits = 7; 582 + break; 583 + case LINE_CR_6BIT: 584 + *bits = 6; 585 + break; 586 + case LINE_CR_5BIT: 587 + *bits = 5; 588 + break; 589 + } 590 + 591 + if (readl(port->membase + UART_RTS_CR) & RTS_CR_AUTO) 592 + *flow = 'r'; 593 + } 594 + 595 + static int __init 596 + netx_console_setup(struct console *co, char *options) 597 + { 598 + struct netx_port *sport; 599 + int baud = 9600; 600 + int bits = 8; 601 + int parity = 'n'; 602 + int flow = 'n'; 603 + 604 + /* 605 + * Check whether an invalid uart number has been specified, and 606 + * if so, search for the first available port that does have 607 + * console support. 608 + */ 609 + if (co->index == -1 || co->index >= ARRAY_SIZE(netx_ports)) 610 + co->index = 0; 611 + sport = &netx_ports[co->index]; 612 + 613 + if (options) { 614 + uart_parse_options(options, &baud, &parity, &bits, &flow); 615 + } else { 616 + /* if the UART is enabled, assume it has been correctly setup 617 + * by the bootloader and get the options 618 + */ 619 + if (readl(sport->port.membase + UART_CR) & CR_UART_EN) { 620 + netx_console_get_options(&sport->port, &baud, 621 + &parity, &bits, &flow); 622 + } 623 + 624 + } 625 + 626 + return uart_set_options(&sport->port, co, baud, parity, bits, flow); 627 + } 628 + 629 + static struct uart_driver netx_reg; 630 + static struct console netx_console = { 631 + .name = "ttyNX", 632 + .write = netx_console_write, 633 + .device = uart_console_device, 634 + .setup = netx_console_setup, 635 + .flags = CON_PRINTBUFFER, 636 + .index = -1, 637 + .data = &netx_reg, 638 + }; 639 + 640 + static int __init netx_console_init(void) 641 + { 642 + register_console(&netx_console); 643 + return 0; 644 + } 645 + console_initcall(netx_console_init); 646 + 647 + #define NETX_CONSOLE &netx_console 648 + #else 649 + #define NETX_CONSOLE NULL 650 + #endif 651 + 652 + static struct uart_driver netx_reg = { 653 + .owner = THIS_MODULE, 654 + .driver_name = DRIVER_NAME, 655 + .dev_name = "ttyNX", 656 + .major = SERIAL_NX_MAJOR, 657 + .minor = MINOR_START, 658 + .nr = ARRAY_SIZE(netx_ports), 659 + .cons = NETX_CONSOLE, 660 + }; 661 + 662 + static int serial_netx_suspend(struct platform_device *pdev, pm_message_t state) 663 + { 664 + struct netx_port *sport = platform_get_drvdata(pdev); 665 + 666 + if (sport) 667 + uart_suspend_port(&netx_reg, &sport->port); 668 + 669 + return 0; 670 + } 671 + 672 + static int serial_netx_resume(struct platform_device *pdev) 673 + { 674 + struct netx_port *sport = platform_get_drvdata(pdev); 675 + 676 + if (sport) 677 + uart_resume_port(&netx_reg, &sport->port); 678 + 679 + return 0; 680 + } 681 + 682 + static int serial_netx_probe(struct platform_device *pdev) 683 + { 684 + struct uart_port *port = &netx_ports[pdev->id].port; 685 + 686 + dev_info(&pdev->dev, "initialising\n"); 687 + 688 + port->dev = &pdev->dev; 689 + 690 + writel(1, port->membase + UART_RXFIFO_IRQLEVEL); 691 + uart_add_one_port(&netx_reg, &netx_ports[pdev->id].port); 692 + platform_set_drvdata(pdev, &netx_ports[pdev->id]); 693 + 694 + return 0; 695 + } 696 + 697 + static int serial_netx_remove(struct platform_device *pdev) 698 + { 699 + struct netx_port *sport = platform_get_drvdata(pdev); 700 + 701 + platform_set_drvdata(pdev, NULL); 702 + 703 + if (sport) 704 + uart_remove_one_port(&netx_reg, &sport->port); 705 + 706 + return 0; 707 + } 708 + 709 + static struct platform_driver serial_netx_driver = { 710 + .probe = serial_netx_probe, 711 + .remove = serial_netx_remove, 712 + 713 + .suspend = serial_netx_suspend, 714 + .resume = serial_netx_resume, 715 + 716 + .driver = { 717 + .name = DRIVER_NAME, 718 + }, 719 + }; 720 + 721 + static int __init netx_serial_init(void) 722 + { 723 + int ret; 724 + 725 + printk(KERN_INFO "Serial: NetX driver\n"); 726 + 727 + ret = uart_register_driver(&netx_reg); 728 + if (ret) 729 + return ret; 730 + 731 + ret = platform_driver_register(&serial_netx_driver); 732 + if (ret != 0) 733 + uart_unregister_driver(&netx_reg); 734 + 735 + return 0; 736 + } 737 + 738 + static void __exit netx_serial_exit(void) 739 + { 740 + platform_driver_unregister(&serial_netx_driver); 741 + uart_unregister_driver(&netx_reg); 742 + } 743 + 744 + module_init(netx_serial_init); 745 + module_exit(netx_serial_exit); 746 + 747 + MODULE_AUTHOR("Sascha Hauer"); 748 + MODULE_DESCRIPTION("NetX serial port driver"); 749 + MODULE_LICENSE("GPL");