dz.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. /*
  2. * dz.c: Serial port driver for DECstations equipped
  3. * with the DZ chipset.
  4. *
  5. * Copyright (C) 1998 Olivier A. D. Lebaillif
  6. *
  7. * Email: olivier.lebaillif@ifrsys.com
  8. *
  9. * Copyright (C) 2004, 2006, 2007 Maciej W. Rozycki
  10. *
  11. * [31-AUG-98] triemer
  12. * Changed IRQ to use Harald's dec internals interrupts.h
  13. * removed base_addr code - moving address assignment to setup.c
  14. * Changed name of dz_init to rs_init to be consistent with tc code
  15. * [13-NOV-98] triemer fixed code to receive characters
  16. * after patches by harald to irq code.
  17. * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
  18. * field from "current" - somewhere between 2.1.121 and 2.1.131
  19. Qua Jun 27 15:02:26 BRT 2001
  20. * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
  21. *
  22. * Parts (C) 1999 David Airlie, airlied@linux.ie
  23. * [07-SEP-99] Bugfixes
  24. *
  25. * [06-Jan-2002] Russell King <rmk@arm.linux.org.uk>
  26. * Converted to new serial core
  27. */
  28. #undef DEBUG_DZ
  29. #if defined(CONFIG_SERIAL_DZ_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
  30. #define SUPPORT_SYSRQ
  31. #endif
  32. #include <linux/bitops.h>
  33. #include <linux/compiler.h>
  34. #include <linux/console.h>
  35. #include <linux/delay.h>
  36. #include <linux/errno.h>
  37. #include <linux/init.h>
  38. #include <linux/interrupt.h>
  39. #include <linux/kernel.h>
  40. #include <linux/major.h>
  41. #include <linux/module.h>
  42. #include <linux/serial.h>
  43. #include <linux/serial_core.h>
  44. #include <linux/sysrq.h>
  45. #include <linux/tty.h>
  46. #include <asm/bootinfo.h>
  47. #include <asm/system.h>
  48. #include <asm/dec/interrupts.h>
  49. #include <asm/dec/kn01.h>
  50. #include <asm/dec/kn02.h>
  51. #include <asm/dec/machtype.h>
  52. #include <asm/dec/prom.h>
  53. #include "dz.h"
  54. static char *dz_name = "DECstation DZ serial driver version ";
  55. static char *dz_version = "1.03";
  56. struct dz_port {
  57. struct uart_port port;
  58. unsigned int cflag;
  59. };
  60. static struct dz_port dz_ports[DZ_NB_PORT];
  61. static inline struct dz_port *to_dport(struct uart_port *uport)
  62. {
  63. return container_of(uport, struct dz_port, port);
  64. }
  65. /*
  66. * ------------------------------------------------------------
  67. * dz_in () and dz_out ()
  68. *
  69. * These routines are used to access the registers of the DZ
  70. * chip, hiding relocation differences between implementation.
  71. * ------------------------------------------------------------
  72. */
  73. static inline unsigned short dz_in(struct dz_port *dport, unsigned offset)
  74. {
  75. volatile unsigned short *addr =
  76. (volatile unsigned short *) (dport->port.membase + offset);
  77. return *addr;
  78. }
  79. static inline void dz_out(struct dz_port *dport, unsigned offset,
  80. unsigned short value)
  81. {
  82. volatile unsigned short *addr =
  83. (volatile unsigned short *) (dport->port.membase + offset);
  84. *addr = value;
  85. }
  86. /*
  87. * ------------------------------------------------------------
  88. * rs_stop () and rs_start ()
  89. *
  90. * These routines are called before setting or resetting
  91. * tty->stopped. They enable or disable transmitter interrupts,
  92. * as necessary.
  93. * ------------------------------------------------------------
  94. */
  95. static void dz_stop_tx(struct uart_port *uport)
  96. {
  97. struct dz_port *dport = to_dport(uport);
  98. unsigned short tmp, mask = 1 << dport->port.line;
  99. tmp = dz_in(dport, DZ_TCR); /* read the TX flag */
  100. tmp &= ~mask; /* clear the TX flag */
  101. dz_out(dport, DZ_TCR, tmp);
  102. }
  103. static void dz_start_tx(struct uart_port *uport)
  104. {
  105. struct dz_port *dport = to_dport(uport);
  106. unsigned short tmp, mask = 1 << dport->port.line;
  107. tmp = dz_in(dport, DZ_TCR); /* read the TX flag */
  108. tmp |= mask; /* set the TX flag */
  109. dz_out(dport, DZ_TCR, tmp);
  110. }
  111. static void dz_stop_rx(struct uart_port *uport)
  112. {
  113. struct dz_port *dport = to_dport(uport);
  114. dport->cflag &= ~DZ_RXENAB;
  115. dz_out(dport, DZ_LPR, dport->cflag);
  116. }
  117. static void dz_enable_ms(struct uart_port *port)
  118. {
  119. /* nothing to do */
  120. }
  121. /*
  122. * ------------------------------------------------------------
  123. *
  124. * Here start the interrupt handling routines. All of the following
  125. * subroutines are declared as inline and are folded into
  126. * dz_interrupt. They were separated out for readability's sake.
  127. *
  128. * Note: dz_interrupt() is a "fast" interrupt, which means that it
  129. * runs with interrupts turned off. People who may want to modify
  130. * dz_interrupt() should try to keep the interrupt handler as fast as
  131. * possible. After you are done making modifications, it is not a bad
  132. * idea to do:
  133. *
  134. * make drivers/serial/dz.s
  135. *
  136. * and look at the resulting assemble code in dz.s.
  137. *
  138. * ------------------------------------------------------------
  139. */
  140. /*
  141. * ------------------------------------------------------------
  142. * receive_char ()
  143. *
  144. * This routine deals with inputs from any lines.
  145. * ------------------------------------------------------------
  146. */
  147. static inline void dz_receive_chars(struct dz_port *dport_in)
  148. {
  149. struct uart_port *uport;
  150. struct dz_port *dport;
  151. struct tty_struct *tty = NULL;
  152. struct uart_icount *icount;
  153. int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 };
  154. unsigned short status;
  155. unsigned char ch, flag;
  156. int i;
  157. while ((status = dz_in(dport_in, DZ_RBUF)) & DZ_DVAL) {
  158. dport = &dz_ports[LINE(status)];
  159. uport = &dport->port;
  160. tty = uport->info->tty; /* point to the proper dev */
  161. ch = UCHAR(status); /* grab the char */
  162. flag = TTY_NORMAL;
  163. icount = &uport->icount;
  164. icount->rx++;
  165. if (unlikely(status & (DZ_OERR | DZ_FERR | DZ_PERR))) {
  166. /*
  167. * There is no separate BREAK status bit, so treat
  168. * null characters with framing errors as BREAKs;
  169. * normally, otherwise. For this move the Framing
  170. * Error bit to a simulated BREAK bit.
  171. */
  172. if (!ch) {
  173. status |= (status & DZ_FERR) >>
  174. (ffs(DZ_FERR) - ffs(DZ_BREAK));
  175. status &= ~DZ_FERR;
  176. }
  177. /* Handle SysRq/SAK & keep track of the statistics. */
  178. if (status & DZ_BREAK) {
  179. icount->brk++;
  180. if (uart_handle_break(uport))
  181. continue;
  182. } else if (status & DZ_FERR)
  183. icount->frame++;
  184. else if (status & DZ_PERR)
  185. icount->parity++;
  186. if (status & DZ_OERR)
  187. icount->overrun++;
  188. status &= uport->read_status_mask;
  189. if (status & DZ_BREAK)
  190. flag = TTY_BREAK;
  191. else if (status & DZ_FERR)
  192. flag = TTY_FRAME;
  193. else if (status & DZ_PERR)
  194. flag = TTY_PARITY;
  195. }
  196. if (uart_handle_sysrq_char(uport, ch))
  197. continue;
  198. uart_insert_char(uport, status, DZ_OERR, ch, flag);
  199. lines_rx[LINE(status)] = 1;
  200. }
  201. for (i = 0; i < DZ_NB_PORT; i++)
  202. if (lines_rx[i])
  203. tty_flip_buffer_push(dz_ports[i].port.info->tty);
  204. }
  205. /*
  206. * ------------------------------------------------------------
  207. * transmit_char ()
  208. *
  209. * This routine deals with outputs to any lines.
  210. * ------------------------------------------------------------
  211. */
  212. static inline void dz_transmit_chars(struct dz_port *dport_in)
  213. {
  214. struct dz_port *dport;
  215. struct circ_buf *xmit;
  216. unsigned short status;
  217. unsigned char tmp;
  218. status = dz_in(dport_in, DZ_CSR);
  219. dport = &dz_ports[LINE(status)];
  220. xmit = &dport->port.info->xmit;
  221. if (dport->port.x_char) { /* XON/XOFF chars */
  222. dz_out(dport, DZ_TDR, dport->port.x_char);
  223. dport->port.icount.tx++;
  224. dport->port.x_char = 0;
  225. return;
  226. }
  227. /* If nothing to do or stopped or hardware stopped. */
  228. if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
  229. spin_lock(&dport->port.lock);
  230. dz_stop_tx(&dport->port);
  231. spin_unlock(&dport->port.lock);
  232. return;
  233. }
  234. /*
  235. * If something to do... (remember the dz has no output fifo,
  236. * so we go one char at a time) :-<
  237. */
  238. tmp = xmit->buf[xmit->tail];
  239. xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1);
  240. dz_out(dport, DZ_TDR, tmp);
  241. dport->port.icount.tx++;
  242. if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS)
  243. uart_write_wakeup(&dport->port);
  244. /* Are we are done. */
  245. if (uart_circ_empty(xmit)) {
  246. spin_lock(&dport->port.lock);
  247. dz_stop_tx(&dport->port);
  248. spin_unlock(&dport->port.lock);
  249. }
  250. }
  251. /*
  252. * ------------------------------------------------------------
  253. * check_modem_status()
  254. *
  255. * DS 3100 & 5100: Only valid for the MODEM line, duh!
  256. * DS 5000/200: Valid for the MODEM and PRINTER line.
  257. * ------------------------------------------------------------
  258. */
  259. static inline void check_modem_status(struct dz_port *dport)
  260. {
  261. /*
  262. * FIXME:
  263. * 1. No status change interrupt; use a timer.
  264. * 2. Handle the 3100/5000 as appropriate. --macro
  265. */
  266. unsigned short status;
  267. /* If not the modem line just return. */
  268. if (dport->port.line != DZ_MODEM)
  269. return;
  270. status = dz_in(dport, DZ_MSR);
  271. /* it's easy, since DSR2 is the only bit in the register */
  272. if (status)
  273. dport->port.icount.dsr++;
  274. }
  275. /*
  276. * ------------------------------------------------------------
  277. * dz_interrupt ()
  278. *
  279. * this is the main interrupt routine for the DZ chip.
  280. * It deals with the multiple ports.
  281. * ------------------------------------------------------------
  282. */
  283. static irqreturn_t dz_interrupt(int irq, void *dev)
  284. {
  285. struct dz_port *dport = dev;
  286. unsigned short status;
  287. /* get the reason why we just got an irq */
  288. status = dz_in(dport, DZ_CSR);
  289. if ((status & (DZ_RDONE | DZ_RIE)) == (DZ_RDONE | DZ_RIE))
  290. dz_receive_chars(dport);
  291. if ((status & (DZ_TRDY | DZ_TIE)) == (DZ_TRDY | DZ_TIE))
  292. dz_transmit_chars(dport);
  293. return IRQ_HANDLED;
  294. }
  295. /*
  296. * -------------------------------------------------------------------
  297. * Here ends the DZ interrupt routines.
  298. * -------------------------------------------------------------------
  299. */
  300. static unsigned int dz_get_mctrl(struct uart_port *uport)
  301. {
  302. /*
  303. * FIXME: Handle the 3100/5000 as appropriate. --macro
  304. */
  305. struct dz_port *dport = to_dport(uport);
  306. unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
  307. if (dport->port.line == DZ_MODEM) {
  308. if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR)
  309. mctrl &= ~TIOCM_DSR;
  310. }
  311. return mctrl;
  312. }
  313. static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
  314. {
  315. /*
  316. * FIXME: Handle the 3100/5000 as appropriate. --macro
  317. */
  318. struct dz_port *dport = to_dport(uport);
  319. unsigned short tmp;
  320. if (dport->port.line == DZ_MODEM) {
  321. tmp = dz_in(dport, DZ_TCR);
  322. if (mctrl & TIOCM_DTR)
  323. tmp &= ~DZ_MODEM_DTR;
  324. else
  325. tmp |= DZ_MODEM_DTR;
  326. dz_out(dport, DZ_TCR, tmp);
  327. }
  328. }
  329. /*
  330. * -------------------------------------------------------------------
  331. * startup ()
  332. *
  333. * various initialization tasks
  334. * -------------------------------------------------------------------
  335. */
  336. static int dz_startup(struct uart_port *uport)
  337. {
  338. struct dz_port *dport = to_dport(uport);
  339. unsigned long flags;
  340. unsigned short tmp;
  341. spin_lock_irqsave(&dport->port.lock, flags);
  342. /* enable the interrupt and the scanning */
  343. tmp = dz_in(dport, DZ_CSR);
  344. tmp |= DZ_RIE | DZ_TIE | DZ_MSE;
  345. dz_out(dport, DZ_CSR, tmp);
  346. spin_unlock_irqrestore(&dport->port.lock, flags);
  347. return 0;
  348. }
  349. /*
  350. * -------------------------------------------------------------------
  351. * shutdown ()
  352. *
  353. * This routine will shutdown a serial port; interrupts are disabled, and
  354. * DTR is dropped if the hangup on close termio flag is on.
  355. * -------------------------------------------------------------------
  356. */
  357. static void dz_shutdown(struct uart_port *uport)
  358. {
  359. struct dz_port *dport = to_dport(uport);
  360. unsigned long flags;
  361. spin_lock_irqsave(&dport->port.lock, flags);
  362. dz_stop_tx(&dport->port);
  363. spin_unlock_irqrestore(&dport->port.lock, flags);
  364. }
  365. /*
  366. * -------------------------------------------------------------------
  367. * dz_tx_empty() -- get the transmitter empty status
  368. *
  369. * Purpose: Let user call ioctl() to get info when the UART physically
  370. * is emptied. On bus types like RS485, the transmitter must
  371. * release the bus after transmitting. This must be done when
  372. * the transmit shift register is empty, not be done when the
  373. * transmit holding register is empty. This functionality
  374. * allows an RS485 driver to be written in user space.
  375. * -------------------------------------------------------------------
  376. */
  377. static unsigned int dz_tx_empty(struct uart_port *uport)
  378. {
  379. struct dz_port *dport = to_dport(uport);
  380. unsigned short tmp, mask = 1 << dport->port.line;
  381. tmp = dz_in(dport, DZ_TCR);
  382. tmp &= mask;
  383. return tmp ? 0 : TIOCSER_TEMT;
  384. }
  385. static void dz_break_ctl(struct uart_port *uport, int break_state)
  386. {
  387. /*
  388. * FIXME: Can't access BREAK bits in TDR easily;
  389. * reuse the code for polled TX. --macro
  390. */
  391. struct dz_port *dport = to_dport(uport);
  392. unsigned long flags;
  393. unsigned short tmp, mask = 1 << dport->port.line;
  394. spin_lock_irqsave(&uport->lock, flags);
  395. tmp = dz_in(dport, DZ_TCR);
  396. if (break_state)
  397. tmp |= mask;
  398. else
  399. tmp &= ~mask;
  400. dz_out(dport, DZ_TCR, tmp);
  401. spin_unlock_irqrestore(&uport->lock, flags);
  402. }
  403. static int dz_encode_baud_rate(unsigned int baud)
  404. {
  405. switch (baud) {
  406. case 50:
  407. return DZ_B50;
  408. case 75:
  409. return DZ_B75;
  410. case 110:
  411. return DZ_B110;
  412. case 134:
  413. return DZ_B134;
  414. case 150:
  415. return DZ_B150;
  416. case 300:
  417. return DZ_B300;
  418. case 600:
  419. return DZ_B600;
  420. case 1200:
  421. return DZ_B1200;
  422. case 1800:
  423. return DZ_B1800;
  424. case 2000:
  425. return DZ_B2000;
  426. case 2400:
  427. return DZ_B2400;
  428. case 3600:
  429. return DZ_B3600;
  430. case 4800:
  431. return DZ_B4800;
  432. case 7200:
  433. return DZ_B7200;
  434. case 9600:
  435. return DZ_B9600;
  436. default:
  437. return -1;
  438. }
  439. }
  440. static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
  441. struct ktermios *old_termios)
  442. {
  443. struct dz_port *dport = to_dport(uport);
  444. unsigned long flags;
  445. unsigned int cflag, baud;
  446. int bflag;
  447. cflag = dport->port.line;
  448. switch (termios->c_cflag & CSIZE) {
  449. case CS5:
  450. cflag |= DZ_CS5;
  451. break;
  452. case CS6:
  453. cflag |= DZ_CS6;
  454. break;
  455. case CS7:
  456. cflag |= DZ_CS7;
  457. break;
  458. case CS8:
  459. default:
  460. cflag |= DZ_CS8;
  461. }
  462. if (termios->c_cflag & CSTOPB)
  463. cflag |= DZ_CSTOPB;
  464. if (termios->c_cflag & PARENB)
  465. cflag |= DZ_PARENB;
  466. if (termios->c_cflag & PARODD)
  467. cflag |= DZ_PARODD;
  468. baud = uart_get_baud_rate(uport, termios, old_termios, 50, 9600);
  469. bflag = dz_encode_baud_rate(baud);
  470. if (bflag < 0) { /* Try to keep unchanged. */
  471. baud = uart_get_baud_rate(uport, old_termios, NULL, 50, 9600);
  472. bflag = dz_encode_baud_rate(baud);
  473. if (bflag < 0) { /* Resort to 9600. */
  474. baud = 9600;
  475. bflag = DZ_B9600;
  476. }
  477. tty_termios_encode_baud_rate(termios, baud, baud);
  478. }
  479. cflag |= bflag;
  480. if (termios->c_cflag & CREAD)
  481. cflag |= DZ_RXENAB;
  482. spin_lock_irqsave(&dport->port.lock, flags);
  483. uart_update_timeout(uport, termios->c_cflag, baud);
  484. dz_out(dport, DZ_LPR, cflag);
  485. dport->cflag = cflag;
  486. /* setup accept flag */
  487. dport->port.read_status_mask = DZ_OERR;
  488. if (termios->c_iflag & INPCK)
  489. dport->port.read_status_mask |= DZ_FERR | DZ_PERR;
  490. if (termios->c_iflag & (BRKINT | PARMRK))
  491. dport->port.read_status_mask |= DZ_BREAK;
  492. /* characters to ignore */
  493. uport->ignore_status_mask = 0;
  494. if ((termios->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))
  495. dport->port.ignore_status_mask |= DZ_OERR;
  496. if (termios->c_iflag & IGNPAR)
  497. dport->port.ignore_status_mask |= DZ_FERR | DZ_PERR;
  498. if (termios->c_iflag & IGNBRK)
  499. dport->port.ignore_status_mask |= DZ_BREAK;
  500. spin_unlock_irqrestore(&dport->port.lock, flags);
  501. }
  502. static const char *dz_type(struct uart_port *port)
  503. {
  504. return "DZ";
  505. }
  506. static void dz_release_port(struct uart_port *port)
  507. {
  508. /* nothing to do */
  509. }
  510. static int dz_request_port(struct uart_port *port)
  511. {
  512. return 0;
  513. }
  514. static void dz_config_port(struct uart_port *port, int flags)
  515. {
  516. if (flags & UART_CONFIG_TYPE)
  517. port->type = PORT_DZ;
  518. }
  519. /*
  520. * verify the new serial_struct (for TIOCSSERIAL).
  521. */
  522. static int dz_verify_port(struct uart_port *port, struct serial_struct *ser)
  523. {
  524. int ret = 0;
  525. if (ser->type != PORT_UNKNOWN && ser->type != PORT_DZ)
  526. ret = -EINVAL;
  527. if (ser->irq != port->irq)
  528. ret = -EINVAL;
  529. return ret;
  530. }
  531. static struct uart_ops dz_ops = {
  532. .tx_empty = dz_tx_empty,
  533. .get_mctrl = dz_get_mctrl,
  534. .set_mctrl = dz_set_mctrl,
  535. .stop_tx = dz_stop_tx,
  536. .start_tx = dz_start_tx,
  537. .stop_rx = dz_stop_rx,
  538. .enable_ms = dz_enable_ms,
  539. .break_ctl = dz_break_ctl,
  540. .startup = dz_startup,
  541. .shutdown = dz_shutdown,
  542. .set_termios = dz_set_termios,
  543. .type = dz_type,
  544. .release_port = dz_release_port,
  545. .request_port = dz_request_port,
  546. .config_port = dz_config_port,
  547. .verify_port = dz_verify_port,
  548. };
  549. static void __init dz_init_ports(void)
  550. {
  551. static int first = 1;
  552. struct dz_port *dport;
  553. unsigned long base;
  554. int i;
  555. if (!first)
  556. return;
  557. first = 0;
  558. if (mips_machtype == MACH_DS23100 ||
  559. mips_machtype == MACH_DS5100)
  560. base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_DZ11);
  561. else
  562. base = CKSEG1ADDR(KN02_SLOT_BASE + KN02_DZ11);
  563. for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
  564. spin_lock_init(&dport->port.lock);
  565. dport->port.membase = (char *) base;
  566. dport->port.iotype = UPIO_MEM;
  567. dport->port.irq = dec_interrupt[DEC_IRQ_DZ11];
  568. dport->port.line = i;
  569. dport->port.fifosize = 1;
  570. dport->port.ops = &dz_ops;
  571. dport->port.flags = UPF_BOOT_AUTOCONF;
  572. }
  573. }
  574. static void dz_reset(struct dz_port *dport)
  575. {
  576. dz_out(dport, DZ_CSR, DZ_CLR);
  577. while (dz_in(dport, DZ_CSR) & DZ_CLR);
  578. iob();
  579. /* enable scanning */
  580. dz_out(dport, DZ_CSR, DZ_MSE);
  581. }
  582. #ifdef CONFIG_SERIAL_DZ_CONSOLE
  583. /*
  584. * -------------------------------------------------------------------
  585. * dz_console_putchar() -- transmit a character
  586. *
  587. * Polled transmission. This is tricky. We need to mask transmit
  588. * interrupts so that they do not interfere, enable the transmitter
  589. * for the line requested and then wait till the transmit scanner
  590. * requests data for this line. But it may request data for another
  591. * line first, in which case we have to disable its transmitter and
  592. * repeat waiting till our line pops up. Only then the character may
  593. * be transmitted. Finally, the state of the transmitter mask is
  594. * restored. Welcome to the world of PDP-11!
  595. * -------------------------------------------------------------------
  596. */
  597. static void dz_console_putchar(struct uart_port *uport, int ch)
  598. {
  599. struct dz_port *dport = to_dport(uport);
  600. unsigned long flags;
  601. unsigned short csr, tcr, trdy, mask;
  602. int loops = 10000;
  603. spin_lock_irqsave(&dport->port.lock, flags);
  604. csr = dz_in(dport, DZ_CSR);
  605. dz_out(dport, DZ_CSR, csr & ~DZ_TIE);
  606. tcr = dz_in(dport, DZ_TCR);
  607. tcr |= 1 << dport->port.line;
  608. mask = tcr;
  609. dz_out(dport, DZ_TCR, mask);
  610. iob();
  611. spin_unlock_irqrestore(&dport->port.lock, flags);
  612. do {
  613. trdy = dz_in(dport, DZ_CSR);
  614. if (!(trdy & DZ_TRDY))
  615. continue;
  616. trdy = (trdy & DZ_TLINE) >> 8;
  617. if (trdy == dport->port.line)
  618. break;
  619. mask &= ~(1 << trdy);
  620. dz_out(dport, DZ_TCR, mask);
  621. iob();
  622. udelay(2);
  623. } while (loops--);
  624. if (loops) /* Cannot send otherwise. */
  625. dz_out(dport, DZ_TDR, ch);
  626. dz_out(dport, DZ_TCR, tcr);
  627. dz_out(dport, DZ_CSR, csr);
  628. }
  629. /*
  630. * -------------------------------------------------------------------
  631. * dz_console_print ()
  632. *
  633. * dz_console_print is registered for printk.
  634. * The console must be locked when we get here.
  635. * -------------------------------------------------------------------
  636. */
  637. static void dz_console_print(struct console *co,
  638. const char *str,
  639. unsigned int count)
  640. {
  641. struct dz_port *dport = &dz_ports[co->index];
  642. #ifdef DEBUG_DZ
  643. prom_printf((char *) str);
  644. #endif
  645. uart_console_write(&dport->port, str, count, dz_console_putchar);
  646. }
  647. static int __init dz_console_setup(struct console *co, char *options)
  648. {
  649. struct dz_port *dport = &dz_ports[co->index];
  650. int baud = 9600;
  651. int bits = 8;
  652. int parity = 'n';
  653. int flow = 'n';
  654. if (options)
  655. uart_parse_options(options, &baud, &parity, &bits, &flow);
  656. dz_reset(dport);
  657. return uart_set_options(&dport->port, co, baud, parity, bits, flow);
  658. }
  659. static struct uart_driver dz_reg;
  660. static struct console dz_console = {
  661. .name = "ttyS",
  662. .write = dz_console_print,
  663. .device = uart_console_device,
  664. .setup = dz_console_setup,
  665. .flags = CON_PRINTBUFFER,
  666. .index = -1,
  667. .data = &dz_reg,
  668. };
  669. static int __init dz_serial_console_init(void)
  670. {
  671. if (!IOASIC) {
  672. dz_init_ports();
  673. register_console(&dz_console);
  674. return 0;
  675. } else
  676. return -ENXIO;
  677. }
  678. console_initcall(dz_serial_console_init);
  679. #define SERIAL_DZ_CONSOLE &dz_console
  680. #else
  681. #define SERIAL_DZ_CONSOLE NULL
  682. #endif /* CONFIG_SERIAL_DZ_CONSOLE */
  683. static struct uart_driver dz_reg = {
  684. .owner = THIS_MODULE,
  685. .driver_name = "serial",
  686. .dev_name = "ttyS",
  687. .major = TTY_MAJOR,
  688. .minor = 64,
  689. .nr = DZ_NB_PORT,
  690. .cons = SERIAL_DZ_CONSOLE,
  691. };
  692. static int __init dz_init(void)
  693. {
  694. int ret, i;
  695. if (IOASIC)
  696. return -ENXIO;
  697. printk("%s%s\n", dz_name, dz_version);
  698. dz_init_ports();
  699. #ifndef CONFIG_SERIAL_DZ_CONSOLE
  700. /* reset the chip */
  701. dz_reset(&dz_ports[0]);
  702. #endif
  703. ret = uart_register_driver(&dz_reg);
  704. if (ret != 0)
  705. goto out;
  706. ret = request_irq(dz_ports[0].port.irq, dz_interrupt, IRQF_DISABLED,
  707. "DZ", &dz_ports[0]);
  708. if (ret != 0) {
  709. printk(KERN_ERR "dz: Cannot get IRQ %d!\n",
  710. dz_ports[0].port.irq);
  711. goto out_unregister;
  712. }
  713. for (i = 0; i < DZ_NB_PORT; i++)
  714. uart_add_one_port(&dz_reg, &dz_ports[i].port);
  715. return ret;
  716. out_unregister:
  717. uart_unregister_driver(&dz_reg);
  718. out:
  719. return ret;
  720. }
  721. module_init(dz_init);
  722. MODULE_DESCRIPTION("DECstation DZ serial driver");
  723. MODULE_LICENSE("GPL");