• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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", &regPbase, 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