1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "los_event.h"
17 #include "device_resource_if.h"
18 #include "hdf_base.h"
19 #include "hdf_log.h"
20 #include "osal_io.h"
21 #include "osal_mem.h"
22 #include "osal_time.h"
23 #include "platform_dumper.h"
24 #include "uart_core.h"
25 #include "uart_dev.h"
26 #include "uart_if.h"
27 #include "uart_pl011.h"
28
29 #define HDF_LOG_TAG uart_hi35xx
30
31 #define UART_DUMPER_NAME_PREFIX "uart_dumper_"
32 #define UART_DUMPER_NAME_LEN 64
33
UartDumperDump(struct UartPl011Port * port)34 static void UartDumperDump(struct UartPl011Port *port)
35 {
36 int32_t ret;
37 struct PlatformDumperData datas[] = {
38 {"UART_DR", PLATFORM_DUMPER_REGISTERL, (void *)port->physBase},
39 {"UART_RSR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_RSR)},
40 {"UART_FR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_FR)},
41 {"UART_IBRD", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_IBRD)},
42 {"UART_FBRD", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_FBRD)},
43 {"UART_LCR_H", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_LCR_H)},
44 {"UART_CR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_CR)},
45 {"UART_IFLS", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_IFLS)},
46 {"UART_IMSC", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_IMSC)},
47 {"UART_RIS", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_RIS)},
48 {"UART_MIS", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_MIS)},
49 {"UART_ICR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_ICR)},
50 {"UART_DMACR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_DMACR)},
51 };
52 if (port->dumper == NULL) {
53 HDF_LOGE("%s: uart dumper is NULL", __func__);
54 return;
55 }
56 ret = PlatformDumperAddDatas(port->dumper, datas, sizeof(datas) / sizeof(struct PlatformDumperData));
57 if (ret != HDF_SUCCESS) {
58 return;
59 }
60 (void)PlatformDumperDump(port->dumper);
61 (void)PlatformDumperClearDatas(port->dumper);
62 }
63
UartDumperCreate(struct UartPl011Port * port)64 static int32_t UartDumperCreate(struct UartPl011Port *port)
65 {
66 struct PlatformDumper *dumper = NULL;
67 char *name = NULL;
68
69 name = (char *)OsalMemCalloc(UART_DUMPER_NAME_LEN);
70 if (name == NULL) {
71 HDF_LOGE("%s: alloc name fail", __func__);
72 return HDF_ERR_MALLOC_FAIL;
73 }
74
75 if (snprintf_s(name, UART_DUMPER_NAME_LEN, UART_DUMPER_NAME_LEN - 1, "%s%d",
76 UART_DUMPER_NAME_PREFIX, port->udd->num) < 0) {
77 HDF_LOGE("%s: snprintf_s name fail!", __func__);
78 OsalMemFree(name);
79 return HDF_ERR_IO;
80 }
81
82 dumper = PlatformDumperCreate(name);
83 if (dumper == NULL) {
84 HDF_LOGE("%s: get dumper for %s fail!", __func__, name);
85 OsalMemFree(name);
86 return HDF_ERR_IO;
87 }
88
89 port->dumper = dumper;
90 port->dumperName = name;
91
92 return HDF_SUCCESS;
93 }
94
UartDumperDestroy(struct UartPl011Port * port)95 static inline void UartDumperDestroy(struct UartPl011Port *port)
96 {
97 PlatformDumperDestroy(port->dumper);
98 OsalMemFree(port->dumperName);
99 }
100
Hi35xxRead(struct UartHost * host,uint8_t * data,uint32_t size)101 static int32_t Hi35xxRead(struct UartHost *host, uint8_t *data, uint32_t size)
102 {
103 int32_t ret;
104 struct UartDriverData *udd = NULL;
105
106 if (host == NULL || host->priv == NULL) {
107 HDF_LOGE("%s: invalid parameter", __func__);
108 return HDF_ERR_INVALID_PARAM;
109 }
110 udd = (struct UartDriverData *)host->priv;
111 if (udd->state != UART_STATE_USEABLE) {
112 return HDF_FAILURE;
113 }
114 if ((udd->flags & UART_FLG_RD_BLOCK) && (PL011UartRxBufEmpty(udd))) {
115 (void)LOS_EventRead(&udd->wait.stEvent, 0x1, LOS_WAITMODE_OR, LOS_WAIT_FOREVER);
116 }
117 ret = Pl011Read(udd, (char *)data, size);
118 if ((udd->flags & UART_FLG_RD_BLOCK) && (PL011UartRxBufEmpty(udd))) {
119 (void)LOS_EventClear(&udd->wait.stEvent, ~(0x1));
120 }
121 return ret;
122 }
123
Hi35xxWrite(struct UartHost * host,uint8_t * data,uint32_t size)124 static int32_t Hi35xxWrite(struct UartHost *host, uint8_t *data, uint32_t size)
125 {
126 int32_t ret;
127 struct UartDriverData *udd = NULL;
128
129 if (host == NULL || host->priv == NULL) {
130 HDF_LOGE("%s: invalid parameter", __func__);
131 return HDF_ERR_INVALID_PARAM;
132 }
133 udd = (struct UartDriverData *)host->priv;
134 if (udd->state != UART_STATE_USEABLE) {
135 return HDF_FAILURE;
136 }
137 if (udd->ops->StartTx != NULL) {
138 ret = udd->ops->StartTx(udd, (char *)data, size);
139 } else {
140 ret = HDF_ERR_NOT_SUPPORT;
141 HDF_LOGE("%s: not support", __func__);
142 }
143 return ret;
144 }
145
Hi35xxGetBaud(struct UartHost * host,uint32_t * baudRate)146 static int32_t Hi35xxGetBaud(struct UartHost *host, uint32_t *baudRate)
147 {
148 struct UartDriverData *udd = NULL;
149
150 if (host == NULL || host->priv == NULL || baudRate == NULL) {
151 HDF_LOGE("%s: invalid parameter", __func__);
152 return HDF_ERR_INVALID_PARAM;
153 }
154
155 udd = (struct UartDriverData *)host->priv;
156 if (udd->state != UART_STATE_USEABLE) {
157 return HDF_FAILURE;
158 }
159 *baudRate = udd->baudrate;
160 return HDF_SUCCESS;
161 }
162
Hi35xxSetBaud(struct UartHost * host,uint32_t baudRate)163 static int32_t Hi35xxSetBaud(struct UartHost *host, uint32_t baudRate)
164 {
165 struct UartDriverData *udd = NULL;
166 struct UartPl011Port *port = NULL;
167
168 if (host == NULL || host->priv == NULL) {
169 HDF_LOGE("%s: invalid parameter", __func__);
170 return HDF_ERR_INVALID_PARAM;
171 }
172
173 udd = (struct UartDriverData *)host->priv;
174 if (udd->state != UART_STATE_USEABLE || udd->private == NULL) {
175 return HDF_FAILURE;
176 }
177 port = udd->private;
178
179 if ((baudRate > 0) && (baudRate <= CONFIG_MAX_BAUDRATE)) {
180 udd->baudrate = baudRate;
181 if (udd->ops->Config == NULL) {
182 HDF_LOGE("%s: not support", __func__);
183 return HDF_ERR_NOT_SUPPORT;
184 }
185 if (udd->ops->Config(udd) != HDF_SUCCESS) {
186 HDF_LOGE("%s: config baudrate %u failed", __func__, baudRate);
187 UartDumperDump(port);
188 return HDF_FAILURE;
189 }
190 } else {
191 HDF_LOGE("%s: invalid baudrate, which is:%u", __func__, baudRate);
192 return HDF_FAILURE;
193 }
194 return HDF_SUCCESS;
195 }
196
Hi35xxGetAttribute(struct UartHost * host,struct UartAttribute * attribute)197 static int32_t Hi35xxGetAttribute(struct UartHost *host, struct UartAttribute *attribute)
198 {
199 struct UartDriverData *udd = NULL;
200
201 if (host == NULL || host->priv == NULL || attribute == NULL) {
202 HDF_LOGE("%s: invalid parameter", __func__);
203 return HDF_ERR_INVALID_PARAM;
204 }
205 udd = (struct UartDriverData *)host->priv;
206 if (udd->state != UART_STATE_USEABLE) {
207 return HDF_FAILURE;
208 }
209 attribute->cts = udd->attr.cts;
210 attribute->dataBits = udd->attr.dataBits;
211 attribute->fifoRxEn = udd->attr.fifoRxEn;
212 attribute->fifoTxEn = udd->attr.fifoTxEn;
213 attribute->parity = udd->attr.parity;
214 attribute->rts = udd->attr.rts;
215 attribute->stopBits = udd->attr.stopBits;
216 return HDF_SUCCESS;
217 }
218
Hi35xxSetAttribute(struct UartHost * host,struct UartAttribute * attribute)219 static int32_t Hi35xxSetAttribute(struct UartHost *host, struct UartAttribute *attribute)
220 {
221 struct UartDriverData *udd = NULL;
222 struct UartPl011Port *port = NULL;
223
224 if (host == NULL || host->priv == NULL || attribute == NULL) {
225 HDF_LOGE("%s: invalid parameter", __func__);
226 return HDF_ERR_INVALID_PARAM;
227 }
228 udd = (struct UartDriverData *)host->priv;
229 if (udd->state != UART_STATE_USEABLE || udd->private == NULL) {
230 return HDF_FAILURE;
231 }
232
233 port = udd->private;
234 udd->attr.cts = attribute->cts;
235 udd->attr.dataBits = attribute->dataBits;
236 udd->attr.fifoRxEn = attribute->fifoRxEn;
237 udd->attr.fifoTxEn = attribute->fifoTxEn;
238 udd->attr.parity = attribute->parity;
239 udd->attr.rts = attribute->rts;
240 udd->attr.stopBits = attribute->stopBits;
241 if (udd->ops->Config == NULL) {
242 HDF_LOGE("%s: not support", __func__);
243 return HDF_ERR_NOT_SUPPORT;
244 }
245 if (udd->ops->Config(udd) != HDF_SUCCESS) {
246 HDF_LOGE("%s: config failed", __func__);
247 UartDumperDump(port);
248 return HDF_FAILURE;
249 }
250 return HDF_SUCCESS;
251 }
252
Hi35xxSetTransMode(struct UartHost * host,enum UartTransMode mode)253 static int32_t Hi35xxSetTransMode(struct UartHost *host, enum UartTransMode mode)
254 {
255 struct UartDriverData *udd = NULL;
256
257 if (host == NULL || host->priv == NULL) {
258 HDF_LOGE("%s: invalid parameter", __func__);
259 return HDF_ERR_INVALID_PARAM;
260 }
261 udd = (struct UartDriverData *)host->priv;
262 if (udd->state != UART_STATE_USEABLE) {
263 return HDF_FAILURE;
264 }
265 if (mode == UART_MODE_RD_BLOCK) {
266 udd->flags |= UART_FLG_RD_BLOCK;
267 } else if (mode == UART_MODE_RD_NONBLOCK) {
268 udd->flags &= ~UART_FLG_RD_BLOCK;
269 (void)LOS_EventWrite(&udd->wait.stEvent, 0x1);
270 }
271 return HDF_SUCCESS;
272 }
273
Hi35xxInit(struct UartHost * host)274 static int32_t Hi35xxInit(struct UartHost *host)
275 {
276 int32_t ret = 0;
277 struct UartDriverData *udd = NULL;
278 struct UartPl011Port *port = NULL;
279 struct wait_queue_head *wait = NULL;
280
281 if (host == NULL || host->priv == NULL) {
282 HDF_LOGE("%s: invalid parameter", __func__);
283 return HDF_ERR_INVALID_PARAM;
284 }
285
286 udd = (struct UartDriverData *)host->priv;
287 if (udd->private == NULL) {
288 HDF_LOGE("%s:udd private is NULL", __func__);
289 return HDF_FAILURE;
290 }
291 port = udd->private;
292
293 wait = &udd->wait;
294 if (udd->state == UART_STATE_NOT_OPENED) {
295 udd->state = UART_STATE_OPENING;
296 (void)LOS_EventInit(&wait->stEvent);
297 spin_lock_init(&wait->lock);
298 LOS_ListInit(&wait->poll_queue);
299 udd->rxTransfer = (struct UartTransfer *)OsalMemCalloc(sizeof(struct UartTransfer));
300 if (udd->rxTransfer == NULL) {
301 HDF_LOGE("%s: alloc transfer failed", __func__);
302 return HDF_ERR_MALLOC_FAIL;
303 }
304 if (udd->ops->StartUp == NULL) {
305 HDF_LOGE("%s: not support", __func__);
306 ret = HDF_ERR_NOT_SUPPORT;
307 goto FREE_TRANSFER;
308 }
309 if (udd->ops->StartUp(udd) != HDF_SUCCESS) {
310 HDF_LOGE("%s: StartUp failed", __func__);
311 UartDumperDump(port);
312 ret = HDF_FAILURE;
313 goto FREE_TRANSFER;
314 }
315 }
316 udd->state = UART_STATE_USEABLE;
317 udd->count++;
318 return HDF_SUCCESS;
319
320 FREE_TRANSFER:
321 OsalMemFree(udd->rxTransfer);
322 udd->rxTransfer = NULL;
323 return ret;
324 }
325
Hi35xxDeinit(struct UartHost * host)326 static int32_t Hi35xxDeinit(struct UartHost *host)
327 {
328 struct wait_queue_head *wait = NULL;
329 struct UartDriverData *udd = NULL;
330
331 if (host == NULL || host->priv == NULL) {
332 HDF_LOGE("%s: invalid parameter", __func__);
333 return HDF_ERR_INVALID_PARAM;
334 }
335
336 udd = (struct UartDriverData *)host->priv;
337 if ((--udd->count) != 0) {
338 return HDF_SUCCESS;
339 }
340 wait = &udd->wait;
341 if (udd->flags & UART_FLG_DMA_RX) {
342 if (udd->ops->DmaShutDown != NULL) {
343 udd->ops->DmaShutDown(udd, UART_DMA_DIR_RX);
344 }
345 }
346 if (udd->flags & UART_FLG_DMA_TX) {
347 if (udd->ops->DmaShutDown != NULL) {
348 udd->ops->DmaShutDown(udd, UART_DMA_DIR_TX);
349 }
350 }
351 LOS_ListDelete(&wait->poll_queue);
352 LOS_EventDestroy(&wait->stEvent);
353 if (udd->ops->ShutDown != NULL) {
354 udd->ops->ShutDown(udd);
355 }
356 if (udd->rxTransfer != NULL) {
357 OsalMemFree(udd->rxTransfer);
358 udd->rxTransfer = NULL;
359 }
360 udd->state = UART_STATE_NOT_OPENED;
361 return HDF_SUCCESS;
362 }
363
Hi35xxPollEvent(struct UartHost * host,void * filep,void * table)364 static int32_t Hi35xxPollEvent(struct UartHost *host, void *filep, void *table)
365 {
366 struct UartDriverData *udd = NULL;
367
368 if (host == NULL || host->priv == NULL) {
369 HDF_LOGE("%s: host is NULL", __func__);
370 return HDF_FAILURE;
371 }
372 udd = (struct UartDriverData *)host->priv;
373 if (UART_STATE_USEABLE != udd->state) {
374 return -EFAULT;
375 }
376
377 poll_wait((struct file *)filep, &udd->wait, (poll_table *)table);
378
379 if (!PL011UartRxBufEmpty(udd)) {
380 return POLLIN | POLLRDNORM;
381 }
382 return 0;
383 }
384
385 struct UartHostMethod g_uartHostMethod = {
386 .Init = Hi35xxInit,
387 .Deinit = Hi35xxDeinit,
388 .Read = Hi35xxRead,
389 .Write = Hi35xxWrite,
390 .SetBaud = Hi35xxSetBaud,
391 .GetBaud = Hi35xxGetBaud,
392 .SetAttribute = Hi35xxSetAttribute,
393 .GetAttribute = Hi35xxGetAttribute,
394 .SetTransMode = Hi35xxSetTransMode,
395 .pollEvent = Hi35xxPollEvent,
396 };
397
UartGetConfigFromHcs(struct UartPl011Port * port,const struct DeviceResourceNode * node)398 static int32_t UartGetConfigFromHcs(struct UartPl011Port *port, const struct DeviceResourceNode *node)
399 {
400 uint32_t tmp, regPbase, iomemCount;
401 struct UartDriverData *udd = port->udd;
402 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
403 if (iface == NULL || iface->GetUint32 == NULL) {
404 HDF_LOGE("%s: face is invalid", __func__);
405 return HDF_FAILURE;
406 }
407 if (iface->GetUint32(node, "num", &udd->num, 0) != HDF_SUCCESS) {
408 HDF_LOGE("%s: read busNum fail", __func__);
409 return HDF_FAILURE;
410 }
411 if (iface->GetUint32(node, "baudrate", &udd->baudrate, 0) != HDF_SUCCESS) {
412 HDF_LOGE("%s: read numCs fail", __func__);
413 return HDF_FAILURE;
414 }
415 if (iface->GetUint32(node, "fifoRxEn", &tmp, 0) != HDF_SUCCESS) {
416 HDF_LOGE("%s: read speed fail", __func__);
417 return HDF_FAILURE;
418 }
419 udd->attr.fifoRxEn = tmp;
420 if (iface->GetUint32(node, "fifoTxEn", &tmp, 0) != HDF_SUCCESS) {
421 HDF_LOGE("%s: read fifoSize fail", __func__);
422 return HDF_FAILURE;
423 }
424 udd->attr.fifoTxEn = tmp;
425 if (iface->GetUint32(node, "flags", &udd->flags, 0) != HDF_SUCCESS) {
426 HDF_LOGE("%s: read clkRate fail", __func__);
427 return HDF_FAILURE;
428 }
429 if (iface->GetUint32(node, "regPbase", ®Pbase, 0) != HDF_SUCCESS) {
430 HDF_LOGE("%s: read mode fail", __func__);
431 return HDF_FAILURE;
432 }
433 if (iface->GetUint32(node, "iomemCount", &iomemCount, 0) != HDF_SUCCESS) {
434 HDF_LOGE("%s: read bitsPerWord fail", __func__);
435 return HDF_FAILURE;
436 }
437 port->physBase = (unsigned long)OsalIoRemap(regPbase, iomemCount);
438 if (iface->GetUint32(node, "interrupt", &port->irqNum, 0) != HDF_SUCCESS) {
439 HDF_LOGE("%s: read comMode fail", __func__);
440 return HDF_FAILURE;
441 }
442 return 0;
443 }
444
Hi35xxAttach(struct UartHost * host,struct HdfDeviceObject * device)445 static int32_t Hi35xxAttach(struct UartHost *host, struct HdfDeviceObject *device)
446 {
447 int32_t ret;
448 struct UartDriverData *udd = NULL;
449 struct UartPl011Port *port = NULL;
450
451 if (device->property == NULL) {
452 HDF_LOGE("%s: property is null", __func__);
453 return HDF_FAILURE;
454 }
455 udd = (struct UartDriverData *)OsalMemCalloc(sizeof(*udd));
456 if (udd == NULL) {
457 HDF_LOGE("%s: OsalMemCalloc udd error", __func__);
458 return HDF_ERR_MALLOC_FAIL;
459 }
460 port = (struct UartPl011Port *)OsalMemCalloc(sizeof(struct UartPl011Port));
461 if (port == NULL) {
462 HDF_LOGE("%s: OsalMemCalloc port error", __func__);
463 OsalMemFree(udd);
464 return HDF_ERR_MALLOC_FAIL;
465 }
466 udd->ops = Pl011GetOps();
467 udd->recv = PL011UartRecvNotify;
468 udd->count = 0;
469 port->udd = udd;
470 ret = UartGetConfigFromHcs(port, device->property);
471 if (ret != 0 || port->physBase == 0) {
472 OsalMemFree(port);
473 OsalMemFree(udd);
474 return HDF_FAILURE;
475 }
476 udd->private = port;
477 host->priv = udd;
478 host->num = udd->num;
479 UartAddDev(host);
480 ret = UartDumperCreate(port);
481 if (ret != HDF_SUCCESS) {
482 HDF_LOGE("%s: create dumper failed:%d", __func__, ret);
483 OsalMemFree(port);
484 OsalMemFree(udd);
485 return ret;
486 }
487 UartDumperDump(port);
488 return HDF_SUCCESS;
489 }
490
Hi35xxDetach(struct UartHost * host)491 static void Hi35xxDetach(struct UartHost *host)
492 {
493 struct UartDriverData *udd = NULL;
494 struct UartPl011Port *port = NULL;
495
496 if (host->priv == NULL) {
497 HDF_LOGE("%s: invalid parameter", __func__);
498 return;
499 }
500 udd = host->priv;
501 if (udd->state != UART_STATE_NOT_OPENED) {
502 HDF_LOGE("%s: uart driver data state invalid", __func__);
503 return;
504 }
505 UartRemoveDev(host);
506 port = udd->private;
507 if (port != NULL) {
508 UartDumperDestroy(port);
509 if (port->physBase != 0) {
510 OsalIoUnmap((void *)port->physBase);
511 }
512 OsalMemFree(port);
513 udd->private = NULL;
514 }
515 OsalMemFree(udd);
516 host->priv = NULL;
517 }
518
HdfUartDeviceBind(struct HdfDeviceObject * device)519 static int32_t HdfUartDeviceBind(struct HdfDeviceObject *device)
520 {
521 HDF_LOGI("%s: entry", __func__);
522 if (device == NULL) {
523 return HDF_ERR_INVALID_OBJECT;
524 }
525 return (UartHostCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;
526 }
527
HdfUartDeviceInit(struct HdfDeviceObject * device)528 int32_t HdfUartDeviceInit(struct HdfDeviceObject *device)
529 {
530 int32_t ret;
531 struct UartHost *host = NULL;
532
533 if (device == NULL) {
534 HDF_LOGE("%s: device is null", __func__);
535 return HDF_ERR_INVALID_OBJECT;
536 }
537 host = UartHostFromDevice(device);
538 if (host == NULL) {
539 HDF_LOGE("%s: host is null", __func__);
540 return HDF_FAILURE;
541 }
542 ret = Hi35xxAttach(host, device);
543 if (ret != HDF_SUCCESS) {
544 HDF_LOGE("%s: attach error", __func__);
545 return HDF_FAILURE;
546 }
547 host->method = &g_uartHostMethod;
548 HDF_LOGI("%s: uart device init success.", __func__);
549 return ret;
550 }
551
HdfUartDeviceRelease(struct HdfDeviceObject * device)552 void HdfUartDeviceRelease(struct HdfDeviceObject *device)
553 {
554 struct UartHost *host = NULL;
555
556 HDF_LOGI("%s: entry", __func__);
557 if (device == NULL) {
558 HDF_LOGE("%s: device is null", __func__);
559 return;
560 }
561 host = UartHostFromDevice(device);
562 if (host == NULL) {
563 HDF_LOGE("%s: host is null", __func__);
564 return;
565 }
566 if (host->priv != NULL) {
567 Hi35xxDetach(host);
568 }
569 UartHostDestroy(host);
570 }
571
572 struct HdfDriverEntry g_hdfUartDevice = {
573 .moduleVersion = 1,
574 .moduleName = "HDF_PLATFORM_UART",
575 .Bind = HdfUartDeviceBind,
576 .Init = HdfUartDeviceInit,
577 .Release = HdfUartDeviceRelease,
578 };
579
580 HDF_INIT(g_hdfUartDevice);
581