tilegx.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. /*
  2. * Copyright 2013 Tilera Corporation. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation, version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11. * NON INFRINGEMENT. See the GNU General Public License for
  12. * more details.
  13. *
  14. * TILEGx UART driver.
  15. */
  16. #include <linux/delay.h>
  17. #include <linux/init.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/io.h>
  20. #include <linux/irq.h>
  21. #include <linux/module.h>
  22. #include <linux/serial_core.h>
  23. #include <linux/tty.h>
  24. #include <linux/tty_flip.h>
  25. #include <gxio/common.h>
  26. #include <gxio/iorpc_globals.h>
  27. #include <gxio/iorpc_uart.h>
  28. #include <gxio/kiorpc.h>
  29. #include <hv/drv_uart_intf.h>
  30. /*
  31. * Use device name ttyS, major 4, minor 64-65.
  32. * This is the usual serial port name, 8250 conventional range.
  33. */
  34. #define TILEGX_UART_MAJOR TTY_MAJOR
  35. #define TILEGX_UART_MINOR 64
  36. #define TILEGX_UART_NAME "ttyS"
  37. #define DRIVER_NAME_STRING "TILEGx_Serial"
  38. #define TILEGX_UART_REF_CLK 125000000; /* REF_CLK is always 125 MHz. */
  39. struct tile_uart_port {
  40. /* UART port. */
  41. struct uart_port uart;
  42. /* GXIO device context. */
  43. gxio_uart_context_t context;
  44. /* UART access mutex. */
  45. struct mutex mutex;
  46. /* CPU receiving interrupts. */
  47. int irq_cpu;
  48. };
  49. static struct tile_uart_port tile_uart_ports[TILEGX_UART_NR];
  50. static struct uart_driver tilegx_uart_driver;
  51. /*
  52. * Read UART rx fifo, and insert the chars into tty buffer.
  53. */
  54. static void receive_chars(struct tile_uart_port *tile_uart,
  55. struct tty_struct *tty)
  56. {
  57. int i;
  58. char c;
  59. UART_FIFO_COUNT_t count;
  60. gxio_uart_context_t *context = &tile_uart->context;
  61. struct tty_port *port = tty->port;
  62. count.word = gxio_uart_read(context, UART_FIFO_COUNT);
  63. for (i = 0; i < count.rfifo_count; i++) {
  64. c = (char)gxio_uart_read(context, UART_RECEIVE_DATA);
  65. tty_insert_flip_char(port, c, TTY_NORMAL);
  66. }
  67. }
  68. /*
  69. * Drain the Rx FIFO, called by interrupt handler.
  70. */
  71. static void handle_receive(struct tile_uart_port *tile_uart)
  72. {
  73. struct tty_port *port = &tile_uart->uart.state->port;
  74. struct tty_struct *tty = tty_port_tty_get(port);
  75. gxio_uart_context_t *context = &tile_uart->context;
  76. if (!tty)
  77. return;
  78. /* First read UART rx fifo. */
  79. receive_chars(tile_uart, tty);
  80. /* Reset RFIFO_WE interrupt. */
  81. gxio_uart_write(context, UART_INTERRUPT_STATUS,
  82. UART_INTERRUPT_MASK__RFIFO_WE_MASK);
  83. /* Final read, if any chars comes between the first read and
  84. * the interrupt reset.
  85. */
  86. receive_chars(tile_uart, tty);
  87. spin_unlock(&tile_uart->uart.lock);
  88. tty_flip_buffer_push(port);
  89. spin_lock(&tile_uart->uart.lock);
  90. tty_kref_put(tty);
  91. }
  92. /*
  93. * Push one char to UART Write FIFO.
  94. * Return 0 on success, -1 if write filo is full.
  95. */
  96. static int tilegx_putchar(gxio_uart_context_t *context, char c)
  97. {
  98. UART_FLAG_t flag;
  99. flag.word = gxio_uart_read(context, UART_FLAG);
  100. if (flag.wfifo_full)
  101. return -1;
  102. gxio_uart_write(context, UART_TRANSMIT_DATA, (unsigned long)c);
  103. return 0;
  104. }
  105. /*
  106. * Send chars to UART Write FIFO; called by interrupt handler.
  107. */
  108. static void handle_transmit(struct tile_uart_port *tile_uart)
  109. {
  110. unsigned char ch;
  111. struct uart_port *port;
  112. struct circ_buf *xmit;
  113. gxio_uart_context_t *context = &tile_uart->context;
  114. /* First reset WFIFO_RE interrupt. */
  115. gxio_uart_write(context, UART_INTERRUPT_STATUS,
  116. UART_INTERRUPT_MASK__WFIFO_RE_MASK);
  117. port = &tile_uart->uart;
  118. xmit = &port->state->xmit;
  119. if (port->x_char) {
  120. if (tilegx_putchar(context, port->x_char))
  121. return;
  122. port->x_char = 0;
  123. port->icount.tx++;
  124. }
  125. if (uart_circ_empty(xmit) || uart_tx_stopped(port))
  126. return;
  127. while (!uart_circ_empty(xmit)) {
  128. ch = xmit->buf[xmit->tail];
  129. if (tilegx_putchar(context, ch))
  130. break;
  131. xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
  132. port->icount.tx++;
  133. }
  134. /* Reset WFIFO_RE interrupt. */
  135. gxio_uart_write(context, UART_INTERRUPT_STATUS,
  136. UART_INTERRUPT_MASK__WFIFO_RE_MASK);
  137. if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
  138. uart_write_wakeup(port);
  139. }
  140. /*
  141. * UART Interrupt handler.
  142. */
  143. static irqreturn_t tilegx_interrupt(int irq, void *dev_id)
  144. {
  145. unsigned long flags;
  146. UART_INTERRUPT_STATUS_t intr_stat;
  147. struct tile_uart_port *tile_uart;
  148. gxio_uart_context_t *context;
  149. struct uart_port *port = dev_id;
  150. irqreturn_t ret = IRQ_NONE;
  151. spin_lock_irqsave(&port->lock, flags);
  152. tile_uart = container_of(port, struct tile_uart_port, uart);
  153. context = &tile_uart->context;
  154. intr_stat.word = gxio_uart_read(context, UART_INTERRUPT_STATUS);
  155. if (intr_stat.rfifo_we) {
  156. handle_receive(tile_uart);
  157. ret = IRQ_HANDLED;
  158. }
  159. if (intr_stat.wfifo_re) {
  160. handle_transmit(tile_uart);
  161. ret = IRQ_HANDLED;
  162. }
  163. spin_unlock_irqrestore(&port->lock, flags);
  164. return ret;
  165. }
  166. /*
  167. * Return TIOCSER_TEMT when transmitter FIFO is empty.
  168. */
  169. static u_int tilegx_tx_empty(struct uart_port *port)
  170. {
  171. int ret;
  172. UART_FLAG_t flag;
  173. struct tile_uart_port *tile_uart;
  174. gxio_uart_context_t *context;
  175. tile_uart = container_of(port, struct tile_uart_port, uart);
  176. if (!mutex_trylock(&tile_uart->mutex))
  177. return 0;
  178. context = &tile_uart->context;
  179. flag.word = gxio_uart_read(context, UART_FLAG);
  180. ret = (flag.wfifo_empty) ? TIOCSER_TEMT : 0;
  181. mutex_unlock(&tile_uart->mutex);
  182. return ret;
  183. }
  184. /*
  185. * Set state of the modem control output lines.
  186. */
  187. static void tilegx_set_mctrl(struct uart_port *port, u_int mctrl)
  188. {
  189. /* N/A */
  190. }
  191. /*
  192. * Get state of the modem control input lines.
  193. */
  194. static u_int tilegx_get_mctrl(struct uart_port *port)
  195. {
  196. return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
  197. }
  198. /*
  199. * Stop transmitting.
  200. */
  201. static void tilegx_stop_tx(struct uart_port *port)
  202. {
  203. /* N/A */
  204. }
  205. /*
  206. * Start transmitting.
  207. */
  208. static void tilegx_start_tx(struct uart_port *port)
  209. {
  210. unsigned char ch;
  211. struct circ_buf *xmit;
  212. struct tile_uart_port *tile_uart;
  213. gxio_uart_context_t *context;
  214. tile_uart = container_of(port, struct tile_uart_port, uart);
  215. if (!mutex_trylock(&tile_uart->mutex))
  216. return;
  217. context = &tile_uart->context;
  218. xmit = &port->state->xmit;
  219. if (port->x_char) {
  220. if (tilegx_putchar(context, port->x_char))
  221. return;
  222. port->x_char = 0;
  223. port->icount.tx++;
  224. }
  225. if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
  226. mutex_unlock(&tile_uart->mutex);
  227. return;
  228. }
  229. while (!uart_circ_empty(xmit)) {
  230. ch = xmit->buf[xmit->tail];
  231. if (tilegx_putchar(context, ch))
  232. break;
  233. xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
  234. port->icount.tx++;
  235. }
  236. if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
  237. uart_write_wakeup(port);
  238. mutex_unlock(&tile_uart->mutex);
  239. }
  240. /*
  241. * Stop receiving - port is in process of being closed.
  242. */
  243. static void tilegx_stop_rx(struct uart_port *port)
  244. {
  245. int err;
  246. struct tile_uart_port *tile_uart;
  247. gxio_uart_context_t *context;
  248. int cpu;
  249. tile_uart = container_of(port, struct tile_uart_port, uart);
  250. if (!mutex_trylock(&tile_uart->mutex))
  251. return;
  252. context = &tile_uart->context;
  253. cpu = tile_uart->irq_cpu;
  254. err = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
  255. KERNEL_PL, -1);
  256. mutex_unlock(&tile_uart->mutex);
  257. }
  258. /*
  259. * Control the transmission of a break signal.
  260. */
  261. static void tilegx_break_ctl(struct uart_port *port, int break_state)
  262. {
  263. /* N/A */
  264. }
  265. /*
  266. * Perform initialization and enable port for reception.
  267. */
  268. static int tilegx_startup(struct uart_port *port)
  269. {
  270. struct tile_uart_port *tile_uart;
  271. gxio_uart_context_t *context;
  272. int ret = 0;
  273. int cpu = raw_smp_processor_id(); /* pick an arbitrary cpu */
  274. tile_uart = container_of(port, struct tile_uart_port, uart);
  275. if (mutex_lock_interruptible(&tile_uart->mutex))
  276. return -EBUSY;
  277. context = &tile_uart->context;
  278. /* Now open the hypervisor device if we haven't already. */
  279. if (context->fd < 0) {
  280. UART_INTERRUPT_MASK_t intr_mask;
  281. /* Initialize UART device. */
  282. ret = gxio_uart_init(context, port->line);
  283. if (ret) {
  284. ret = -ENXIO;
  285. goto err;
  286. }
  287. /* Create our IRQs. */
  288. port->irq = irq_alloc_hwirq(-1);
  289. if (!port->irq)
  290. goto err_uart_dest;
  291. tile_irq_activate(port->irq, TILE_IRQ_PERCPU);
  292. /* Register our IRQs. */
  293. ret = request_irq(port->irq, tilegx_interrupt, 0,
  294. tilegx_uart_driver.driver_name, port);
  295. if (ret)
  296. goto err_dest_irq;
  297. /* Request that the hardware start sending us interrupts. */
  298. tile_uart->irq_cpu = cpu;
  299. ret = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
  300. KERNEL_PL, port->irq);
  301. if (ret)
  302. goto err_free_irq;
  303. /* Enable UART Tx/Rx Interrupt. */
  304. intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
  305. intr_mask.wfifo_re = 0;
  306. intr_mask.rfifo_we = 0;
  307. gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);
  308. /* Reset the Tx/Rx interrupt in case it's set. */
  309. gxio_uart_write(context, UART_INTERRUPT_STATUS,
  310. UART_INTERRUPT_MASK__WFIFO_RE_MASK |
  311. UART_INTERRUPT_MASK__RFIFO_WE_MASK);
  312. }
  313. mutex_unlock(&tile_uart->mutex);
  314. return ret;
  315. err_free_irq:
  316. free_irq(port->irq, port);
  317. err_dest_irq:
  318. irq_free_hwirq(port->irq);
  319. err_uart_dest:
  320. gxio_uart_destroy(context);
  321. ret = -ENXIO;
  322. err:
  323. mutex_unlock(&tile_uart->mutex);
  324. return ret;
  325. }
  326. /*
  327. * Release kernel resources if it is the last close, disable the port,
  328. * free IRQ and close the port.
  329. */
  330. static void tilegx_shutdown(struct uart_port *port)
  331. {
  332. int err;
  333. UART_INTERRUPT_MASK_t intr_mask;
  334. struct tile_uart_port *tile_uart;
  335. gxio_uart_context_t *context;
  336. int cpu;
  337. tile_uart = container_of(port, struct tile_uart_port, uart);
  338. if (mutex_lock_interruptible(&tile_uart->mutex))
  339. return;
  340. context = &tile_uart->context;
  341. /* Disable UART Tx/Rx Interrupt. */
  342. intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
  343. intr_mask.wfifo_re = 1;
  344. intr_mask.rfifo_we = 1;
  345. gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);
  346. /* Request that the hardware stop sending us interrupts. */
  347. cpu = tile_uart->irq_cpu;
  348. err = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
  349. KERNEL_PL, -1);
  350. if (port->irq > 0) {
  351. free_irq(port->irq, port);
  352. irq_free_hwirq(port->irq);
  353. port->irq = 0;
  354. }
  355. gxio_uart_destroy(context);
  356. mutex_unlock(&tile_uart->mutex);
  357. }
  358. /*
  359. * Flush the buffer.
  360. */
  361. static void tilegx_flush_buffer(struct uart_port *port)
  362. {
  363. /* N/A */
  364. }
  365. /*
  366. * Change the port parameters.
  367. */
  368. static void tilegx_set_termios(struct uart_port *port,
  369. struct ktermios *termios, struct ktermios *old)
  370. {
  371. int err;
  372. UART_DIVISOR_t divisor;
  373. UART_TYPE_t type;
  374. unsigned int baud;
  375. struct tile_uart_port *tile_uart;
  376. gxio_uart_context_t *context;
  377. tile_uart = container_of(port, struct tile_uart_port, uart);
  378. if (!mutex_trylock(&tile_uart->mutex))
  379. return;
  380. context = &tile_uart->context;
  381. /* Open the hypervisor device if we haven't already. */
  382. if (context->fd < 0) {
  383. err = gxio_uart_init(context, port->line);
  384. if (err) {
  385. mutex_unlock(&tile_uart->mutex);
  386. return;
  387. }
  388. }
  389. divisor.word = gxio_uart_read(context, UART_DIVISOR);
  390. type.word = gxio_uart_read(context, UART_TYPE);
  391. /* Divisor. */
  392. baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
  393. divisor.divisor = uart_get_divisor(port, baud);
  394. /* Byte size. */
  395. if ((termios->c_cflag & CSIZE) == CS7)
  396. type.dbits = UART_TYPE__DBITS_VAL_SEVEN_DBITS;
  397. else
  398. type.dbits = UART_TYPE__DBITS_VAL_EIGHT_DBITS;
  399. /* Parity. */
  400. if (termios->c_cflag & PARENB) {
  401. /* Mark or Space parity. */
  402. if (termios->c_cflag & CMSPAR)
  403. if (termios->c_cflag & PARODD)
  404. type.ptype = UART_TYPE__PTYPE_VAL_MARK;
  405. else
  406. type.ptype = UART_TYPE__PTYPE_VAL_SPACE;
  407. else if (termios->c_cflag & PARODD)
  408. type.ptype = UART_TYPE__PTYPE_VAL_ODD;
  409. else
  410. type.ptype = UART_TYPE__PTYPE_VAL_EVEN;
  411. } else
  412. type.ptype = UART_TYPE__PTYPE_VAL_NONE;
  413. /* Stop bits. */
  414. if (termios->c_cflag & CSTOPB)
  415. type.sbits = UART_TYPE__SBITS_VAL_TWO_SBITS;
  416. else
  417. type.sbits = UART_TYPE__SBITS_VAL_ONE_SBITS;
  418. /* Set the uart paramters. */
  419. gxio_uart_write(context, UART_DIVISOR, divisor.word);
  420. gxio_uart_write(context, UART_TYPE, type.word);
  421. mutex_unlock(&tile_uart->mutex);
  422. }
  423. /*
  424. * Return string describing the specified port.
  425. */
  426. static const char *tilegx_type(struct uart_port *port)
  427. {
  428. return port->type == PORT_TILEGX ? DRIVER_NAME_STRING : NULL;
  429. }
  430. /*
  431. * Release the resources being used by 'port'.
  432. */
  433. static void tilegx_release_port(struct uart_port *port)
  434. {
  435. /* Nothing to release. */
  436. }
  437. /*
  438. * Request the resources being used by 'port'.
  439. */
  440. static int tilegx_request_port(struct uart_port *port)
  441. {
  442. /* Always present. */
  443. return 0;
  444. }
  445. /*
  446. * Configure/autoconfigure the port.
  447. */
  448. static void tilegx_config_port(struct uart_port *port, int flags)
  449. {
  450. if (flags & UART_CONFIG_TYPE)
  451. port->type = PORT_TILEGX;
  452. }
  453. /*
  454. * Verify the new serial_struct (for TIOCSSERIAL).
  455. */
  456. static int tilegx_verify_port(struct uart_port *port,
  457. struct serial_struct *ser)
  458. {
  459. if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_TILEGX))
  460. return -EINVAL;
  461. return 0;
  462. }
  463. #ifdef CONFIG_CONSOLE_POLL
  464. /*
  465. * Console polling routines for writing and reading from the uart while
  466. * in an interrupt or debug context.
  467. */
  468. static int tilegx_poll_get_char(struct uart_port *port)
  469. {
  470. UART_FIFO_COUNT_t count;
  471. gxio_uart_context_t *context;
  472. struct tile_uart_port *tile_uart;
  473. tile_uart = container_of(port, struct tile_uart_port, uart);
  474. context = &tile_uart->context;
  475. count.word = gxio_uart_read(context, UART_FIFO_COUNT);
  476. if (count.rfifo_count == 0)
  477. return NO_POLL_CHAR;
  478. return (char)gxio_uart_read(context, UART_RECEIVE_DATA);
  479. }
  480. static void tilegx_poll_put_char(struct uart_port *port, unsigned char c)
  481. {
  482. gxio_uart_context_t *context;
  483. struct tile_uart_port *tile_uart;
  484. tile_uart = container_of(port, struct tile_uart_port, uart);
  485. context = &tile_uart->context;
  486. gxio_uart_write(context, UART_TRANSMIT_DATA, (unsigned long)c);
  487. }
  488. #endif /* CONFIG_CONSOLE_POLL */
  489. static const struct uart_ops tilegx_ops = {
  490. .tx_empty = tilegx_tx_empty,
  491. .set_mctrl = tilegx_set_mctrl,
  492. .get_mctrl = tilegx_get_mctrl,
  493. .stop_tx = tilegx_stop_tx,
  494. .start_tx = tilegx_start_tx,
  495. .stop_rx = tilegx_stop_rx,
  496. .break_ctl = tilegx_break_ctl,
  497. .startup = tilegx_startup,
  498. .shutdown = tilegx_shutdown,
  499. .flush_buffer = tilegx_flush_buffer,
  500. .set_termios = tilegx_set_termios,
  501. .type = tilegx_type,
  502. .release_port = tilegx_release_port,
  503. .request_port = tilegx_request_port,
  504. .config_port = tilegx_config_port,
  505. .verify_port = tilegx_verify_port,
  506. #ifdef CONFIG_CONSOLE_POLL
  507. .poll_get_char = tilegx_poll_get_char,
  508. .poll_put_char = tilegx_poll_put_char,
  509. #endif
  510. };
  511. static void tilegx_init_ports(void)
  512. {
  513. int i;
  514. struct uart_port *port;
  515. for (i = 0; i < TILEGX_UART_NR; i++) {
  516. port = &tile_uart_ports[i].uart;
  517. port->ops = &tilegx_ops;
  518. port->line = i;
  519. port->type = PORT_TILEGX;
  520. port->uartclk = TILEGX_UART_REF_CLK;
  521. port->flags = UPF_BOOT_AUTOCONF;
  522. tile_uart_ports[i].context.fd = -1;
  523. mutex_init(&tile_uart_ports[i].mutex);
  524. }
  525. }
  526. static struct uart_driver tilegx_uart_driver = {
  527. .owner = THIS_MODULE,
  528. .driver_name = DRIVER_NAME_STRING,
  529. .dev_name = TILEGX_UART_NAME,
  530. .major = TILEGX_UART_MAJOR,
  531. .minor = TILEGX_UART_MINOR,
  532. .nr = TILEGX_UART_NR,
  533. };
  534. static int __init tilegx_init(void)
  535. {
  536. int i;
  537. int ret;
  538. struct tty_driver *tty_drv;
  539. ret = uart_register_driver(&tilegx_uart_driver);
  540. if (ret)
  541. return ret;
  542. tty_drv = tilegx_uart_driver.tty_driver;
  543. tty_drv->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
  544. tty_drv->init_termios.c_ispeed = 115200;
  545. tty_drv->init_termios.c_ospeed = 115200;
  546. tilegx_init_ports();
  547. for (i = 0; i < TILEGX_UART_NR; i++) {
  548. struct uart_port *port = &tile_uart_ports[i].uart;
  549. ret = uart_add_one_port(&tilegx_uart_driver, port);
  550. }
  551. return 0;
  552. }
  553. static void __exit tilegx_exit(void)
  554. {
  555. int i;
  556. struct uart_port *port;
  557. for (i = 0; i < TILEGX_UART_NR; i++) {
  558. port = &tile_uart_ports[i].uart;
  559. uart_remove_one_port(&tilegx_uart_driver, port);
  560. }
  561. uart_unregister_driver(&tilegx_uart_driver);
  562. }
  563. module_init(tilegx_init);
  564. module_exit(tilegx_exit);
  565. MODULE_AUTHOR("Tilera Corporation");
  566. MODULE_DESCRIPTION("TILEGx serial port driver");
  567. MODULE_LICENSE("GPL");