2
* Exynos4210 UART Emulation
4
* Copyright (C) 2011 Samsung Electronics Co Ltd.
5
* Maksim Kozlov, <m.kozlov@samsung.com>
7
* This program is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the
9
* Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17
* You should have received a copy of the GNU General Public License along
18
* with this program; if not, see <http://www.gnu.org/licenses/>.
22
#include "qemu/osdep.h"
24
#include "migration/vmstate.h"
25
#include "qapi/error.h"
26
#include "qemu/error-report.h"
27
#include "qemu/module.h"
28
#include "qemu/timer.h"
29
#include "chardev/char-fe.h"
30
#include "chardev/char-serial.h"
32
#include "hw/arm/exynos4210.h"
34
#include "hw/qdev-properties.h"
35
#include "hw/qdev-properties-system.h"
38
#include "qom/object.h"
41
* Offsets for UART registers relative to SFR base address
45
#define ULCON 0x0000 /* Line Control */
46
#define UCON 0x0004 /* Control */
47
#define UFCON 0x0008 /* FIFO Control */
48
#define UMCON 0x000C /* Modem Control */
49
#define UTRSTAT 0x0010 /* Tx/Rx Status */
50
#define UERSTAT 0x0014 /* UART Error Status */
51
#define UFSTAT 0x0018 /* FIFO Status */
52
#define UMSTAT 0x001C /* Modem Status */
53
#define UTXH 0x0020 /* Transmit Buffer */
54
#define URXH 0x0024 /* Receive Buffer */
55
#define UBRDIV 0x0028 /* Baud Rate Divisor */
56
#define UFRACVAL 0x002C /* Divisor Fractional Value */
57
#define UINTP 0x0030 /* Interrupt Pending */
58
#define UINTSP 0x0034 /* Interrupt Source Pending */
59
#define UINTM 0x0038 /* Interrupt Mask */
62
* for indexing register in the uint32_t array
64
* 'reg' - register offset (see offsets definitions above)
67
#define I_(reg) (reg / sizeof(uint32_t))
69
typedef struct Exynos4210UartReg {
70
const char *name; /* the only reason is the debug output */
75
static const Exynos4210UartReg exynos4210_uart_regs[] = {
76
{"ULCON", ULCON, 0x00000000},
77
{"UCON", UCON, 0x00003000},
78
{"UFCON", UFCON, 0x00000000},
79
{"UMCON", UMCON, 0x00000000},
80
{"UTRSTAT", UTRSTAT, 0x00000006}, /* RO */
81
{"UERSTAT", UERSTAT, 0x00000000}, /* RO */
82
{"UFSTAT", UFSTAT, 0x00000000}, /* RO */
83
{"UMSTAT", UMSTAT, 0x00000000}, /* RO */
84
{"UTXH", UTXH, 0x5c5c5c5c}, /* WO, undefined reset value*/
85
{"URXH", URXH, 0x00000000}, /* RO */
86
{"UBRDIV", UBRDIV, 0x00000000},
87
{"UFRACVAL", UFRACVAL, 0x00000000},
88
{"UINTP", UINTP, 0x00000000},
89
{"UINTSP", UINTSP, 0x00000000},
90
{"UINTM", UINTM, 0x00000000},
93
#define EXYNOS4210_UART_REGS_MEM_SIZE 0x3C
95
/* UART FIFO Control */
96
#define UFCON_FIFO_ENABLE 0x1
97
#define UFCON_Rx_FIFO_RESET 0x2
98
#define UFCON_Tx_FIFO_RESET 0x4
99
#define UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT 8
100
#define UFCON_Tx_FIFO_TRIGGER_LEVEL (7 << UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT)
101
#define UFCON_Rx_FIFO_TRIGGER_LEVEL_SHIFT 4
102
#define UFCON_Rx_FIFO_TRIGGER_LEVEL (7 << UFCON_Rx_FIFO_TRIGGER_LEVEL_SHIFT)
104
/* Uart FIFO Status */
105
#define UFSTAT_Rx_FIFO_COUNT 0xff
106
#define UFSTAT_Rx_FIFO_FULL 0x100
107
#define UFSTAT_Rx_FIFO_ERROR 0x200
108
#define UFSTAT_Tx_FIFO_COUNT_SHIFT 16
109
#define UFSTAT_Tx_FIFO_COUNT (0xff << UFSTAT_Tx_FIFO_COUNT_SHIFT)
110
#define UFSTAT_Tx_FIFO_FULL_SHIFT 24
111
#define UFSTAT_Tx_FIFO_FULL (1 << UFSTAT_Tx_FIFO_FULL_SHIFT)
113
/* UART Interrupt Source Pending */
114
#define UINTSP_RXD 0x1 /* Receive interrupt */
115
#define UINTSP_ERROR 0x2 /* Error interrupt */
116
#define UINTSP_TXD 0x4 /* Transmit interrupt */
117
#define UINTSP_MODEM 0x8 /* Modem interrupt */
119
/* UART Line Control */
120
#define ULCON_IR_MODE_SHIFT 6
121
#define ULCON_PARITY_SHIFT 3
122
#define ULCON_STOP_BIT_SHIFT 1
124
/* UART Tx/Rx Status */
125
#define UTRSTAT_Rx_TIMEOUT 0x8
126
#define UTRSTAT_TRANSMITTER_EMPTY 0x4
127
#define UTRSTAT_Tx_BUFFER_EMPTY 0x2
128
#define UTRSTAT_Rx_BUFFER_DATA_READY 0x1
130
/* UART Error Status */
131
#define UERSTAT_OVERRUN 0x1
132
#define UERSTAT_PARITY 0x2
133
#define UERSTAT_FRAME 0x4
134
#define UERSTAT_BREAK 0x8
138
uint32_t sp, rp; /* store and retrieve pointers */
142
#define TYPE_EXYNOS4210_UART "exynos4210.uart"
143
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210UartState, EXYNOS4210_UART)
145
struct Exynos4210UartState {
146
SysBusDevice parent_obj;
150
uint32_t reg[EXYNOS4210_UART_REGS_MEM_SIZE / sizeof(uint32_t)];
151
Exynos4210UartFIFO rx;
152
Exynos4210UartFIFO tx;
154
QEMUTimer *fifo_timeout_timer;
155
uint64_t wordtime; /* word time in ns */
166
/* Used only for tracing */
167
static const char *exynos4210_uart_regname(hwaddr offset)
172
for (i = 0; i < ARRAY_SIZE(exynos4210_uart_regs); i++) {
173
if (offset == exynos4210_uart_regs[i].offset) {
174
return exynos4210_uart_regs[i].name;
182
static void fifo_store(Exynos4210UartFIFO *q, uint8_t ch)
185
q->sp = (q->sp + 1) % q->size;
188
static uint8_t fifo_retrieve(Exynos4210UartFIFO *q)
190
uint8_t ret = q->data[q->rp];
191
q->rp = (q->rp + 1) % q->size;
195
static int fifo_elements_number(const Exynos4210UartFIFO *q)
198
return q->size - q->rp + q->sp;
201
return q->sp - q->rp;
204
static int fifo_empty_elements_number(const Exynos4210UartFIFO *q)
206
return q->size - fifo_elements_number(q);
209
static void fifo_reset(Exynos4210UartFIFO *q)
214
q->data = g_malloc0(q->size);
220
static uint32_t exynos4210_uart_FIFO_trigger_level(uint32_t channel,
239
trace_exynos_uart_channel_error(channel);
246
exynos4210_uart_Tx_FIFO_trigger_level(const Exynos4210UartState *s)
250
reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
251
UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
253
return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
257
exynos4210_uart_Rx_FIFO_trigger_level(const Exynos4210UartState *s)
261
reg = ((s->reg[I_(UFCON)] & UFCON_Rx_FIFO_TRIGGER_LEVEL) >>
262
UFCON_Rx_FIFO_TRIGGER_LEVEL_SHIFT) + 1;
264
return exynos4210_uart_FIFO_trigger_level(s->channel, reg);
268
* Update Rx DMA busy signal if Rx DMA is enabled. For simplicity,
269
* mark DMA as busy if DMA is enabled and the receive buffer is empty.
271
static void exynos4210_uart_update_dmabusy(Exynos4210UartState *s)
273
bool rx_dma_enabled = (s->reg[I_(UCON)] & 0x03) == 0x02;
274
uint32_t count = fifo_elements_number(&s->rx);
276
if (rx_dma_enabled && !count) {
277
qemu_irq_raise(s->dmairq);
278
trace_exynos_uart_dmabusy(s->channel);
280
qemu_irq_lower(s->dmairq);
281
trace_exynos_uart_dmaready(s->channel);
285
static void exynos4210_uart_update_irq(Exynos4210UartState *s)
288
* The Tx interrupt is always requested if the number of data in the
289
* transmit FIFO is smaller than the trigger level.
291
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
292
uint32_t count = (s->reg[I_(UFSTAT)] & UFSTAT_Tx_FIFO_COUNT) >>
293
UFSTAT_Tx_FIFO_COUNT_SHIFT;
295
if (count <= exynos4210_uart_Tx_FIFO_trigger_level(s)) {
296
s->reg[I_(UINTSP)] |= UINTSP_TXD;
300
* Rx interrupt if trigger level is reached or if rx timeout
301
* interrupt is disabled and there is data in the receive buffer
303
count = fifo_elements_number(&s->rx);
304
if ((count && !(s->reg[I_(UCON)] & 0x80)) ||
305
count >= exynos4210_uart_Rx_FIFO_trigger_level(s)) {
306
exynos4210_uart_update_dmabusy(s);
307
s->reg[I_(UINTSP)] |= UINTSP_RXD;
308
timer_del(s->fifo_timeout_timer);
310
} else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) {
311
exynos4210_uart_update_dmabusy(s);
312
s->reg[I_(UINTSP)] |= UINTSP_RXD;
315
s->reg[I_(UINTP)] = s->reg[I_(UINTSP)] & ~s->reg[I_(UINTM)];
317
if (s->reg[I_(UINTP)]) {
318
qemu_irq_raise(s->irq);
319
trace_exynos_uart_irq_raised(s->channel, s->reg[I_(UINTP)]);
321
qemu_irq_lower(s->irq);
322
trace_exynos_uart_irq_lowered(s->channel);
326
static void exynos4210_uart_timeout_int(void *opaque)
328
Exynos4210UartState *s = opaque;
330
trace_exynos_uart_rx_timeout(s->channel, s->reg[I_(UTRSTAT)],
333
if ((s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) ||
334
(s->reg[I_(UCON)] & (1 << 11))) {
335
s->reg[I_(UINTSP)] |= UINTSP_RXD;
336
s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT;
337
exynos4210_uart_update_dmabusy(s);
338
exynos4210_uart_update_irq(s);
342
static void exynos4210_uart_update_parameters(Exynos4210UartState *s)
344
int speed, parity, data_bits, stop_bits;
345
QEMUSerialSetParams ssp;
348
if (s->reg[I_(UBRDIV)] == 0) {
352
if (s->reg[I_(ULCON)] & 0x20) {
353
if (s->reg[I_(ULCON)] & 0x28) {
362
if (s->reg[I_(ULCON)] & 0x4) {
368
data_bits = (s->reg[I_(ULCON)] & 0x3) + 5;
370
uclk_rate = 24000000;
372
speed = uclk_rate / ((16 * (s->reg[I_(UBRDIV)]) & 0xffff) +
373
(s->reg[I_(UFRACVAL)] & 0x7) + 16);
377
ssp.data_bits = data_bits;
378
ssp.stop_bits = stop_bits;
380
s->wordtime = NANOSECONDS_PER_SECOND * (data_bits + stop_bits + 1) / speed;
382
qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
384
trace_exynos_uart_update_params(
385
s->channel, speed, parity, data_bits, stop_bits, s->wordtime);
388
static void exynos4210_uart_rx_timeout_set(Exynos4210UartState *s)
390
if (s->reg[I_(UCON)] & 0x80) {
391
uint32_t timeout = ((s->reg[I_(UCON)] >> 12) & 0x0f) * s->wordtime;
393
timer_mod(s->fifo_timeout_timer,
394
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
396
timer_del(s->fifo_timeout_timer);
400
static void exynos4210_uart_write(void *opaque, hwaddr offset,
401
uint64_t val, unsigned size)
403
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
406
trace_exynos_uart_write(s->channel, offset,
407
exynos4210_uart_regname(offset), val);
413
s->reg[I_(offset)] = val;
414
exynos4210_uart_update_parameters(s);
417
s->reg[I_(UFCON)] = val;
418
if (val & UFCON_Rx_FIFO_RESET) {
420
s->reg[I_(UFCON)] &= ~UFCON_Rx_FIFO_RESET;
421
trace_exynos_uart_rx_fifo_reset(s->channel);
423
if (val & UFCON_Tx_FIFO_RESET) {
425
s->reg[I_(UFCON)] &= ~UFCON_Tx_FIFO_RESET;
426
trace_exynos_uart_tx_fifo_reset(s->channel);
431
if (qemu_chr_fe_backend_connected(&s->chr)) {
432
s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY |
433
UTRSTAT_Tx_BUFFER_EMPTY);
435
/* XXX this blocks entire thread. Rewrite to use
436
* qemu_chr_fe_write and background I/O callbacks */
437
qemu_chr_fe_write_all(&s->chr, &ch, 1);
438
trace_exynos_uart_tx(s->channel, ch);
439
s->reg[I_(UTRSTAT)] |= UTRSTAT_TRANSMITTER_EMPTY |
440
UTRSTAT_Tx_BUFFER_EMPTY;
441
s->reg[I_(UINTSP)] |= UINTSP_TXD;
442
exynos4210_uart_update_irq(s);
447
s->reg[I_(UINTP)] &= ~val;
448
s->reg[I_(UINTSP)] &= ~val;
449
trace_exynos_uart_intclr(s->channel, s->reg[I_(UINTP)]);
450
exynos4210_uart_update_irq(s);
453
if (val & UTRSTAT_Rx_TIMEOUT) {
454
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_TIMEOUT;
461
trace_exynos_uart_ro_write(
462
s->channel, exynos4210_uart_regname(offset), offset);
465
s->reg[I_(UINTSP)] &= ~val;
468
s->reg[I_(UINTM)] = val;
469
exynos4210_uart_update_irq(s);
474
s->reg[I_(offset)] = val;
479
static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
482
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
486
case UERSTAT: /* Read Only */
487
res = s->reg[I_(UERSTAT)];
488
s->reg[I_(UERSTAT)] = 0;
489
trace_exynos_uart_read(s->channel, offset,
490
exynos4210_uart_regname(offset), res);
492
case UFSTAT: /* Read Only */
493
s->reg[I_(UFSTAT)] = fifo_elements_number(&s->rx) & 0xff;
494
if (fifo_empty_elements_number(&s->rx) == 0) {
495
s->reg[I_(UFSTAT)] |= UFSTAT_Rx_FIFO_FULL;
496
s->reg[I_(UFSTAT)] &= ~0xff;
498
trace_exynos_uart_read(s->channel, offset,
499
exynos4210_uart_regname(offset),
501
return s->reg[I_(UFSTAT)];
503
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
504
if (fifo_elements_number(&s->rx)) {
505
res = fifo_retrieve(&s->rx);
506
trace_exynos_uart_rx(s->channel, res);
507
if (!fifo_elements_number(&s->rx)) {
508
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
510
s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
513
trace_exynos_uart_rx_error(s->channel);
514
s->reg[I_(UINTSP)] |= UINTSP_ERROR;
515
exynos4210_uart_update_irq(s);
519
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
520
res = s->reg[I_(URXH)];
522
qemu_chr_fe_accept_input(&s->chr);
523
exynos4210_uart_update_dmabusy(s);
524
trace_exynos_uart_read(s->channel, offset,
525
exynos4210_uart_regname(offset), res);
528
trace_exynos_uart_wo_read(s->channel, exynos4210_uart_regname(offset),
532
trace_exynos_uart_read(s->channel, offset,
533
exynos4210_uart_regname(offset),
535
return s->reg[I_(offset)];
538
trace_exynos_uart_read(s->channel, offset, exynos4210_uart_regname(offset),
543
static const MemoryRegionOps exynos4210_uart_ops = {
544
.read = exynos4210_uart_read,
545
.write = exynos4210_uart_write,
546
.endianness = DEVICE_NATIVE_ENDIAN,
548
.max_access_size = 4,
553
static int exynos4210_uart_can_receive(void *opaque)
555
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
557
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
558
return fifo_empty_elements_number(&s->rx);
560
return !(s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY);
564
static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size)
566
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
569
if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
570
if (fifo_empty_elements_number(&s->rx) < size) {
571
size = fifo_empty_elements_number(&s->rx);
572
s->reg[I_(UINTSP)] |= UINTSP_ERROR;
574
for (i = 0; i < size; i++) {
575
fifo_store(&s->rx, buf[i]);
577
exynos4210_uart_rx_timeout_set(s);
579
s->reg[I_(URXH)] = buf[0];
581
s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY;
583
exynos4210_uart_update_irq(s);
587
static void exynos4210_uart_event(void *opaque, QEMUChrEvent event)
589
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
591
if (event == CHR_EVENT_BREAK) {
592
/* When the RxDn is held in logic 0, then a null byte is pushed into the
594
fifo_store(&s->rx, '\0');
595
s->reg[I_(UERSTAT)] |= UERSTAT_BREAK;
596
exynos4210_uart_update_irq(s);
601
static void exynos4210_uart_reset(DeviceState *dev)
603
Exynos4210UartState *s = EXYNOS4210_UART(dev);
606
for (i = 0; i < ARRAY_SIZE(exynos4210_uart_regs); i++) {
607
s->reg[I_(exynos4210_uart_regs[i].offset)] =
608
exynos4210_uart_regs[i].reset_value;
614
trace_exynos_uart_rxsize(s->channel, s->rx.size);
617
static int exynos4210_uart_post_load(void *opaque, int version_id)
619
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
621
exynos4210_uart_update_parameters(s);
622
exynos4210_uart_rx_timeout_set(s);
627
static const VMStateDescription vmstate_exynos4210_uart_fifo = {
628
.name = "exynos4210.uart.fifo",
630
.minimum_version_id = 1,
631
.fields = (const VMStateField[]) {
632
VMSTATE_UINT32(sp, Exynos4210UartFIFO),
633
VMSTATE_UINT32(rp, Exynos4210UartFIFO),
634
VMSTATE_VBUFFER_UINT32(data, Exynos4210UartFIFO, 1, NULL, size),
635
VMSTATE_END_OF_LIST()
639
static const VMStateDescription vmstate_exynos4210_uart = {
640
.name = "exynos4210.uart",
642
.minimum_version_id = 1,
643
.post_load = exynos4210_uart_post_load,
644
.fields = (const VMStateField[]) {
645
VMSTATE_STRUCT(rx, Exynos4210UartState, 1,
646
vmstate_exynos4210_uart_fifo, Exynos4210UartFIFO),
647
VMSTATE_UINT32_ARRAY(reg, Exynos4210UartState,
648
EXYNOS4210_UART_REGS_MEM_SIZE / sizeof(uint32_t)),
649
VMSTATE_END_OF_LIST()
653
DeviceState *exynos4210_uart_create(hwaddr addr,
662
dev = qdev_new(TYPE_EXYNOS4210_UART);
664
qdev_prop_set_chr(dev, "chardev", chr);
665
qdev_prop_set_uint32(dev, "channel", channel);
666
qdev_prop_set_uint32(dev, "rx-size", fifo_size);
667
qdev_prop_set_uint32(dev, "tx-size", fifo_size);
669
bus = SYS_BUS_DEVICE(dev);
670
sysbus_realize_and_unref(bus, &error_fatal);
671
if (addr != (hwaddr)-1) {
672
sysbus_mmio_map(bus, 0, addr);
674
sysbus_connect_irq(bus, 0, irq);
679
static void exynos4210_uart_init(Object *obj)
681
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
682
Exynos4210UartState *s = EXYNOS4210_UART(dev);
684
s->wordtime = NANOSECONDS_PER_SECOND * 10 / 9600;
687
memory_region_init_io(&s->iomem, obj, &exynos4210_uart_ops, s,
688
"exynos4210.uart", EXYNOS4210_UART_REGS_MEM_SIZE);
689
sysbus_init_mmio(dev, &s->iomem);
691
sysbus_init_irq(dev, &s->irq);
692
sysbus_init_irq(dev, &s->dmairq);
695
static void exynos4210_uart_realize(DeviceState *dev, Error **errp)
697
Exynos4210UartState *s = EXYNOS4210_UART(dev);
699
s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
700
exynos4210_uart_timeout_int, s);
702
qemu_chr_fe_set_handlers(&s->chr, exynos4210_uart_can_receive,
703
exynos4210_uart_receive, exynos4210_uart_event,
704
NULL, s, NULL, true);
707
static Property exynos4210_uart_properties[] = {
708
DEFINE_PROP_CHR("chardev", Exynos4210UartState, chr),
709
DEFINE_PROP_UINT32("channel", Exynos4210UartState, channel, 0),
710
DEFINE_PROP_UINT32("rx-size", Exynos4210UartState, rx.size, 16),
711
DEFINE_PROP_UINT32("tx-size", Exynos4210UartState, tx.size, 16),
712
DEFINE_PROP_END_OF_LIST(),
715
static void exynos4210_uart_class_init(ObjectClass *klass, void *data)
717
DeviceClass *dc = DEVICE_CLASS(klass);
719
dc->realize = exynos4210_uart_realize;
720
dc->reset = exynos4210_uart_reset;
721
device_class_set_props(dc, exynos4210_uart_properties);
722
dc->vmsd = &vmstate_exynos4210_uart;
725
static const TypeInfo exynos4210_uart_info = {
726
.name = TYPE_EXYNOS4210_UART,
727
.parent = TYPE_SYS_BUS_DEVICE,
728
.instance_size = sizeof(Exynos4210UartState),
729
.instance_init = exynos4210_uart_init,
730
.class_init = exynos4210_uart_class_init,
733
static void exynos4210_uart_register(void)
735
type_register_static(&exynos4210_uart_info);
738
type_init(exynos4210_uart_register)