292feea29dba8e1a053e79f1de4ed7f1dc56c69d
[rtems-devel.git] / rtems-patches / rtems-csb336-20051008-uart.patch
1 Index: rtems/c/src/lib/libbsp/arm/csb336/console/uart.c
2 ===================================================================
3 --- rtems.orig/c/src/lib/libbsp/arm/csb336/console/uart.c
4 +++ rtems/c/src/lib/libbsp/arm/csb336/console/uart.c
5 @@ -1,262 +1,453 @@
6  /*
7 - *  console driver for MC9328XML UARTs
8 + * Console driver for MC9328XML UARTs.
9   *
10 - *  This driver uses the shared console driver in 
11 - *  ...../libbsp/shared/console.c
12 + * Written Jay Monkman <jtm@lopingdog.com>
13 + * Copyright (c) 2005 by Loping Dog Embedded Systems
14   *
15 - *  If you want the driver to be interrupt driven, you 
16 - *  need to write the ISR, and in the ISR insert the
17 - *  chars into termios's queue.
18 + * The license and distribution terms for this file may be
19 + * found in the file LICENSE in this distribution or at
20 + *    http://www.rtems.com/license
21   *
22 - *  Copyright (c) 2004 Cogent Computer Systems
23 - *  Written by Jay Monkman <jtm@lopingdog.com>
24 - *
25 - *  The license and distribution terms for this file may be
26 - *  found in the file LICENSE in this distribution or at
27 - *
28 - *  http://www.OARcorp.com/rtems/license.html.
29 - *
30 - *
31 - *  $Id: uart.c,v 1.1 2004/07/15 06:12:05 jtm Exp $
32 -*/
33 -#include <bsp.h>                /* Must be before libio.h */
34 + * $Id:$
35 + */
36 +#include <bsp.h>
37  #include <rtems/libio.h>
38 -#include <termios.h>
39 +#include <libchip/sersupp.h>
40 +#include <rtems/error.h>
41  #include <rtems/bspIo.h>
42 -
43 -/* Put the CPU (or UART) specific header file #include here */
44 +#include <termios.h>
45 +#include <irq.h>
46  #include <mc9328mxl.h>
47 -#include <libchip/serial.h>
48 -#include <libchip/sersupp.h>
49 +
50 +
51 +/* Define this to use interrupt driver UART driver */
52 +#define USE_INTERRUPTS 1
53  
54  /* How many serial ports? */
55  #define NUM_DEVS       2
56 +#define poll_write(c)  imx_uart_poll_write_char(0, c)
57 +#define poll_read()  imx_uart_poll_read_char(0)
58  
59 -int     uart_poll_read(int minor);
60 +static int imx_uart_first_open(int, int, void *);
61 +static int imx_uart_last_close(int, int, void *);
62 +static int imx_uart_poll_read(int);
63 +static int imx_uart_set_attrs(int, const struct termios *);
64 +static void imx_uart_init(int minor);
65 +static void imx_uart_set_baud(int, int);
66 +static int imx_uart_poll_write(int, const char *, int);
67 +
68 +#if defined(USE_INTERRUPTS)
69 +static void imx_uart_tx_isr(rtems_irq_hdl_param);
70 +static void imx_uart_rx_isr(rtems_irq_hdl_param);
71 +static void imx_uart_isr_on(const rtems_irq_connect_data *irq);
72 +static void imx_uart_isr_off(const rtems_irq_connect_data *irq);
73 +static int imx_uart_isr_is_on(const rtems_irq_connect_data *irq);
74 +static int imx_uart_intr_write(int, const char *, int);
75 +#endif
76  
77 -int dbg_dly;
78  
79 -/* static function prototypes */
80 -static int     uart_first_open(int major, int minor, void *arg);
81 -static int     uart_last_close(int major, int minor, void *arg);
82 -static int     uart_read(int minor);
83 -static int     uart_write(int minor, const char *buf, int len);
84 -static void    uart_init(int minor);
85 -static void    uart_write_polled(int minor, char c);
86 -static int     uart_set_attributes(int minor, const struct termios *t);
87 -
88 -/* These are used by code in console.c */
89 -unsigned long Console_Port_Count = NUM_DEVS;
90 -console_data  Console_Port_Data[NUM_DEVS];
91 -
92 -/* rtems console uses the following minor number */
93 -rtems_device_minor_number  Console_Port_Minor = 0;
94 -
95 -/* Pointers to functions for handling the UART. */
96 -console_fns uart_fns = 
97 -{ 
98 -    libchip_serial_default_probe,
99 -    uart_first_open,
100 -    uart_last_close,
101 -    uart_read,
102 -    uart_write,
103 -    uart_init,
104 -    uart_write_polled,   /* not used in this driver */
105 -    uart_set_attributes,
106 -    FALSE      /* TRUE if interrupt driven, FALSE if not. */
107 +
108 +/* TERMIOS callbacks */
109 +#if defined(USE_INTERRUPTS)
110 +rtems_termios_callbacks imx_uart_cbacks = {
111 +    .firstOpen            = imx_uart_first_open,
112 +    .lastClose            = imx_uart_last_close,
113 +    .pollRead             = NULL,
114 +    .write                = imx_uart_intr_write,
115 +    .setAttributes        = imx_uart_set_attrs,
116 +    .stopRemoteTx         = NULL,
117 +    .startRemoteTx        = NULL,
118 +    .outputUsesInterrupts = 1,
119 +};
120 +#else
121 +rtems_termios_callbacks imx_uart_cbacks = {
122 +    .firstOpen            = imx_uart_first_open,
123 +    .lastClose            = imx_uart_last_close,
124 +    .pollRead             = imx_uart_poll_read,
125 +    .write                = imx_uart_poll_write,
126 +    .setAttributes        = imx_uart_set_attrs,
127 +    .stopRemoteTx         = NULL,
128 +    .startRemoteTx        = NULL,
129 +    .outputUsesInterrupts = 0,
130  };
131 +#endif
132  
133 -/* 
134 - * There's one item in array for each UART.
135 - *
136 - * Some of these fields are marked "NOT USED". They are not used
137 - * by console.c, but may be used by drivers in libchip
138 - *
139 - */
140 -console_tbl Console_Port_Tbl[] = {
141 -    {
142 -        "/dev/com0",                      /* sDeviceName */
143 -        SERIAL_CUSTOM,                    /* deviceType */
144 -        &uart_fns,                        /* pDeviceFns */
145 -        NULL,                             /* deviceProbe */
146 -        NULL,                             /* pDeviceFlow */
147 -        0,                                /* ulMargin - NOT USED */
148 -        0,                                /* ulHysteresis - NOT USED */
149 -        NULL,                             /* pDeviceParams */
150 -        0,                                /* ulCtrlPort1  - NOT USED */
151 -        0,                                /* ulCtrlPort2  - NOT USED */
152 -        0,                                /* ulDataPort  - NOT USED */
153 -        NULL,                             /* getRegister - NOT USED */
154 -        NULL,                             /* setRegister - NOT USED */
155 -        NULL,                             /* getData - NOT USED */
156 -        NULL,                             /* setData - NOT USED */
157 -        0,                                /* ulClock - NOT USED */
158 -        0                                 /* ulIntVector - NOT USED */
159 -    },
160 -    {
161 -        "/dev/com1",                      /* sDeviceName */
162 -        SERIAL_CUSTOM,                    /* deviceType */
163 -        &uart_fns,                        /* pDeviceFns */
164 -        NULL,                             /* deviceProbe */
165 -        NULL,                             /* pDeviceFlow */
166 -        0,                                /* ulMargin - NOT USED */
167 -        0,                                /* ulHysteresis - NOT USED */
168 -        NULL,                             /* pDeviceParams */
169 -        0,                                /* ulCtrlPort1  - NOT USED */
170 -        0,                                /* ulCtrlPort2  - NOT USED */
171 -        0,                                /* ulDataPort  - NOT USED */
172 -        NULL,                             /* getRegister - NOT USED */
173 -        NULL,                             /* setRegister - NOT USED */
174 -        NULL,                             /* getData - NOT USED */
175 -        NULL,                             /* setData - NOT USED */
176 -        0,                                /* ulClock - NOT USED */
177 -        0                                 /* ulIntVector - NOT USED */
178 +#if defined(USE_INTERRUPTS)
179 +static rtems_irq_connect_data imx_uart_tx_isr_data[NUM_DEVS];
180 +static rtems_irq_connect_data imx_uart_rx_isr_data[NUM_DEVS];
181 +#endif
182 +
183 +typedef struct {
184 +    int minor;
185 +    mc9328mxl_uart_regs_t * regs;
186 +    volatile const char *buf;
187 +    volatile int len;
188 +    volatile int idx;
189 +    void *tty;
190 +} imx_uart_data_t;
191 +
192 +static imx_uart_data_t imx_uart_data[NUM_DEVS];
193 +
194 +rtems_device_driver console_initialize(
195 +    rtems_device_major_number  major,
196 +    rtems_device_minor_number  minor,
197 +    void                      *arg
198 +)
199 +{
200 +    rtems_status_code status;
201 +    int i;
202 +
203 +    for (i = 0; i < NUM_DEVS; i++) {
204 +        imx_uart_init(i);
205      }
206 -};
207  
208 -/*********************************************************************/
209 -/* Functions called via termios callbacks (i.e. the ones in uart_fns */
210 -/*********************************************************************/
211 -
212 -/* 
213 - * This is called the first time each device is opened. If the driver 
214 - * is interrupt driven, you should enable interrupts here. Otherwise, 
215 - * it's probably safe to do nothing.
216 - *
217 - * Since micromonitor already set up the UART, we do nothing.
218 - */
219 -static int uart_first_open(int major, int minor, void *arg) 
220 +    rtems_termios_initialize();
221 +
222 +    /* /dev/console and /dev/tty0 are the same */
223 +    status = rtems_io_register_name("/dev/console", major, 0);
224 +    if (status != RTEMS_SUCCESSFUL) {
225 +        rtems_panic("%s:%d Error registering /dev/console :: %d\n",
226 +                    __FUNCTION__, __LINE__, status);
227 +    }
228 +
229 +    status = rtems_io_register_name("/dev/tty0", major, 0);
230 +    if (status != RTEMS_SUCCESSFUL) {
231 +        rtems_panic("%s:%d Error registering /dev/tty0 :: %d\n",
232 +                    __FUNCTION__, __LINE__, status);
233 +    }
234 +
235 +    status = rtems_io_register_name("/dev/tty1", major, 1);
236 +    if (status != RTEMS_SUCCESSFUL) {
237 +        rtems_panic("%s:%d Error registering /dev/tty1 :: %d\n",
238 +                    __FUNCTION__, __LINE__, status);
239 +    }
240 +    return RTEMS_SUCCESSFUL;
241 +}
242 +
243 +rtems_device_driver console_open(
244 +    rtems_device_major_number major,
245 +    rtems_device_minor_number minor,
246 +    void                    * arg
247 +)
248  {
249 -    return 0;
250 +    rtems_status_code rc;
251 +
252 +    if (minor > (NUM_DEVS - 1)) {
253 +        return RTEMS_INVALID_NUMBER;
254 +    }
255 +
256 +    rc = rtems_termios_open(major, minor, arg, &imx_uart_cbacks);
257 +
258 +    return rc;
259  }
260  
261 +rtems_device_driver console_close(
262 +    rtems_device_major_number major,
263 +    rtems_device_minor_number minor,
264 +    void                    * arg
265 +)
266 +{
267 +    return rtems_termios_close(arg);
268 +}
269  
270 -/* 
271 - * This is called the last time each device is closed. If the driver 
272 - * is interrupt driven, you should disable interrupts here. Otherwise, 
273 - * it's probably safe to do nothing.
274 - */
275 -static int uart_last_close(int major, int minor, void *arg) 
276 +rtems_device_driver console_read(
277 +    rtems_device_major_number major,
278 +    rtems_device_minor_number minor,
279 +    void                    * arg
280 +)
281  {
282 -    return 0;
283 +  return rtems_termios_read(arg);
284  }
285  
286 +rtems_device_driver console_write(
287 +    rtems_device_major_number major,
288 +    rtems_device_minor_number minor,
289 +    void                    * arg
290 +)
291 +{
292 +  return rtems_termios_write(arg);
293 +}
294  
295 -/*
296 - * Read one character from UART.
297 - *
298 - * Return -1 if there's no data, otherwise return
299 - * the character in lowest 8 bits of returned int.
300 - */
301 -static int uart_read(int minor) 
302 +rtems_device_driver console_control(
303 +    rtems_device_major_number major,
304 +    rtems_device_minor_number minor,
305 +    void                    * arg
306 +)
307  {
308 -    char c;
309 +  return rtems_termios_ioctl(arg);
310 +}
311 +
312 +static void imx_uart_init(int minor)
313 +{
314 +    imx_uart_data[minor].minor = minor;
315 +    imx_uart_data[minor].buf   = NULL;
316 +    imx_uart_data[minor].len   = 0;
317 +    imx_uart_data[minor].idx   = 0;
318  
319      if (minor == 0) {
320 -        if (MC9328MXL_UART1_SR2 & MC9328MXL_UART_SR2_RDR) {
321 -            c = MC9328MXL_UART1_RXD & MC9328MXL_UART_RXD_CHARMASK;
322 -            return c;
323 -        } else {
324 -            return -1;
325 -        }
326 +#if defined(USE_INTERRUPTS)
327 +        imx_uart_tx_isr_data[minor].name = BSP_INT_UART1_TX;
328 +        imx_uart_rx_isr_data[minor].name = BSP_INT_UART1_RX;
329 +#endif
330 +        imx_uart_data[minor].regs =
331 +            (mc9328mxl_uart_regs_t *) MC9328MXL_UART1_BASE;
332      } else if (minor == 1) {
333 -        if (MC9328MXL_UART2_SR2 & MC9328MXL_UART_SR2_RDR) {
334 -            c = MC9328MXL_UART2_RXD & MC9328MXL_UART_RXD_CHARMASK;
335 -            return c;
336 -        } else {
337 -            return -1;
338 -        }
339 +#if defined(USE_INTERRUPTS)
340 +        imx_uart_tx_isr_data[minor].name = BSP_INT_UART2_TX;
341 +        imx_uart_rx_isr_data[minor].name = BSP_INT_UART2_RX;
342 +#endif
343 +        imx_uart_data[minor].regs =
344 +            (mc9328mxl_uart_regs_t *) MC9328MXL_UART2_BASE;
345      } else {
346 -        printk("Unknown console minor number: %d\n", minor);
347 -        return -1;
348 +        rtems_panic("%s:%d Unknown UART minor number %d\n",
349 +                    __FUNCTION__, __LINE__, minor);
350      }
351  
352 +#if defined(USE_INTERRUPTS)
353 +    imx_uart_tx_isr_data[minor].hdl    = imx_uart_tx_isr;
354 +    imx_uart_tx_isr_data[minor].handle = &imx_uart_data[minor];
355 +    imx_uart_tx_isr_data[minor].on     = imx_uart_isr_on;
356 +    imx_uart_tx_isr_data[minor].off    = imx_uart_isr_off;
357 +    imx_uart_tx_isr_data[minor].isOn   = imx_uart_isr_is_on;
358 +
359 +    imx_uart_rx_isr_data[minor].hdl    = imx_uart_rx_isr;
360 +    imx_uart_rx_isr_data[minor].handle = &imx_uart_data[minor];
361 +    imx_uart_rx_isr_data[minor].on     = imx_uart_isr_on;
362 +    imx_uart_rx_isr_data[minor].off    = imx_uart_isr_off;
363 +    imx_uart_rx_isr_data[minor].isOn   = imx_uart_isr_is_on;
364 +#endif
365 +
366 +    imx_uart_data[minor].regs->cr1 = (
367 +        MC9328MXL_UART_CR1_UARTCLKEN |
368 +        MC9328MXL_UART_CR1_UARTEN);
369 +
370 +    imx_uart_data[minor].regs->cr2 = (
371 +        MC9328MXL_UART_CR2_IRTS |
372 +        MC9328MXL_UART_CR2_WS   |
373 +        MC9328MXL_UART_CR2_TXEN |
374 +        MC9328MXL_UART_CR2_RXEN |
375 +        MC9328MXL_UART_CR2_SRST);
376 +
377 +    imx_uart_data[minor].regs->cr3 = 0;
378 +
379 +    imx_uart_data[minor].regs->cr4 = 0;
380 +
381 +    imx_uart_data[minor].regs->fcr = (
382 +        MC9328MXL_UART_FCR_TXTL(32) |
383 +        MC9328MXL_UART_FCR_RFDIV_1 |
384 +        MC9328MXL_UART_FCR_RXTL(1));
385 +
386 +    imx_uart_set_baud(minor, 38400);
387 +
388  }
389  
390 +static int imx_uart_first_open(int major, int minor, void *arg)
391 +{
392 +    rtems_libio_open_close_args_t *args = arg;
393  
394 -/* 
395 - * Write buffer to UART 
396 - *
397 - * return 1 on success, -1 on error
398 - */
399 -static int uart_write(int minor, const char *buf, int len)
400 +    imx_uart_data[minor].tty   = args->iop->data1;
401 +
402 +#if defined(USE_INTERRUPTS)
403 +    BSP_install_rtems_irq_handler(&imx_uart_tx_isr_data[minor]);
404 +    BSP_install_rtems_irq_handler(&imx_uart_rx_isr_data[minor]);
405 +
406 +    imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_RRDYEN;
407 +#endif
408 +
409 +    return 0;
410 +}
411 +
412 +static int imx_uart_last_close(int major, int minor, void *arg)
413  {
414 -    int i;
415 +#if defined(USE_INTERRUPTS)
416 +    BSP_remove_rtems_irq_handler(&imx_uart_tx_isr_data[minor]);
417 +    BSP_remove_rtems_irq_handler(&imx_uart_rx_isr_data[minor]);
418 +#endif
419  
420 -    if (minor == 0) {
421 -        for (i = 0; i < len; i++) {
422 -            /* Wait for fifo to have room */
423 -            while(!(MC9328MXL_UART1_SR2 & MC9328MXL_UART_SR2_TXDC)) {
424 -                continue;
425 -            }
426 -            
427 -            MC9328MXL_UART1_TXD = (char) buf[i];
428 -        }
429 -    } else if (minor == 1) {
430 -        for (i = 0; i < len; i++) {
431 -            /* Wait for fifo to have room */
432 -            while(!(MC9328MXL_UART2_SR2 & MC9328MXL_UART_SR2_TXDC)) {
433 -                continue;
434 -            }
435 -            
436 -            MC9328MXL_UART2_TXD = (char) buf[i];
437 -        }
438 +    return 0;
439 +}
440 +
441 +static int imx_uart_poll_read(int minor)
442 +{
443 +    if (imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_RDR) {
444 +        return imx_uart_data[minor].regs->rxd & 0xff;
445      } else {
446 -        printk("Unknown console minor number: %d\n", minor);
447          return -1;
448      }
449 -    
450 -    return 1;
451  }
452  
453  
454 -/* Set up the UART. */
455 -static void uart_init(int minor)
456 +static int imx_uart_poll_write(int minor, const char *buf, int len)
457  {
458 -        /* leave the debug sio port as setup by umon */
459 +    int i;
460 +    for (i = 0; i < len; i++) {
461 +        /* Wait for there to be room in the fifo */
462 +        while (!(imx_uart_data[minor].regs->sr2 & MC9328MXL_UART_SR2_TXDC)) {
463 +            continue;
464 +        }
465 +
466 +        imx_uart_data[minor].regs->txd = buf[i];
467 +    }
468 +    return 1;
469 +
470  }
471  
472 -/* I'm not sure this is needed for the shared console driver. */
473 -static void    uart_write_polled(int minor, char c)
474 +#if defined(USE_INTERRUPTS)
475 +static int imx_uart_intr_write(int minor, const char *buf, int len)
476  {
477 -    uart_write(minor, &c, 1);
478 +    imx_uart_data[minor].buf = buf;
479 +    imx_uart_data[minor].len = len;
480 +    imx_uart_data[minor].idx = 0;
481 +
482 +    imx_uart_data[minor].regs->cr1 |= MC9328MXL_UART_CR1_TXMPTYEN;
483 +
484 +    return 1;
485  }
486 +#endif
487 +
488  
489  /* This is for setting baud rate, bits, etc. */
490 -static int     uart_set_attributes(int minor, const struct termios *t) 
491 +static int imx_uart_set_attrs(int minor, const struct termios *t)
492  {
493 +    int baud;
494 +
495 +    baud = termios_baud_to_number(t->c_cflag & CBAUD);
496 +    imx_uart_set_baud(minor, baud);
497 +
498      return 0;
499  }
500  
501 -/***********************************************************************/
502 +#if defined(USE_INTERRUPTS)
503 +static void imx_uart_isr_on(const rtems_irq_connect_data *irq)
504 +{
505 +    MC9328MXL_AITC_INTENNUM = irq->name;
506 +}
507 +static void imx_uart_isr_off(const rtems_irq_connect_data *irq)
508 +{
509 +    MC9328MXL_AITC_INTDISNUM = irq->name;
510 +}
511 +static int imx_uart_isr_is_on(const rtems_irq_connect_data *irq)
512 +{
513 +    int irq_num = (int)irq->name;
514 +    if (irq_num < 32) {
515 +        return MC9328MXL_AITC_INTENABLEL & (1 << irq_num);
516 +    } else {
517 +        return MC9328MXL_AITC_INTENABLEH & (1 << (irq_num - 32));
518 +    }
519 +}
520 +
521 +static void imx_uart_rx_isr(rtems_irq_hdl_param param)
522 +{
523 +    imx_uart_data_t *uart_data = param;
524 +    char buf[32];
525 +    int i=0;
526 +
527 +    while (uart_data->regs->sr2 & MC9328MXL_UART_SR2_RDR) {
528 +        buf[i] = uart_data->regs->rxd & 0xff;
529 +        i++;
530 +    }
531 +
532 +    rtems_termios_enqueue_raw_characters(uart_data->tty, buf, i);
533 +}
534 +
535 +static void imx_uart_tx_isr(rtems_irq_hdl_param param)
536 +{
537 +    imx_uart_data_t *uart_data = param;
538 +    int len;
539 +    int minor = uart_data->minor;
540 +
541 +
542 +    if (uart_data->idx < uart_data->len) {
543 +        while ( (uart_data->regs->sr1 & MC9328MXL_UART_SR1_TRDY) &&
544 +                (uart_data->idx < uart_data->len)) {
545 +            uart_data->regs->txd = uart_data->buf[uart_data->idx];
546 +            uart_data->idx++;
547 +        }
548 +    } else {
549 +        len = uart_data->len;
550 +        uart_data->len = 0;
551 +        imx_uart_data[minor].regs->cr1 &= ~MC9328MXL_UART_CR1_TXMPTYEN;
552 +        rtems_termios_dequeue_characters(uart_data->tty, len);
553 +    }
554 +}
555 +#endif
556 +
557  /*
558 - * The following functions are not used by TERMIOS, but other RTEMS
559 - * functions use them instead.
560 + * Set the UART's baud rate. The calculation is:
561 + *   (baud * 16) / ref_freq  = num/demom
562 + *
563 + *   ref_freq = perclk1 / RFDIV[2:0]
564 + *   BIR = num - 1
565 + *   BMR = demom - 1
566 + *
567 + * Setting 'num' to 16 yields this equation:
568 + *    demom = ref_freq / baud
569   */
570 -/***********************************************************************/
571 -/* 
572 - * Read from UART. This is used in the exit code, and can't
573 - * rely on interrupts.
574 -*/
575 -int uart_poll_read(int minor)
576 +static void imx_uart_set_baud(int minor, int baud)
577  {
578 -    return uart_read(minor);
579 +    unsigned int perclk1;
580 +    unsigned int denom;
581 +    unsigned int ref_freq = 0;
582 +    uint32_t fcr;
583 +
584 +    perclk1 = get_perclk1_freq();
585 +    fcr = imx_uart_data[minor].regs->fcr;
586 +
587 +    switch(fcr & MC9328MXL_UART_FCR_RFDIV_MASK) {
588 +    case MC9328MXL_UART_FCR_RFDIV_1:  ref_freq = perclk1/1; break;
589 +    case MC9328MXL_UART_FCR_RFDIV_2:  ref_freq = perclk1/2; break;
590 +    case MC9328MXL_UART_FCR_RFDIV_3:  ref_freq = perclk1/3; break;
591 +    case MC9328MXL_UART_FCR_RFDIV_4:  ref_freq = perclk1/4; break;
592 +    case MC9328MXL_UART_FCR_RFDIV_5:  ref_freq = perclk1/5; break;
593 +    case MC9328MXL_UART_FCR_RFDIV_6:  ref_freq = perclk1/6; break;
594 +    case MC9328MXL_UART_FCR_RFDIV_7:  ref_freq = perclk1/7; break;
595 +    default:
596 +        rtems_panic("%s:%d Unknown RFDIV: 0x%x",
597 +                    __FUNCTION__, __LINE__,
598 +                    fcr & MC9328MXL_UART_FCR_RFDIV_MASK);
599 +        break;
600 +    }
601 +
602 +    denom = ref_freq / baud;
603 +
604 +    imx_uart_data[minor].regs->bir = 0xf;
605 +    imx_uart_data[minor].regs->bmr = denom;
606  }
607  
608  
609  /*
610 - * Write a character to the console. This is used by printk() and 
611 - * maybe other low level functions. It should not use interrupts or any
612 - * RTEMS system calls. It needs to be very simple
613 + * Polled, non-blocking read from UART
614 + */
615 +int imx_uart_poll_read_char(int minor)
616 +{
617 +    return imx_uart_poll_read(minor);
618 +}
619 +
620 +/*
621 + * Polled, blocking write from UART
622   */
623 -static void _BSP_put_char( char c ) {
624 -    uart_write_polled(0, c);
625 +void  imx_uart_poll_write_char(int minor, char c)
626 +{
627 +    imx_uart_poll_write(minor, &c, 1);
628 +}
629 +
630 +/*
631 + * Functions for printk() and friends.
632 + */
633 +void _BSP_output_char(char c)
634 +{
635 +    poll_write(c);
636      if (c == '\n') {
637 -        uart_write_polled(0, '\r');
638 +        poll_write('\r');
639      }
640  }
641 +BSP_output_char_function_type BSP_output_char = _BSP_output_char;
642  
643 -BSP_output_char_function_type BSP_output_char = _BSP_put_char;
644  
645 +char _BSP_poll_char()
646 +{
647 +    return poll_read();
648 +}
649 +BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;
650  
651  
652 Index: rtems/c/src/lib/libbsp/arm/csb336/Makefile.am
653 ===================================================================
654 --- rtems.orig/c/src/lib/libbsp/arm/csb336/Makefile.am
655 +++ rtems/c/src/lib/libbsp/arm/csb336/Makefile.am
656 @@ -35,7 +35,7 @@ startup_rel_CPPFLAGS = $(AM_CPPFLAGS)
657  startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
658  
659  noinst_PROGRAMS += console.rel
660 -console_rel_SOURCES = console/uart.c ../../shared/console.c
661 +console_rel_SOURCES = console/uart.c
662  console_rel_CPPFLAGS = $(AM_CPPFLAGS)
663  console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
664