uart00.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. /*
  2. * linux/drivers/serial/uart00.c
  3. *
  4. * Driver for UART00 serial ports
  5. *
  6. * Based on drivers/char/serial_amba.c, by ARM Limited &
  7. * Deep Blue Solutions Ltd.
  8. * Copyright 2001 Altera Corporation
  9. *
  10. * Update for 2.6.4 by Dirk Behme <dirk.behme@de.bosch.com>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  25. *
  26. * $Id: uart00.c,v 1.35 2002/07/28 10:03:28 rmk Exp $
  27. *
  28. */
  29. #include <linux/config.h>
  30. #if defined(CONFIG_SERIAL_UART00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
  31. #define SUPPORT_SYSRQ
  32. #endif
  33. #include <linux/module.h>
  34. #include <linux/ioport.h>
  35. #include <linux/init.h>
  36. #include <linux/console.h>
  37. #include <linux/sysrq.h>
  38. #include <linux/tty.h>
  39. #include <linux/tty_flip.h>
  40. #include <linux/serial_core.h>
  41. #include <linux/serial.h>
  42. #include <asm/io.h>
  43. #include <asm/irq.h>
  44. #include <asm/sizes.h>
  45. #include <asm/arch/excalibur.h>
  46. #define UART00_TYPE (volatile unsigned int*)
  47. #include <asm/arch/uart00.h>
  48. #include <asm/arch/int_ctrl00.h>
  49. #define UART_NR 2
  50. #define SERIAL_UART00_NAME "ttyUA"
  51. #define SERIAL_UART00_MAJOR 204
  52. #define SERIAL_UART00_MINOR 16 /* Temporary - will change in future */
  53. #define SERIAL_UART00_NR UART_NR
  54. #define UART_PORT_SIZE 0x50
  55. #define UART00_ISR_PASS_LIMIT 256
  56. /*
  57. * Access macros for the UART00 UARTs
  58. */
  59. #define UART_GET_INT_STATUS(p) inl(UART_ISR((p)->membase))
  60. #define UART_PUT_IES(p, c) outl(c,UART_IES((p)->membase))
  61. #define UART_GET_IES(p) inl(UART_IES((p)->membase))
  62. #define UART_PUT_IEC(p, c) outl(c,UART_IEC((p)->membase))
  63. #define UART_GET_IEC(p) inl(UART_IEC((p)->membase))
  64. #define UART_PUT_CHAR(p, c) outl(c,UART_TD((p)->membase))
  65. #define UART_GET_CHAR(p) inl(UART_RD((p)->membase))
  66. #define UART_GET_RSR(p) inl(UART_RSR((p)->membase))
  67. #define UART_GET_RDS(p) inl(UART_RDS((p)->membase))
  68. #define UART_GET_MSR(p) inl(UART_MSR((p)->membase))
  69. #define UART_GET_MCR(p) inl(UART_MCR((p)->membase))
  70. #define UART_PUT_MCR(p, c) outl(c,UART_MCR((p)->membase))
  71. #define UART_GET_MC(p) inl(UART_MC((p)->membase))
  72. #define UART_PUT_MC(p, c) outl(c,UART_MC((p)->membase))
  73. #define UART_GET_TSR(p) inl(UART_TSR((p)->membase))
  74. #define UART_GET_DIV_HI(p) inl(UART_DIV_HI((p)->membase))
  75. #define UART_PUT_DIV_HI(p,c) outl(c,UART_DIV_HI((p)->membase))
  76. #define UART_GET_DIV_LO(p) inl(UART_DIV_LO((p)->membase))
  77. #define UART_PUT_DIV_LO(p,c) outl(c,UART_DIV_LO((p)->membase))
  78. #define UART_RX_DATA(s) ((s) & UART_RSR_RX_LEVEL_MSK)
  79. #define UART_TX_READY(s) (((s) & UART_TSR_TX_LEVEL_MSK) < 15)
  80. //#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0)
  81. static void uart00_stop_tx(struct uart_port *port)
  82. {
  83. UART_PUT_IEC(port, UART_IEC_TIE_MSK);
  84. }
  85. static void uart00_stop_rx(struct uart_port *port)
  86. {
  87. UART_PUT_IEC(port, UART_IEC_RE_MSK);
  88. }
  89. static void uart00_enable_ms(struct uart_port *port)
  90. {
  91. UART_PUT_IES(port, UART_IES_ME_MSK);
  92. }
  93. static void
  94. uart00_rx_chars(struct uart_port *port, struct pt_regs *regs)
  95. {
  96. struct tty_struct *tty = port->info->tty;
  97. unsigned int status, ch, rds, flg, ignored = 0;
  98. status = UART_GET_RSR(port);
  99. while (UART_RX_DATA(status)) {
  100. /*
  101. * We need to read rds before reading the
  102. * character from the fifo
  103. */
  104. rds = UART_GET_RDS(port);
  105. ch = UART_GET_CHAR(port);
  106. port->icount.rx++;
  107. if (tty->flip.count >= TTY_FLIPBUF_SIZE)
  108. goto ignore_char;
  109. flg = TTY_NORMAL;
  110. /*
  111. * Note that the error handling code is
  112. * out of the main execution path
  113. */
  114. if (rds & (UART_RDS_BI_MSK |UART_RDS_FE_MSK|
  115. UART_RDS_PE_MSK |UART_RDS_PE_MSK))
  116. goto handle_error;
  117. if (uart_handle_sysrq_char(port, ch, regs))
  118. goto ignore_char;
  119. error_return:
  120. tty_insert_flip_char(tty, ch, flg);
  121. ignore_char:
  122. status = UART_GET_RSR(port);
  123. }
  124. out:
  125. tty_flip_buffer_push(tty);
  126. return;
  127. handle_error:
  128. if (rds & UART_RDS_BI_MSK) {
  129. status &= ~(UART_RDS_FE_MSK | UART_RDS_PE_MSK);
  130. port->icount.brk++;
  131. if (uart_handle_break(port))
  132. goto ignore_char;
  133. } else if (rds & UART_RDS_PE_MSK)
  134. port->icount.parity++;
  135. else if (rds & UART_RDS_FE_MSK)
  136. port->icount.frame++;
  137. if (rds & UART_RDS_OE_MSK)
  138. port->icount.overrun++;
  139. if (rds & port->ignore_status_mask) {
  140. if (++ignored > 100)
  141. goto out;
  142. goto ignore_char;
  143. }
  144. rds &= port->read_status_mask;
  145. if (rds & UART_RDS_BI_MSK)
  146. flg = TTY_BREAK;
  147. else if (rds & UART_RDS_PE_MSK)
  148. flg = TTY_PARITY;
  149. else if (rds & UART_RDS_FE_MSK)
  150. flg = TTY_FRAME;
  151. if (rds & UART_RDS_OE_MSK) {
  152. /*
  153. * CHECK: does overrun affect the current character?
  154. * ASSUMPTION: it does not.
  155. */
  156. tty_insert_flip_char(tty, ch, flg);
  157. ch = 0;
  158. flg = TTY_OVERRUN;
  159. }
  160. #ifdef SUPPORT_SYSRQ
  161. port->sysrq = 0;
  162. #endif
  163. goto error_return;
  164. }
  165. static void uart00_tx_chars(struct uart_port *port)
  166. {
  167. struct circ_buf *xmit = &port->info->xmit;
  168. int count;
  169. if (port->x_char) {
  170. while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15)
  171. barrier();
  172. UART_PUT_CHAR(port, port->x_char);
  173. port->icount.tx++;
  174. port->x_char = 0;
  175. return;
  176. }
  177. if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
  178. uart00_stop_tx(port);
  179. return;
  180. }
  181. count = port->fifosize >> 1;
  182. do {
  183. while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15)
  184. barrier();
  185. UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
  186. xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
  187. port->icount.tx++;
  188. if (uart_circ_empty(xmit))
  189. break;
  190. } while (--count > 0);
  191. if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
  192. uart_write_wakeup(port);
  193. if (uart_circ_empty(xmit))
  194. uart00_stop_tx(port);
  195. }
  196. static void uart00_start_tx(struct uart_port *port)
  197. {
  198. UART_PUT_IES(port, UART_IES_TIE_MSK);
  199. uart00_tx_chars(port);
  200. }
  201. static void uart00_modem_status(struct uart_port *port)
  202. {
  203. unsigned int status;
  204. status = UART_GET_MSR(port);
  205. if (!(status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK |
  206. UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK)))
  207. return;
  208. if (status & UART_MSR_DDCD_MSK)
  209. uart_handle_dcd_change(port, status & UART_MSR_DCD_MSK);
  210. if (status & UART_MSR_DDSR_MSK)
  211. port->icount.dsr++;
  212. if (status & UART_MSR_DCTS_MSK)
  213. uart_handle_cts_change(port, status & UART_MSR_CTS_MSK);
  214. wake_up_interruptible(&port->info->delta_msr_wait);
  215. }
  216. static irqreturn_t uart00_int(int irq, void *dev_id, struct pt_regs *regs)
  217. {
  218. struct uart_port *port = dev_id;
  219. unsigned int status, pass_counter = 0;
  220. status = UART_GET_INT_STATUS(port);
  221. do {
  222. if (status & UART_ISR_RI_MSK)
  223. uart00_rx_chars(port, regs);
  224. if (status & UART_ISR_MI_MSK)
  225. uart00_modem_status(port);
  226. if (status & (UART_ISR_TI_MSK | UART_ISR_TII_MSK))
  227. uart00_tx_chars(port);
  228. if (pass_counter++ > UART00_ISR_PASS_LIMIT)
  229. break;
  230. status = UART_GET_INT_STATUS(port);
  231. } while (status);
  232. return IRQ_HANDLED;
  233. }
  234. static unsigned int uart00_tx_empty(struct uart_port *port)
  235. {
  236. return UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK? 0 : TIOCSER_TEMT;
  237. }
  238. static unsigned int uart00_get_mctrl(struct uart_port *port)
  239. {
  240. unsigned int result = 0;
  241. unsigned int status;
  242. status = UART_GET_MSR(port);
  243. if (status & UART_MSR_DCD_MSK)
  244. result |= TIOCM_CAR;
  245. if (status & UART_MSR_DSR_MSK)
  246. result |= TIOCM_DSR;
  247. if (status & UART_MSR_CTS_MSK)
  248. result |= TIOCM_CTS;
  249. if (status & UART_MSR_RI_MSK)
  250. result |= TIOCM_RI;
  251. return result;
  252. }
  253. static void uart00_set_mctrl_null(struct uart_port *port, unsigned int mctrl)
  254. {
  255. }
  256. static void uart00_break_ctl(struct uart_port *port, int break_state)
  257. {
  258. unsigned long flags;
  259. unsigned int mcr;
  260. spin_lock_irqsave(&port->lock, flags);
  261. mcr = UART_GET_MCR(port);
  262. if (break_state == -1)
  263. mcr |= UART_MCR_BR_MSK;
  264. else
  265. mcr &= ~UART_MCR_BR_MSK;
  266. UART_PUT_MCR(port, mcr);
  267. spin_unlock_irqrestore(&port->lock, flags);
  268. }
  269. static void
  270. uart00_set_termios(struct uart_port *port, struct termios *termios,
  271. struct termios *old)
  272. {
  273. unsigned int uart_mc, old_ies, baud, quot;
  274. unsigned long flags;
  275. /*
  276. * We don't support CREAD (yet)
  277. */
  278. termios->c_cflag |= CREAD;
  279. /*
  280. * Ask the core to calculate the divisor for us.
  281. */
  282. baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
  283. quot = uart_get_divisor(port, baud);
  284. /* byte size and parity */
  285. switch (termios->c_cflag & CSIZE) {
  286. case CS5:
  287. uart_mc = UART_MC_CLS_CHARLEN_5;
  288. break;
  289. case CS6:
  290. uart_mc = UART_MC_CLS_CHARLEN_6;
  291. break;
  292. case CS7:
  293. uart_mc = UART_MC_CLS_CHARLEN_7;
  294. break;
  295. default: // CS8
  296. uart_mc = UART_MC_CLS_CHARLEN_8;
  297. break;
  298. }
  299. if (termios->c_cflag & CSTOPB)
  300. uart_mc|= UART_MC_ST_TWO;
  301. if (termios->c_cflag & PARENB) {
  302. uart_mc |= UART_MC_PE_MSK;
  303. if (!(termios->c_cflag & PARODD))
  304. uart_mc |= UART_MC_EP_MSK;
  305. }
  306. spin_lock_irqsave(&port->lock, flags);
  307. /*
  308. * Update the per-port timeout.
  309. */
  310. uart_update_timeout(port, termios->c_cflag, baud);
  311. port->read_status_mask = UART_RDS_OE_MSK;
  312. if (termios->c_iflag & INPCK)
  313. port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
  314. if (termios->c_iflag & (BRKINT | PARMRK))
  315. port->read_status_mask |= UART_RDS_BI_MSK;
  316. /*
  317. * Characters to ignore
  318. */
  319. port->ignore_status_mask = 0;
  320. if (termios->c_iflag & IGNPAR)
  321. port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
  322. if (termios->c_iflag & IGNBRK) {
  323. port->ignore_status_mask |= UART_RDS_BI_MSK;
  324. /*
  325. * If we're ignoring parity and break indicators,
  326. * ignore overruns to (for real raw support).
  327. */
  328. if (termios->c_iflag & IGNPAR)
  329. port->ignore_status_mask |= UART_RDS_OE_MSK;
  330. }
  331. /* first, disable everything */
  332. old_ies = UART_GET_IES(port);
  333. if (UART_ENABLE_MS(port, termios->c_cflag))
  334. old_ies |= UART_IES_ME_MSK;
  335. /* Set baud rate */
  336. UART_PUT_DIV_LO(port, (quot & 0xff));
  337. UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
  338. UART_PUT_MC(port, uart_mc);
  339. UART_PUT_IES(port, old_ies);
  340. spin_unlock_irqrestore(&port->lock, flags);
  341. }
  342. static int uart00_startup(struct uart_port *port)
  343. {
  344. int result;
  345. /*
  346. * Allocate the IRQ
  347. */
  348. result = request_irq(port->irq, uart00_int, 0, "uart00", port);
  349. if (result) {
  350. printk(KERN_ERR "Request of irq %d failed\n", port->irq);
  351. return result;
  352. }
  353. /*
  354. * Finally, enable interrupts. Use the TII interrupt to minimise
  355. * the number of interrupts generated. If higher performance is
  356. * needed, consider using the TI interrupt with a suitable FIFO
  357. * threshold
  358. */
  359. UART_PUT_IES(port, UART_IES_RE_MSK | UART_IES_TIE_MSK);
  360. return 0;
  361. }
  362. static void uart00_shutdown(struct uart_port *port)
  363. {
  364. /*
  365. * disable all interrupts, disable the port
  366. */
  367. UART_PUT_IEC(port, 0xff);
  368. /* disable break condition and fifos */
  369. UART_PUT_MCR(port, UART_GET_MCR(port) &~UART_MCR_BR_MSK);
  370. /*
  371. * Free the interrupt
  372. */
  373. free_irq(port->irq, port);
  374. }
  375. static const char *uart00_type(struct uart_port *port)
  376. {
  377. return port->type == PORT_UART00 ? "Altera UART00" : NULL;
  378. }
  379. /*
  380. * Release the memory region(s) being used by 'port'
  381. */
  382. static void uart00_release_port(struct uart_port *port)
  383. {
  384. release_mem_region(port->mapbase, UART_PORT_SIZE);
  385. #ifdef CONFIG_ARCH_CAMELOT
  386. if (port->membase != (void*)IO_ADDRESS(EXC_UART00_BASE)) {
  387. iounmap(port->membase);
  388. }
  389. #endif
  390. }
  391. /*
  392. * Request the memory region(s) being used by 'port'
  393. */
  394. static int uart00_request_port(struct uart_port *port)
  395. {
  396. return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_uart00")
  397. != NULL ? 0 : -EBUSY;
  398. }
  399. /*
  400. * Configure/autoconfigure the port.
  401. */
  402. static void uart00_config_port(struct uart_port *port, int flags)
  403. {
  404. /*
  405. * Map the io memory if this is a soft uart
  406. */
  407. if (!port->membase)
  408. port->membase = ioremap_nocache(port->mapbase,SZ_4K);
  409. if (!port->membase)
  410. printk(KERN_ERR "serial00: cannot map io memory\n");
  411. else
  412. port->type = PORT_UART00;
  413. }
  414. /*
  415. * verify the new serial_struct (for TIOCSSERIAL).
  416. */
  417. static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser)
  418. {
  419. int ret = 0;
  420. if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
  421. ret = -EINVAL;
  422. if (ser->irq < 0 || ser->irq >= NR_IRQS)
  423. ret = -EINVAL;
  424. if (ser->baud_base < 9600)
  425. ret = -EINVAL;
  426. return ret;
  427. }
  428. static struct uart_ops uart00_pops = {
  429. .tx_empty = uart00_tx_empty,
  430. .set_mctrl = uart00_set_mctrl_null,
  431. .get_mctrl = uart00_get_mctrl,
  432. .stop_tx = uart00_stop_tx,
  433. .start_tx = uart00_start_tx,
  434. .stop_rx = uart00_stop_rx,
  435. .enable_ms = uart00_enable_ms,
  436. .break_ctl = uart00_break_ctl,
  437. .startup = uart00_startup,
  438. .shutdown = uart00_shutdown,
  439. .set_termios = uart00_set_termios,
  440. .type = uart00_type,
  441. .release_port = uart00_release_port,
  442. .request_port = uart00_request_port,
  443. .config_port = uart00_config_port,
  444. .verify_port = uart00_verify_port,
  445. };
  446. #ifdef CONFIG_ARCH_CAMELOT
  447. static struct uart_port epxa10db_port = {
  448. .membase = (void*)IO_ADDRESS(EXC_UART00_BASE),
  449. .mapbase = EXC_UART00_BASE,
  450. .iotype = SERIAL_IO_MEM,
  451. .irq = IRQ_UART,
  452. .uartclk = EXC_AHB2_CLK_FREQUENCY,
  453. .fifosize = 16,
  454. .ops = &uart00_pops,
  455. .flags = ASYNC_BOOT_AUTOCONF,
  456. };
  457. #endif
  458. #ifdef CONFIG_SERIAL_UART00_CONSOLE
  459. static void uart00_console_write(struct console *co, const char *s, unsigned count)
  460. {
  461. #ifdef CONFIG_ARCH_CAMELOT
  462. struct uart_port *port = &epxa10db_port;
  463. unsigned int status, old_ies;
  464. int i;
  465. /*
  466. * First save the CR then disable the interrupts
  467. */
  468. old_ies = UART_GET_IES(port);
  469. UART_PUT_IEC(port,0xff);
  470. /*
  471. * Now, do each character
  472. */
  473. for (i = 0; i < count; i++) {
  474. do {
  475. status = UART_GET_TSR(port);
  476. } while (!UART_TX_READY(status));
  477. UART_PUT_CHAR(port, s[i]);
  478. if (s[i] == '\n') {
  479. do {
  480. status = UART_GET_TSR(port);
  481. } while (!UART_TX_READY(status));
  482. UART_PUT_CHAR(port, '\r');
  483. }
  484. }
  485. /*
  486. * Finally, wait for transmitter to become empty
  487. * and restore the IES
  488. */
  489. do {
  490. status = UART_GET_TSR(port);
  491. } while (status & UART_TSR_TX_LEVEL_MSK);
  492. UART_PUT_IES(port, old_ies);
  493. #endif
  494. }
  495. static void __init
  496. uart00_console_get_options(struct uart_port *port, int *baud,
  497. int *parity, int *bits)
  498. {
  499. unsigned int uart_mc, quot;
  500. uart_mc = UART_GET_MC(port);
  501. *parity = 'n';
  502. if (uart_mc & UART_MC_PE_MSK) {
  503. if (uart_mc & UART_MC_EP_MSK)
  504. *parity = 'e';
  505. else
  506. *parity = 'o';
  507. }
  508. switch (uart_mc & UART_MC_CLS_MSK) {
  509. case UART_MC_CLS_CHARLEN_5:
  510. *bits = 5;
  511. break;
  512. case UART_MC_CLS_CHARLEN_6:
  513. *bits = 6;
  514. break;
  515. case UART_MC_CLS_CHARLEN_7:
  516. *bits = 7;
  517. break;
  518. case UART_MC_CLS_CHARLEN_8:
  519. *bits = 8;
  520. break;
  521. }
  522. quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);
  523. *baud = port->uartclk / (16 *quot );
  524. }
  525. static int __init uart00_console_setup(struct console *co, char *options)
  526. {
  527. struct uart_port *port;
  528. int baud = 115200;
  529. int bits = 8;
  530. int parity = 'n';
  531. int flow = 'n';
  532. #ifdef CONFIG_ARCH_CAMELOT
  533. port = &epxa10db_port; ;
  534. #else
  535. return -ENODEV;
  536. #endif
  537. if (options)
  538. uart_parse_options(options, &baud, &parity, &bits, &flow);
  539. else
  540. uart00_console_get_options(port, &baud, &parity, &bits);
  541. return uart_set_options(port, co, baud, parity, bits, flow);
  542. }
  543. extern struct uart_driver uart00_reg;
  544. static struct console uart00_console = {
  545. .name = SERIAL_UART00_NAME,
  546. .write = uart00_console_write,
  547. .device = uart_console_device,
  548. .setup = uart00_console_setup,
  549. .flags = CON_PRINTBUFFER,
  550. .index = 0,
  551. .data = &uart00_reg,
  552. };
  553. static int __init uart00_console_init(void)
  554. {
  555. register_console(&uart00_console);
  556. return 0;
  557. }
  558. console_initcall(uart00_console_init);
  559. #define UART00_CONSOLE &uart00_console
  560. #else
  561. #define UART00_CONSOLE NULL
  562. #endif
  563. static struct uart_driver uart00_reg = {
  564. .owner = NULL,
  565. .driver_name = SERIAL_UART00_NAME,
  566. .dev_name = SERIAL_UART00_NAME,
  567. .major = SERIAL_UART00_MAJOR,
  568. .minor = SERIAL_UART00_MINOR,
  569. .nr = UART_NR,
  570. .cons = UART00_CONSOLE,
  571. };
  572. struct dev_port_entry{
  573. unsigned int base_addr;
  574. struct uart_port *port;
  575. };
  576. #ifdef CONFIG_PLD_HOTSWAP
  577. static struct dev_port_entry dev_port_map[UART_NR];
  578. /*
  579. * Keep a mapping of dev_info addresses -> port lines to use when
  580. * removing ports dev==NULL indicates unused entry
  581. */
  582. struct uart00_ps_data{
  583. unsigned int clk;
  584. unsigned int fifosize;
  585. };
  586. int uart00_add_device(struct pldhs_dev_info* dev_info, void* dev_ps_data)
  587. {
  588. struct uart00_ps_data* dev_ps=dev_ps_data;
  589. struct uart_port * port;
  590. int i,result;
  591. i=0;
  592. while(dev_port_map[i].port)
  593. i++;
  594. if(i==UART_NR){
  595. printk(KERN_WARNING "uart00: Maximum number of ports reached\n");
  596. return 0;
  597. }
  598. port=kmalloc(sizeof(struct uart_port),GFP_KERNEL);
  599. if(!port)
  600. return -ENOMEM;
  601. printk("clk=%d fifo=%d\n",dev_ps->clk,dev_ps->fifosize);
  602. port->membase=0;
  603. port->mapbase=dev_info->base_addr;
  604. port->iotype=SERIAL_IO_MEM;
  605. port->irq=dev_info->irq;
  606. port->uartclk=dev_ps->clk;
  607. port->fifosize=dev_ps->fifosize;
  608. port->ops=&uart00_pops;
  609. port->line=i;
  610. port->flags=ASYNC_BOOT_AUTOCONF;
  611. result=uart_add_one_port(&uart00_reg, port);
  612. if(result){
  613. printk("uart_add_one_port returned %d\n",result);
  614. return result;
  615. }
  616. dev_port_map[i].base_addr=dev_info->base_addr;
  617. dev_port_map[i].port=port;
  618. printk("uart00: added device at %x as ttyUA%d\n",dev_port_map[i].base_addr,i);
  619. return 0;
  620. }
  621. int uart00_remove_devices(void)
  622. {
  623. int i,result;
  624. result=0;
  625. for(i=1;i<UART_NR;i++){
  626. if(dev_port_map[i].base_addr){
  627. result=uart_remove_one_port(&uart00_reg, dev_port_map[i].port);
  628. if(result)
  629. return result;
  630. /* port removed sucessfully, so now tidy up */
  631. kfree(dev_port_map[i].port);
  632. dev_port_map[i].base_addr=0;
  633. dev_port_map[i].port=NULL;
  634. }
  635. }
  636. return 0;
  637. }
  638. struct pld_hotswap_ops uart00_pldhs_ops={
  639. .name = "uart00",
  640. .add_device = uart00_add_device,
  641. .remove_devices = uart00_remove_devices,
  642. };
  643. #endif
  644. static int __init uart00_init(void)
  645. {
  646. int result;
  647. printk(KERN_INFO "Serial: UART00 driver $Revision: 1.35 $\n");
  648. printk(KERN_WARNING "serial_uart00:Using temporary major/minor pairs"
  649. " - these WILL change in the future\n");
  650. result = uart_register_driver(&uart00_reg);
  651. if (result)
  652. return result;
  653. #ifdef CONFIG_ARCH_CAMELOT
  654. result = uart_add_one_port(&uart00_reg,&epxa10db_port);
  655. #endif
  656. if (result)
  657. uart_unregister_driver(&uart00_reg);
  658. #ifdef CONFIG_PLD_HOTSWAP
  659. pldhs_register_driver(&uart00_pldhs_ops);
  660. #endif
  661. return result;
  662. }
  663. __initcall(uart00_init);