source: rtems/c/src/libchip/serial/mc68681.c @ 1c6926c1

Last change on this file since 1c6926c1 was 1c6926c1, checked in by Kevin Kirspel <kevin-kirspel@…>, on Mar 21, 2017 at 7:39:48 PM

termios: Synchronize with latest FreeBSD headers

Adding modified FreeBSD headers to synchronize RTEMS termios with
FreeBSD. Modify termios to support dedicated input and output baud for
termios structure. Updated BSPs to use dedicated input and output baud
in termios structure. Updated tools to use dedicated input and output
baud in termios structure. Updated termios testsuites to use dedicated
input and output baud in termios structure.

Close #2897.

  • Property mode set to 100644
File size: 18.8 KB
Line 
1/*
2 *  This file contains the termios TTY driver for the Motorola MC68681.
3 *
4 *  This part is available from a number of secondary sources.
5 *  In particular, we know about the following:
6 *
7 *     + Exar 88c681 and 68c681
8 *
9 *  COPYRIGHT (c) 1989-1999.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#include <rtems.h>
18#include <rtems/libio.h>
19#include <rtems/score/sysstate.h>
20#include <stdlib.h>
21
22#include <libchip/serial.h>
23#include <libchip/mc68681.h>
24#include <libchip/sersupp.h>
25#include "mc68681_p.h"
26
27/*
28 * Flow control is only supported when using interrupts
29 */
30
31const console_fns mc68681_fns =
32{
33  libchip_serial_default_probe,   /* deviceProbe */
34  mc68681_open,                   /* deviceFirstOpen */
35  NULL,                           /* deviceLastClose */
36  NULL,                           /* deviceRead */
37  mc68681_write_support_int,      /* deviceWrite */
38  mc68681_initialize_interrupts,  /* deviceInitialize */
39  mc68681_write_polled,           /* deviceWritePolled */
40  mc68681_set_attributes,         /* deviceSetAttributes */
41  true                            /* deviceOutputUsesInterrupts */
42};
43
44const console_fns mc68681_fns_polled =
45{
46  libchip_serial_default_probe,        /* deviceProbe */
47  mc68681_open,                        /* deviceFirstOpen */
48  mc68681_close,                       /* deviceLastClose */
49  mc68681_inbyte_nonblocking_polled,   /* deviceRead */
50  mc68681_write_support_polled,        /* deviceWrite */
51  mc68681_init,                        /* deviceInitialize */
52  mc68681_write_polled,                /* deviceWritePolled */
53  mc68681_set_attributes,              /* deviceSetAttributes */
54  false,                               /* deviceOutputUsesInterrupts */
55};
56
57
58#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
59  extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
60#endif
61
62/*
63 *  Console Device Driver Entry Points
64 */
65
66/*
67 *  mc68681_baud_rate
68 *
69 *  This routine returns the proper ACR bit and baud rate field values
70 *  based on the requested baud rate.  The baud rate set to be used
71 *  must be configured by the user.
72 */
73
74MC68681_STATIC int mc68681_baud_rate(
75  int           minor,
76  int           baud,
77  unsigned int *baud_mask_p,
78  unsigned int *acr_bit_p,
79  unsigned int *command
80);
81
82/*
83 *  mc68681_set_attributes
84 *
85 *  This function sets the DUART channel to reflect the requested termios
86 *  port settings.
87 */
88
89MC68681_STATIC int mc68681_set_attributes(
90  int minor,
91  const struct termios *t
92)
93{
94  uint32_t               pMC68681_port;
95  uint32_t               pMC68681;
96  unsigned int           mode1;
97  unsigned int           mode2;
98  unsigned int           baud_mask;
99  unsigned int           acr_bit;
100  unsigned int           cmd = 0;
101  setRegister_f          setReg;
102  rtems_interrupt_level  Irql;
103
104  pMC68681      = Console_Port_Tbl[minor]->ulCtrlPort1;
105  pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
106  setReg        = Console_Port_Tbl[minor]->setRegister;
107
108  /*
109   *  Set the baud rate
110   */
111
112  if (mc68681_baud_rate( minor, t->c_cflag, &baud_mask, &acr_bit, &cmd ) == -1)
113    return -1;
114
115  baud_mask |=  baud_mask << 4;
116  acr_bit   <<= 7;
117
118  /*
119   *  Parity
120   */
121
122  mode1 = 0;
123  mode2 = 0;
124
125  if (t->c_cflag & PARENB) {
126    if (t->c_cflag & PARODD)
127      mode1 |= 0x04;
128    /* else
129                mode1 |= 0x04; */
130  } else {
131   mode1 |= 0x10;
132  }
133
134  /*
135   *  Character Size
136   */
137
138  if (t->c_cflag & CSIZE) {
139    switch (t->c_cflag & CSIZE) {
140      case CS5:  break;
141      case CS6:  mode1 |= 0x01;  break;
142      case CS7:  mode1 |= 0x02;  break;
143      case CS8:  mode1 |= 0x03;  break;
144    }
145  } else {
146    mode1 |= 0x03;       /* default to 9600,8,N,1 */
147  }
148
149  /*
150   *  Stop Bits
151   */
152
153  if (t->c_cflag & CSTOPB) {
154    mode2 |= 0x0F;                      /* 2 stop bits */
155  } else {
156    if ((t->c_cflag & CSIZE) == CS5)    /* CS5 and 1 stop bits not supported */
157      return -1;
158    mode2 |= 0x07;                      /* 1 stop bit */
159  }
160
161 /*
162  *   Hardware Flow Control
163  */
164
165  if(t->c_cflag & CRTSCTS) {
166          mode1 |= 0x80; /* Enable Rx RTS Control */
167          mode2 |= 0x10; /* Enable CTS Enable Tx */
168  }
169
170
171  rtems_interrupt_disable(Irql);
172    (*setReg)( pMC68681, MC68681_AUX_CTRL_REG, acr_bit );
173    (*setReg)( pMC68681_port, MC68681_CLOCK_SELECT, baud_mask );
174    if ( cmd ) {
175      (*setReg)( pMC68681_port, MC68681_COMMAND, cmd );         /* RX */
176      (*setReg)( pMC68681_port, MC68681_COMMAND, cmd | 0x20 );  /* TX */
177    }
178    (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_MR_PTR );
179    (*setReg)( pMC68681_port, MC68681_MODE, mode1 );
180    (*setReg)( pMC68681_port, MC68681_MODE, mode2 );
181  rtems_interrupt_enable(Irql);
182  return 0;
183}
184
185/*
186 *  mc68681_initialize_context
187 *
188 *  This function sets the default values of the per port context structure.
189 */
190
191MC68681_STATIC void mc68681_initialize_context(
192  int               minor,
193  mc68681_context  *pmc68681Context
194)
195{
196  int          port;
197  unsigned int pMC68681;
198  unsigned int pMC68681_port;
199
200  pMC68681      = Console_Port_Tbl[minor]->ulCtrlPort1;
201  pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
202
203  pmc68681Context->mate = -1;
204
205  for (port=0 ; port<Console_Port_Count ; port++ ) {
206    if ( Console_Port_Tbl[port]->ulCtrlPort1 == pMC68681 &&
207         Console_Port_Tbl[port]->ulCtrlPort2 != pMC68681_port ) {
208      pmc68681Context->mate = port;
209      pmc68681Context->imr  = 0;
210      break;
211    }
212  }
213
214}
215
216/*
217 *  mc68681_init
218 *
219 *  This function initializes the DUART to a quiecsent state.
220 */
221
222MC68681_STATIC void mc68681_init(int minor)
223{
224  uint32_t                pMC68681_port;
225  mc68681_context        *pmc68681Context;
226  setRegister_f           setReg;
227
228  pmc68681Context = (mc68681_context *) malloc(sizeof(mc68681_context));
229
230  Console_Port_Data[minor].pDeviceContext = (void *)pmc68681Context;
231
232  mc68681_initialize_context( minor, pmc68681Context );
233
234  pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
235  setReg        = Console_Port_Tbl[minor]->setRegister;
236
237  /*
238   *  Reset everything and leave this port disabled.
239   */
240
241  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_RX );
242  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_TX );
243  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_ERROR );
244  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_BREAK );
245  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_STOP_BREAK );
246  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_TX );
247  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_RX );
248
249
250  (*setReg)( pMC68681_port, MC68681_MODE_REG_1A, 0x00 );
251  (*setReg)( pMC68681_port, MC68681_MODE_REG_2A, 0x02 );
252
253  /*
254   *  Disable interrupts on RX and TX for this port
255   */
256
257  mc68681_enable_interrupts( minor, MC68681_IMR_DISABLE_ALL );
258}
259
260/*
261 *  mc68681_open
262 *
263 *  This function opens a port for communication.
264 *
265 *  Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
266 */
267
268MC68681_STATIC int mc68681_open(
269  int      major,
270  int      minor,
271  void    *arg
272)
273{
274  uint32_t               pMC68681;
275  uint32_t               pMC68681_port;
276  unsigned int           baud;
277  unsigned int           acr_bit;
278  unsigned int           vector;
279  unsigned int           command = 0;
280  rtems_interrupt_level  Irql;
281  setRegister_f          setReg;
282  int                    status;
283
284
285  pMC68681      = Console_Port_Tbl[minor]->ulCtrlPort1;
286  pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
287  setReg        = Console_Port_Tbl[minor]->setRegister;
288  vector        = Console_Port_Tbl[minor]->ulIntVector;
289
290  /* XXX default baud rate should be from configuration table */
291
292  status = mc68681_baud_rate( minor, B9600, &baud, &acr_bit, &command );
293  if (status < 0) rtems_fatal_error_occurred (RTEMS_NOT_DEFINED);
294
295  /*
296   *  Set the DUART channel to a default useable state
297   */
298
299  rtems_interrupt_disable(Irql);
300    (*setReg)( pMC68681, MC68681_AUX_CTRL_REG, acr_bit << 7 );
301    (*setReg)( pMC68681_port, MC68681_CLOCK_SELECT, baud );
302    if ( command ) {
303      (*setReg)( pMC68681_port, MC68681_COMMAND, command );         /* RX */
304      (*setReg)( pMC68681_port, MC68681_COMMAND, command | 0x20 );  /* TX */
305    }
306    (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_MR_PTR );
307    (*setReg)( pMC68681_port, MC68681_MODE, 0x13 );
308    (*setReg)( pMC68681_port, MC68681_MODE, 0x07 );
309  rtems_interrupt_enable(Irql);
310
311  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_ENABLE_TX );
312  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_ENABLE_RX );
313
314  (*setReg)( pMC68681, MC68681_INTERRUPT_VECTOR_REG, vector );
315
316  return RTEMS_SUCCESSFUL;
317}
318
319/*
320 *  mc68681_close
321 *
322 *  This function shuts down the requested port.
323 */
324
325MC68681_STATIC int mc68681_close(
326  int      major,
327  int      minor,
328  void    *arg
329)
330{
331  uint32_t        pMC68681_port;
332  setRegister_f   setReg;
333
334  pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
335  setReg        = Console_Port_Tbl[minor]->setRegister;
336
337  /*
338   *  Disable interrupts from this channel and then disable it totally.
339   */
340  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_TX );
341  (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_RX );
342
343  return(RTEMS_SUCCESSFUL);
344}
345
346/*
347 *  mc68681_write_polled
348 *
349 *  This routine polls out the requested character.
350 */
351
352MC68681_STATIC void mc68681_write_polled(
353  int   minor,
354  char  cChar
355)
356{
357  uint32_t                pMC68681_port;
358  unsigned char           ucLineStatus;
359  int                     iTimeout;
360  getRegister_f           getReg;
361  setRegister_f           setReg;
362
363  pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
364  getReg        = Console_Port_Tbl[minor]->getRegister;
365  setReg        = Console_Port_Tbl[minor]->setRegister;
366
367  /*
368   * wait for transmitter holding register to be empty
369   */
370  iTimeout = 1000;
371  ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
372  while ((ucLineStatus & (MC68681_TX_READY|MC68681_TX_EMPTY)) == 0) {
373
374    if ((ucLineStatus & 0xF0))
375      (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_ERROR );
376
377    /*
378     * Yield while we wait
379     */
380
381#if 0
382     if(_System_state_Is_up(_System_state_Get())) {
383       rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
384     }
385#endif
386     ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
387     if(!--iTimeout) {
388       break;
389     }
390  }
391
392  /*
393   * transmit character
394   */
395
396  (*setReg)(pMC68681_port, MC68681_TX_BUFFER, cChar);
397}
398
399/*
400 *  mc68681_isr
401 *
402 *  This is the single interrupt entry point which parcels interrupts
403 *  out to the various ports.
404 */
405
406MC68681_STATIC rtems_isr mc68681_isr(
407  rtems_vector_number vector
408)
409{
410  int     minor;
411
412  for(minor=0 ; minor<Console_Port_Count ; minor++) {
413    if(Console_Port_Tbl[minor]->ulIntVector == vector &&
414       Console_Port_Tbl[minor]->deviceType == SERIAL_MC68681 ) {
415      mc68681_process(minor);
416    }
417  }
418}
419
420/*
421 *  mc68681_initialize_interrupts
422 *
423 *  This routine initializes the console's receive and transmit
424 *  ring buffers and loads the appropriate vectors to handle the interrupts.
425 */
426
427MC68681_STATIC void mc68681_initialize_interrupts(int minor)
428{
429  mc68681_init(minor);
430
431  Console_Port_Data[minor].bActive = FALSE;
432
433#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
434  set_vector(mc68681_isr, Console_Port_Tbl[minor]->ulIntVector, 1);
435#endif
436
437  mc68681_enable_interrupts(minor,MC68681_IMR_ENABLE_ALL_EXCEPT_TX);
438}
439
440/*
441 *  mc68681_write_support_int
442 *
443 *  Console Termios output entry point when using interrupt driven output.
444 */
445
446MC68681_STATIC ssize_t mc68681_write_support_int(
447  int         minor,
448  const char *buf,
449  size_t      len
450)
451{
452  uint32_t        Irql;
453  uint32_t        pMC68681_port;
454  setRegister_f   setReg;
455
456  pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
457  setReg        = Console_Port_Tbl[minor]->setRegister;
458
459  /*
460   *  We are using interrupt driven output and termios only sends us
461   *  one character at a time.
462   */
463
464  if ( !len )
465    return 0;
466
467  /*
468   *  Put the character out and enable interrupts if necessary.
469   */
470
471  rtems_interrupt_disable(Irql);
472    if ( Console_Port_Data[minor].bActive == FALSE ) {
473      Console_Port_Data[minor].bActive = TRUE;
474      mc68681_enable_interrupts(minor, MC68681_IMR_ENABLE_ALL);
475    }
476    (*setReg)(pMC68681_port, MC68681_TX_BUFFER, *buf);
477  rtems_interrupt_enable(Irql);
478
479  return 0;
480}
481
482/*
483 *  mc68681_write_support_polled
484 *
485 *  Console Termios output entry point when using polled output.
486 *
487 */
488
489MC68681_STATIC ssize_t mc68681_write_support_polled(
490  int         minor,
491  const char *buf,
492  size_t      len
493)
494{
495  int nwrite = 0;
496
497  /*
498   * poll each byte in the string out of the port.
499   */
500  while (nwrite < len) {
501    /*
502     * transmit character
503     */
504    mc68681_write_polled(minor, *buf++);
505    nwrite++;
506  }
507
508  /*
509   * return the number of bytes written.
510   */
511  return nwrite;
512}
513
514/*
515 *  mc68681_inbyte_nonblocking_polled
516 *
517 *  Console Termios polling input entry point.
518 */
519
520MC68681_STATIC int mc68681_inbyte_nonblocking_polled(
521  int minor
522)
523{
524  uint32_t             pMC68681_port;
525  unsigned char        ucLineStatus;
526  unsigned char        cChar;
527  getRegister_f        getReg;
528
529  pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
530  getReg        = Console_Port_Tbl[minor]->getRegister;
531
532  ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
533  if(ucLineStatus & MC68681_RX_READY) {
534    cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
535    return (int)cChar;
536  } else {
537    return -1;
538  }
539}
540
541/*
542 *  mc68681_baud_rate
543 */
544
545MC68681_STATIC int mc68681_baud_rate(
546  int           minor,
547  int           baud,
548  unsigned int *baud_mask_p,
549  unsigned int *acr_bit_p,
550  unsigned int *command
551)
552{
553  unsigned int           baud_mask;
554  unsigned int           acr_bit;
555  int                    status;
556  int                    is_extended;
557  int                    baud_requested;
558  mc68681_baud_table_t  *baud_tbl;
559
560  baud_mask = 0;
561  acr_bit = 0;
562  status = 0;
563
564  if (Console_Port_Tbl[minor]->ulDataPort & MC68681_DATA_BAUD_RATE_SET_2)
565  {
566    acr_bit = 1;
567  }
568
569  is_extended = 0;
570
571  switch (Console_Port_Tbl[minor]->ulDataPort & MC68681_XBRG_MASK) {
572    case MC68681_XBRG_IGNORED:
573      *command = 0x00;
574      break;
575    case MC68681_XBRG_ENABLED:
576      *command = 0x80;
577      is_extended = 1;
578      break;
579    case MC68681_XBRG_DISABLED:
580      *command = 0x90;
581      break;
582  }
583
584  baud_requested = baud;
585  if (!baud_requested)
586    baud_requested = B9600;              /* default to 9600 baud */
587
588  baud_requested = rtems_termios_baud_to_index( baud_requested );
589  if (baud_requested == -1)
590    return -1;
591
592  baud_tbl = (mc68681_baud_table_t *)
593     ((uintptr_t)Console_Port_Tbl[minor]->ulClock);
594  if (!baud_tbl)
595    rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS);
596
597  if ( is_extended )
598    baud_mask = (unsigned int)baud_tbl[ acr_bit + 2 ][ baud_requested ];
599  else
600    baud_mask = baud_tbl[ acr_bit ][ baud_requested ];
601
602  if ( baud_mask == MC68681_BAUD_NOT_VALID )
603    status = -1;
604
605  /*
606   *  upper nibble is receiver and lower nibble is transmitter
607   */
608
609  *baud_mask_p = (baud_mask << 4) | baud_mask;
610  *acr_bit_p   = acr_bit;
611  return status;
612}
613
614/*
615 *  mc68681_process
616 *
617 *  This routine is the per port console interrupt handler.
618 */
619
620MC68681_STATIC void mc68681_process(
621  int  minor
622)
623{
624  uint32_t                pMC68681;
625  uint32_t                pMC68681_port;
626  volatile uint8_t        ucLineStatus;
627  volatile uint8_t        ucISRStatus;
628  char                    cChar;
629  getRegister_f           getReg;
630
631  pMC68681      = Console_Port_Tbl[minor]->ulCtrlPort1;
632  pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
633  getReg        = Console_Port_Tbl[minor]->getRegister;
634
635  /* Get ISR at the beginning of the IT routine */
636  ucISRStatus = (*getReg)(pMC68681, MC68681_INTERRUPT_STATUS_REG);
637
638  /* Get good ISR a or b channel */
639  if (pMC68681 != pMC68681_port){
640    ucISRStatus >>= 4;
641  }
642
643  /* See if is usefull to call rtems_termios_dequeue */
644  if(Console_Port_Data[minor].bActive == FALSE) {
645                ucISRStatus = ucISRStatus & ~MC68681_IR_TX_READY;
646  }
647
648  /*
649   * Deal with any received characters
650   */
651  while(true) {
652    ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
653    if(!(ucLineStatus & MC68681_RX_READY)) {
654      break;
655    }
656    /*
657     *  If there is a RX error, then dump all the data.
658     */
659    if ( ucLineStatus & MC68681_RX_ERRORS ) {
660      do {
661        cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
662        ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
663      } while ( ucLineStatus & MC68681_RX_READY );
664      continue;
665    }
666    cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
667    rtems_termios_enqueue_raw_characters(
668      Console_Port_Data[minor].termios_data,
669      &cChar,
670      1
671    );
672  }
673
674  /*
675   *  Deal with the transmitter
676   */
677
678  if (ucISRStatus & MC68681_IR_TX_READY) {
679    if (!rtems_termios_dequeue_characters(
680          Console_Port_Data[minor].termios_data, 1)) {
681          /* If no more char to send, disable TX interrupt */
682      Console_Port_Data[minor].bActive = FALSE;
683      mc68681_enable_interrupts(minor, MC68681_IMR_ENABLE_ALL_EXCEPT_TX);
684    }
685  }
686}
687
688/*
689 *  mc68681_build_imr
690 *
691 *  This function returns the value for the interrupt mask register for this
692 *  DUART.  Since this is a shared register, we must look at the other port
693 *  on this chip to determine whether or not it is using interrupts.
694 */
695
696MC68681_STATIC unsigned int mc68681_build_imr(
697  int  minor,
698  int  enable_flag
699)
700{
701  int              mate;
702  int              is_a;
703  unsigned int     mask;
704  unsigned int     mate_mask;
705  unsigned int     pMC68681;
706  unsigned int     pMC68681_port;
707  mc68681_context *pmc68681Context;
708  mc68681_context *mateContext;
709
710  pMC68681        = Console_Port_Tbl[minor]->ulCtrlPort1;
711  pMC68681_port   = Console_Port_Tbl[minor]->ulCtrlPort2;
712  pmc68681Context = (mc68681_context *) Console_Port_Data[minor].pDeviceContext;
713  mate            = pmc68681Context->mate;
714
715  mask = 0;
716  mate_mask = 0;
717
718  is_a = (pMC68681 == pMC68681_port);
719
720  /*
721   *  If there is a mate for this port, get its IMR mask.
722   */
723
724  if ( mate != -1 ) {
725    mateContext = Console_Port_Data[mate].pDeviceContext;
726
727    if (mateContext)
728      mate_mask = mateContext->imr;
729  }
730
731  /*
732   *  Calculate this port's IMR mask and save it in the context area.
733   */
734
735  if ( Console_Port_Tbl[minor]->pDeviceFns->deviceOutputUsesInterrupts )
736    mask = enable_flag;
737
738  pmc68681Context->imr = mask;
739
740  /*
741   *  Now return the full IMR value
742   */
743
744  if (is_a)
745    return (mate_mask << 4) | mask;
746
747  return (mask << 4) | mate_mask;
748}
749
750/*
751 *  mc68681_enable_interrupts
752 *
753 *  This function enables specific interrupt sources on the DUART.
754 */
755
756MC68681_STATIC void mc68681_enable_interrupts(
757  int minor,
758  int imr_mask
759)
760{
761  uint32_t              pMC68681;
762  setRegister_f         setReg;
763
764  pMC68681 = Console_Port_Tbl[minor]->ulCtrlPort1;
765  setReg   = Console_Port_Tbl[minor]->setRegister;
766
767  /*
768   *  Enable interrupts on RX and TX -- not break
769   */
770
771  (*setReg)(
772     pMC68681,
773     MC68681_INTERRUPT_MASK_REG,
774     mc68681_build_imr(minor, imr_mask)
775  );
776}
Note: See TracBrowser for help on using the repository browser.