tilegx.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  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. * Enable modem status interrupts.
  260. */
  261. static void tilegx_enable_ms(struct uart_port *port)
  262. {
  263. /* N/A */
  264. }
  265. /*
  266. * Control the transmission of a break signal.
  267. */
  268. static void tilegx_break_ctl(struct uart_port *port, int break_state)
  269. {
  270. /* N/A */
  271. }
  272. /*
  273. * Perform initialization and enable port for reception.
  274. */
  275. static int tilegx_startup(struct uart_port *port)
  276. {
  277. struct tile_uart_port *tile_uart;
  278. gxio_uart_context_t *context;
  279. int ret = 0;
  280. int cpu = raw_smp_processor_id(); /* pick an arbitrary cpu */
  281. tile_uart = container_of(port, struct tile_uart_port, uart);
  282. if (mutex_lock_interruptible(&tile_uart->mutex))
  283. return -EBUSY;
  284. context = &tile_uart->context;
  285. /* Now open the hypervisor device if we haven't already. */
  286. if (context->fd < 0) {
  287. UART_INTERRUPT_MASK_t intr_mask;
  288. /* Initialize UART device. */
  289. ret = gxio_uart_init(context, port->line);
  290. if (ret) {
  291. ret = -ENXIO;
  292. goto err;
  293. }
  294. /* Create our IRQs. */
  295. port->irq = create_irq();
  296. if (port->irq < 0)
  297. goto err_uart_dest;
  298. tile_irq_activate(port->irq, TILE_IRQ_PERCPU);
  299. /* Register our IRQs. */
  300. ret = request_irq(port->irq, tilegx_interrupt, 0,
  301. tilegx_uart_driver.driver_name, port);
  302. if (ret)
  303. goto err_dest_irq;
  304. /* Request that the hardware start sending us interrupts. */
  305. tile_uart->irq_cpu = cpu;
  306. ret = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
  307. KERNEL_PL, port->irq);
  308. if (ret)
  309. goto err_free_irq;
  310. /* Enable UART Tx/Rx Interrupt. */
  311. intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
  312. intr_mask.wfifo_re = 0;
  313. intr_mask.rfifo_we = 0;
  314. gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);
  315. /* Reset the Tx/Rx interrupt in case it's set. */
  316. gxio_uart_write(context, UART_INTERRUPT_STATUS,
  317. UART_INTERRUPT_MASK__WFIFO_RE_MASK |
  318. UART_INTERRUPT_MASK__RFIFO_WE_MASK);
  319. }
  320. mutex_unlock(&tile_uart->mutex);
  321. return ret;
  322. err_free_irq:
  323. free_irq(port->irq, port);
  324. err_dest_irq:
  325. destroy_irq(port->irq);
  326. err_uart_dest:
  327. gxio_uart_destroy(context);
  328. ret = -ENXIO;
  329. err:
  330. mutex_unlock(&tile_uart->mutex);
  331. return ret;
  332. }
  333. /*
  334. * Release kernel resources if it is the last close, disable the port,
  335. * free IRQ and close the port.
  336. */
  337. static void tilegx_shutdown(struct uart_port *port)
  338. {
  339. int err;
  340. UART_INTERRUPT_MASK_t intr_mask;
  341. struct tile_uart_port *tile_uart;
  342. gxio_uart_context_t *context;
  343. int cpu;
  344. tile_uart = container_of(port, struct tile_uart_port, uart);
  345. if (mutex_lock_interruptible(&tile_uart->mutex))
  346. return;
  347. context = &tile_uart->context;
  348. /* Disable UART Tx/Rx Interrupt. */
  349. intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
  350. intr_mask.wfifo_re = 1;
  351. intr_mask.rfifo_we = 1;
  352. gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);
  353. /* Request that the hardware stop sending us interrupts. */
  354. cpu = tile_uart->irq_cpu;
  355. err = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
  356. KERNEL_PL, -1);
  357. if (port->irq > 0) {
  358. free_irq(port->irq, port);
  359. destroy_irq(port->irq);
  360. port->irq = 0;
  361. }
  362. gxio_uart_destroy(context);
  363. mutex_unlock(&tile_uart->mutex);
  364. }
  365. /*
  366. * Flush the buffer.
  367. */
  368. static void tilegx_flush_buffer(struct uart_port *port)
  369. {
  370. /* N/A */
  371. }
  372. /*
  373. * Change the port parameters.
  374. */
  375. static void tilegx_set_termios(struct uart_port *port,
  376. struct ktermios *termios, struct ktermios *old)
  377. {
  378. int err;
  379. UART_DIVISOR_t divisor;
  380. UART_TYPE_t type;
  381. unsigned int baud;
  382. struct tile_uart_port *tile_uart;
  383. gxio_uart_context_t *context;
  384. tile_uart = container_of(port, struct tile_uart_port, uart);
  385. if (!mutex_trylock(&tile_uart->mutex))
  386. return;
  387. context = &tile_uart->context;
  388. /* Open the hypervisor device if we haven't already. */
  389. if (context->fd < 0) {
  390. err = gxio_uart_init(context, port->line);
  391. if (err) {
  392. mutex_unlock(&tile_uart->mutex);
  393. return;
  394. }
  395. }
  396. divisor.word = gxio_uart_read(context, UART_DIVISOR);
  397. type.word = gxio_uart_read(context, UART_TYPE);
  398. /* Divisor. */
  399. baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
  400. divisor.divisor = uart_get_divisor(port, baud);
  401. /* Byte size. */
  402. if ((termios->c_cflag & CSIZE) == CS7)
  403. type.dbits = UART_TYPE__DBITS_VAL_SEVEN_DBITS;
  404. else
  405. type.dbits = UART_TYPE__DBITS_VAL_EIGHT_DBITS;
  406. /* Parity. */
  407. if (termios->c_cflag & PARENB) {
  408. /* Mark or Space parity. */
  409. if (termios->c_cflag & CMSPAR)
  410. if (termios->c_cflag & PARODD)
  411. type.ptype = UART_TYPE__PTYPE_VAL_MARK;
  412. else
  413. type.ptype = UART_TYPE__PTYPE_VAL_SPACE;
  414. else if (termios->c_cflag & PARODD)
  415. type.ptype = UART_TYPE__PTYPE_VAL_ODD;
  416. else
  417. type.ptype = UART_TYPE__PTYPE_VAL_EVEN;
  418. } else
  419. type.ptype = UART_TYPE__PTYPE_VAL_NONE;
  420. /* Stop bits. */
  421. if (termios->c_cflag & CSTOPB)
  422. type.sbits = UART_TYPE__SBITS_VAL_TWO_SBITS;
  423. else
  424. type.sbits = UART_TYPE__SBITS_VAL_ONE_SBITS;
  425. /* Set the uart paramters. */
  426. gxio_uart_write(context, UART_DIVISOR, divisor.word);
  427. gxio_uart_write(context, UART_TYPE, type.word);
  428. mutex_unlock(&tile_uart->mutex);
  429. }
  430. /*
  431. * Return string describing the specified port.
  432. */
  433. static const char *tilegx_type(struct uart_port *port)
  434. {
  435. return port->type == PORT_TILEGX ? DRIVER_NAME_STRING : NULL;
  436. }
  437. /*
  438. * Release the resources being used by 'port'.
  439. */
  440. static void tilegx_release_port(struct uart_port *port)
  441. {
  442. /* Nothing to release. */
  443. }
  444. /*
  445. * Request the resources being used by 'port'.
  446. */
  447. static int tilegx_request_port(struct uart_port *port)
  448. {
  449. /* Always present. */
  450. return 0;
  451. }
  452. /*
  453. * Configure/autoconfigure the port.
  454. */
  455. static void tilegx_config_port(struct uart_port *port, int flags)
  456. {
  457. if (flags & UART_CONFIG_TYPE)
  458. port->type = PORT_TILEGX;
  459. }
  460. /*
  461. * Verify the new serial_struct (for TIOCSSERIAL).
  462. */
  463. static int tilegx_verify_port(struct uart_port *port,
  464. struct serial_struct *ser)
  465. {
  466. if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_TILEGX))
  467. return -EINVAL;
  468. return 0;
  469. }
  470. #ifdef CONFIG_CONSOLE_POLL
  471. /*
  472. * Console polling routines for writing and reading from the uart while
  473. * in an interrupt or debug context.
  474. */
  475. static int tilegx_poll_get_char(struct uart_port *port)
  476. {
  477. UART_FIFO_COUNT_t count;
  478. gxio_uart_context_t *context;
  479. struct tile_uart_port *tile_uart;
  480. tile_uart = container_of(port, struct tile_uart_port, uart);
  481. context = &tile_uart->context;
  482. count.word = gxio_uart_read(context, UART_FIFO_COUNT);
  483. if (count.rfifo_count == 0)
  484. return NO_POLL_CHAR;
  485. return (char)gxio_uart_read(context, UART_RECEIVE_DATA);
  486. }
  487. static void tilegx_poll_put_char(struct uart_port *port, unsigned char c)
  488. {
  489. gxio_uart_context_t *context;
  490. struct tile_uart_port *tile_uart;
  491. tile_uart = container_of(port, struct tile_uart_port, uart);
  492. context = &tile_uart->context;
  493. gxio_uart_write(context, UART_TRANSMIT_DATA, (unsigned long)c);
  494. }
  495. #endif /* CONFIG_CONSOLE_POLL */
  496. static const struct uart_ops tilegx_ops = {
  497. .tx_empty = tilegx_tx_empty,
  498. .set_mctrl = tilegx_set_mctrl,
  499. .get_mctrl = tilegx_get_mctrl,
  500. .stop_tx = tilegx_stop_tx,
  501. .start_tx = tilegx_start_tx,
  502. .stop_rx = tilegx_stop_rx,
  503. .enable_ms = tilegx_enable_ms,
  504. .break_ctl = tilegx_break_ctl,
  505. .startup = tilegx_startup,
  506. .shutdown = tilegx_shutdown,
  507. .flush_buffer = tilegx_flush_buffer,
  508. .set_termios = tilegx_set_termios,
  509. .type = tilegx_type,
  510. .release_port = tilegx_release_port,
  511. .request_port = tilegx_request_port,
  512. .config_port = tilegx_config_port,
  513. .verify_port = tilegx_verify_port,
  514. #ifdef CONFIG_CONSOLE_POLL
  515. .poll_get_char = tilegx_poll_get_char,
  516. .poll_put_char = tilegx_poll_put_char,
  517. #endif
  518. };
  519. static void tilegx_init_ports(void)
  520. {
  521. int i;
  522. struct uart_port *port;
  523. for (i = 0; i < TILEGX_UART_NR; i++) {
  524. port = &tile_uart_ports[i].uart;
  525. port->ops = &tilegx_ops;
  526. port->line = i;
  527. port->type = PORT_TILEGX;
  528. port->uartclk = TILEGX_UART_REF_CLK;
  529. port->flags = UPF_BOOT_AUTOCONF;
  530. tile_uart_ports[i].context.fd = -1;
  531. mutex_init(&tile_uart_ports[i].mutex);
  532. }
  533. }
  534. static struct uart_driver tilegx_uart_driver = {
  535. .owner = THIS_MODULE,
  536. .driver_name = DRIVER_NAME_STRING,
  537. .dev_name = TILEGX_UART_NAME,
  538. .major = TILEGX_UART_MAJOR,
  539. .minor = TILEGX_UART_MINOR,
  540. .nr = TILEGX_UART_NR,
  541. };
  542. static int __init tilegx_init(void)
  543. {
  544. int i;
  545. int ret;
  546. struct tty_driver *tty_drv;
  547. ret = uart_register_driver(&tilegx_uart_driver);
  548. if (ret)
  549. return ret;
  550. tty_drv = tilegx_uart_driver.tty_driver;
  551. tty_drv->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
  552. tty_drv->init_termios.c_ispeed = 115200;
  553. tty_drv->init_termios.c_ospeed = 115200;
  554. tilegx_init_ports();
  555. for (i = 0; i < TILEGX_UART_NR; i++) {
  556. struct uart_port *port = &tile_uart_ports[i].uart;
  557. ret = uart_add_one_port(&tilegx_uart_driver, port);
  558. }
  559. return 0;
  560. }
  561. static void __exit tilegx_exit(void)
  562. {
  563. int i;
  564. struct uart_port *port;
  565. for (i = 0; i < TILEGX_UART_NR; i++) {
  566. port = &tile_uart_ports[i].uart;
  567. uart_remove_one_port(&tilegx_uart_driver, port);
  568. }
  569. uart_unregister_driver(&tilegx_uart_driver);
  570. }
  571. module_init(tilegx_init);
  572. module_exit(tilegx_exit);
  573. MODULE_AUTHOR("Tilera Corporation");
  574. MODULE_DESCRIPTION("TILEGx serial port driver");
  575. MODULE_LICENSE("GPL");