11bd4fe43Sopenharmony_ci/*
21bd4fe43Sopenharmony_ci * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
31bd4fe43Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
41bd4fe43Sopenharmony_ci * you may not use this file except in compliance with the License.
51bd4fe43Sopenharmony_ci * You may obtain a copy of the License at
61bd4fe43Sopenharmony_ci *
71bd4fe43Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
81bd4fe43Sopenharmony_ci *
91bd4fe43Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
101bd4fe43Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
111bd4fe43Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121bd4fe43Sopenharmony_ci * See the License for the specific language governing permissions and
131bd4fe43Sopenharmony_ci * limitations under the License.
141bd4fe43Sopenharmony_ci */
151bd4fe43Sopenharmony_ci
161bd4fe43Sopenharmony_ci#include "los_event.h"
171bd4fe43Sopenharmony_ci#include "device_resource_if.h"
181bd4fe43Sopenharmony_ci#include "hdf_base.h"
191bd4fe43Sopenharmony_ci#include "hdf_log.h"
201bd4fe43Sopenharmony_ci#include "osal_io.h"
211bd4fe43Sopenharmony_ci#include "osal_mem.h"
221bd4fe43Sopenharmony_ci#include "osal_time.h"
231bd4fe43Sopenharmony_ci#include "platform_dumper.h"
241bd4fe43Sopenharmony_ci#include "uart_core.h"
251bd4fe43Sopenharmony_ci#include "uart_dev.h"
261bd4fe43Sopenharmony_ci#include "uart_if.h"
271bd4fe43Sopenharmony_ci#include "uart_pl011.h"
281bd4fe43Sopenharmony_ci
291bd4fe43Sopenharmony_ci#define HDF_LOG_TAG uart_hi35xx
301bd4fe43Sopenharmony_ci
311bd4fe43Sopenharmony_ci#define UART_DUMPER_NAME_PREFIX    "uart_dumper_"
321bd4fe43Sopenharmony_ci#define UART_DUMPER_NAME_LEN     64
331bd4fe43Sopenharmony_ci
341bd4fe43Sopenharmony_cistatic void UartDumperDump(struct UartPl011Port *port)
351bd4fe43Sopenharmony_ci{
361bd4fe43Sopenharmony_ci    int32_t ret;
371bd4fe43Sopenharmony_ci    struct PlatformDumperData datas[] = {
381bd4fe43Sopenharmony_ci        {"UART_DR", PLATFORM_DUMPER_REGISTERL, (void *)port->physBase},
391bd4fe43Sopenharmony_ci        {"UART_RSR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_RSR)},
401bd4fe43Sopenharmony_ci        {"UART_FR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_FR)},
411bd4fe43Sopenharmony_ci        {"UART_IBRD", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_IBRD)},
421bd4fe43Sopenharmony_ci        {"UART_FBRD", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_FBRD)},
431bd4fe43Sopenharmony_ci        {"UART_LCR_H", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_LCR_H)},
441bd4fe43Sopenharmony_ci        {"UART_CR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_CR)},
451bd4fe43Sopenharmony_ci        {"UART_IFLS", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_IFLS)},
461bd4fe43Sopenharmony_ci        {"UART_IMSC", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_IMSC)},
471bd4fe43Sopenharmony_ci        {"UART_RIS", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_RIS)},
481bd4fe43Sopenharmony_ci        {"UART_MIS", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_MIS)},
491bd4fe43Sopenharmony_ci        {"UART_ICR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_ICR)},
501bd4fe43Sopenharmony_ci        {"UART_DMACR", PLATFORM_DUMPER_REGISTERL, (void *)(port->physBase + UART_DMACR)},
511bd4fe43Sopenharmony_ci    };
521bd4fe43Sopenharmony_ci    if (port->dumper == NULL) {
531bd4fe43Sopenharmony_ci        HDF_LOGE("%s: uart dumper is NULL", __func__);
541bd4fe43Sopenharmony_ci        return;
551bd4fe43Sopenharmony_ci    }
561bd4fe43Sopenharmony_ci    ret = PlatformDumperAddDatas(port->dumper, datas, sizeof(datas) / sizeof(struct PlatformDumperData));
571bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
581bd4fe43Sopenharmony_ci        return;
591bd4fe43Sopenharmony_ci    }
601bd4fe43Sopenharmony_ci    (void)PlatformDumperDump(port->dumper);
611bd4fe43Sopenharmony_ci    (void)PlatformDumperClearDatas(port->dumper);
621bd4fe43Sopenharmony_ci}
631bd4fe43Sopenharmony_ci
641bd4fe43Sopenharmony_cistatic int32_t UartDumperCreate(struct UartPl011Port *port)
651bd4fe43Sopenharmony_ci{
661bd4fe43Sopenharmony_ci    struct PlatformDumper *dumper = NULL;
671bd4fe43Sopenharmony_ci    char *name = NULL;
681bd4fe43Sopenharmony_ci
691bd4fe43Sopenharmony_ci    name = (char *)OsalMemCalloc(UART_DUMPER_NAME_LEN);
701bd4fe43Sopenharmony_ci    if (name == NULL) {
711bd4fe43Sopenharmony_ci        HDF_LOGE("%s: alloc name fail", __func__);
721bd4fe43Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
731bd4fe43Sopenharmony_ci    }
741bd4fe43Sopenharmony_ci
751bd4fe43Sopenharmony_ci    if (snprintf_s(name, UART_DUMPER_NAME_LEN, UART_DUMPER_NAME_LEN - 1, "%s%d",
761bd4fe43Sopenharmony_ci        UART_DUMPER_NAME_PREFIX, port->udd->num) < 0) {
771bd4fe43Sopenharmony_ci        HDF_LOGE("%s: snprintf_s name fail!", __func__);
781bd4fe43Sopenharmony_ci        OsalMemFree(name);
791bd4fe43Sopenharmony_ci        return HDF_ERR_IO;
801bd4fe43Sopenharmony_ci    }
811bd4fe43Sopenharmony_ci
821bd4fe43Sopenharmony_ci    dumper = PlatformDumperCreate(name);
831bd4fe43Sopenharmony_ci    if (dumper == NULL) {
841bd4fe43Sopenharmony_ci        HDF_LOGE("%s: get dumper for %s fail!", __func__, name);
851bd4fe43Sopenharmony_ci        OsalMemFree(name);
861bd4fe43Sopenharmony_ci        return HDF_ERR_IO;
871bd4fe43Sopenharmony_ci    }
881bd4fe43Sopenharmony_ci
891bd4fe43Sopenharmony_ci    port->dumper = dumper;
901bd4fe43Sopenharmony_ci    port->dumperName = name;
911bd4fe43Sopenharmony_ci
921bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
931bd4fe43Sopenharmony_ci}
941bd4fe43Sopenharmony_ci
951bd4fe43Sopenharmony_cistatic inline void UartDumperDestroy(struct UartPl011Port *port)
961bd4fe43Sopenharmony_ci{
971bd4fe43Sopenharmony_ci    PlatformDumperDestroy(port->dumper);
981bd4fe43Sopenharmony_ci    OsalMemFree(port->dumperName);
991bd4fe43Sopenharmony_ci}
1001bd4fe43Sopenharmony_ci
1011bd4fe43Sopenharmony_cistatic int32_t Hi35xxRead(struct UartHost *host, uint8_t *data, uint32_t size)
1021bd4fe43Sopenharmony_ci{
1031bd4fe43Sopenharmony_ci    int32_t ret;
1041bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
1051bd4fe43Sopenharmony_ci
1061bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
1071bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
1081bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1091bd4fe43Sopenharmony_ci    }
1101bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
1111bd4fe43Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
1121bd4fe43Sopenharmony_ci        return HDF_FAILURE;
1131bd4fe43Sopenharmony_ci    }
1141bd4fe43Sopenharmony_ci    if ((udd->flags & UART_FLG_RD_BLOCK) && (PL011UartRxBufEmpty(udd))) {
1151bd4fe43Sopenharmony_ci        (void)LOS_EventRead(&udd->wait.stEvent, 0x1, LOS_WAITMODE_OR, LOS_WAIT_FOREVER);
1161bd4fe43Sopenharmony_ci    }
1171bd4fe43Sopenharmony_ci    ret = Pl011Read(udd, (char *)data, size);
1181bd4fe43Sopenharmony_ci    if ((udd->flags & UART_FLG_RD_BLOCK) && (PL011UartRxBufEmpty(udd))) {
1191bd4fe43Sopenharmony_ci        (void)LOS_EventClear(&udd->wait.stEvent, ~(0x1));
1201bd4fe43Sopenharmony_ci    }
1211bd4fe43Sopenharmony_ci    return ret;
1221bd4fe43Sopenharmony_ci}
1231bd4fe43Sopenharmony_ci
1241bd4fe43Sopenharmony_cistatic int32_t Hi35xxWrite(struct UartHost *host, uint8_t *data, uint32_t size)
1251bd4fe43Sopenharmony_ci{
1261bd4fe43Sopenharmony_ci    int32_t ret;
1271bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
1281bd4fe43Sopenharmony_ci
1291bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
1301bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
1311bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1321bd4fe43Sopenharmony_ci    }
1331bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
1341bd4fe43Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
1351bd4fe43Sopenharmony_ci        return HDF_FAILURE;
1361bd4fe43Sopenharmony_ci    }
1371bd4fe43Sopenharmony_ci    if (udd->ops->StartTx != NULL) {
1381bd4fe43Sopenharmony_ci        ret = udd->ops->StartTx(udd, (char *)data, size);
1391bd4fe43Sopenharmony_ci    } else {
1401bd4fe43Sopenharmony_ci        ret = HDF_ERR_NOT_SUPPORT;
1411bd4fe43Sopenharmony_ci        HDF_LOGE("%s: not support", __func__);
1421bd4fe43Sopenharmony_ci    }
1431bd4fe43Sopenharmony_ci    return ret;
1441bd4fe43Sopenharmony_ci}
1451bd4fe43Sopenharmony_ci
1461bd4fe43Sopenharmony_cistatic int32_t Hi35xxGetBaud(struct UartHost *host, uint32_t *baudRate)
1471bd4fe43Sopenharmony_ci{
1481bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
1491bd4fe43Sopenharmony_ci
1501bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL || baudRate == NULL) {
1511bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
1521bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1531bd4fe43Sopenharmony_ci    }
1541bd4fe43Sopenharmony_ci
1551bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
1561bd4fe43Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
1571bd4fe43Sopenharmony_ci        return HDF_FAILURE;
1581bd4fe43Sopenharmony_ci    }
1591bd4fe43Sopenharmony_ci    *baudRate = udd->baudrate;
1601bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1611bd4fe43Sopenharmony_ci}
1621bd4fe43Sopenharmony_ci
1631bd4fe43Sopenharmony_cistatic int32_t Hi35xxSetBaud(struct UartHost *host, uint32_t baudRate)
1641bd4fe43Sopenharmony_ci{
1651bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
1661bd4fe43Sopenharmony_ci    struct UartPl011Port *port = NULL;
1671bd4fe43Sopenharmony_ci
1681bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
1691bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
1701bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1711bd4fe43Sopenharmony_ci    }
1721bd4fe43Sopenharmony_ci
1731bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
1741bd4fe43Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE || udd->private == NULL) {
1751bd4fe43Sopenharmony_ci        return HDF_FAILURE;
1761bd4fe43Sopenharmony_ci    }
1771bd4fe43Sopenharmony_ci    port = udd->private;
1781bd4fe43Sopenharmony_ci
1791bd4fe43Sopenharmony_ci    if ((baudRate > 0) && (baudRate <= CONFIG_MAX_BAUDRATE)) {
1801bd4fe43Sopenharmony_ci        udd->baudrate = baudRate;
1811bd4fe43Sopenharmony_ci        if (udd->ops->Config == NULL) {
1821bd4fe43Sopenharmony_ci            HDF_LOGE("%s: not support", __func__);
1831bd4fe43Sopenharmony_ci            return HDF_ERR_NOT_SUPPORT;
1841bd4fe43Sopenharmony_ci        }
1851bd4fe43Sopenharmony_ci        if (udd->ops->Config(udd) != HDF_SUCCESS) {
1861bd4fe43Sopenharmony_ci            HDF_LOGE("%s: config baudrate %u failed", __func__, baudRate);
1871bd4fe43Sopenharmony_ci            UartDumperDump(port);
1881bd4fe43Sopenharmony_ci            return HDF_FAILURE;
1891bd4fe43Sopenharmony_ci        }
1901bd4fe43Sopenharmony_ci    } else {
1911bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid baudrate, which is:%u", __func__, baudRate);
1921bd4fe43Sopenharmony_ci        return HDF_FAILURE;
1931bd4fe43Sopenharmony_ci    }
1941bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1951bd4fe43Sopenharmony_ci}
1961bd4fe43Sopenharmony_ci
1971bd4fe43Sopenharmony_cistatic int32_t Hi35xxGetAttribute(struct UartHost *host, struct UartAttribute *attribute)
1981bd4fe43Sopenharmony_ci{
1991bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
2001bd4fe43Sopenharmony_ci
2011bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL || attribute == NULL) {
2021bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
2031bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
2041bd4fe43Sopenharmony_ci    }
2051bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
2061bd4fe43Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
2071bd4fe43Sopenharmony_ci        return HDF_FAILURE;
2081bd4fe43Sopenharmony_ci    }
2091bd4fe43Sopenharmony_ci    attribute->cts = udd->attr.cts;
2101bd4fe43Sopenharmony_ci    attribute->dataBits = udd->attr.dataBits;
2111bd4fe43Sopenharmony_ci    attribute->fifoRxEn = udd->attr.fifoRxEn;
2121bd4fe43Sopenharmony_ci    attribute->fifoTxEn = udd->attr.fifoTxEn;
2131bd4fe43Sopenharmony_ci    attribute->parity = udd->attr.parity;
2141bd4fe43Sopenharmony_ci    attribute->rts = udd->attr.rts;
2151bd4fe43Sopenharmony_ci    attribute->stopBits = udd->attr.stopBits;
2161bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
2171bd4fe43Sopenharmony_ci}
2181bd4fe43Sopenharmony_ci
2191bd4fe43Sopenharmony_cistatic int32_t Hi35xxSetAttribute(struct UartHost *host, struct UartAttribute *attribute)
2201bd4fe43Sopenharmony_ci{
2211bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
2221bd4fe43Sopenharmony_ci    struct UartPl011Port *port = NULL;
2231bd4fe43Sopenharmony_ci
2241bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL || attribute == NULL) {
2251bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
2261bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
2271bd4fe43Sopenharmony_ci    }
2281bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
2291bd4fe43Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE || udd->private == NULL) {
2301bd4fe43Sopenharmony_ci        return HDF_FAILURE;
2311bd4fe43Sopenharmony_ci    }
2321bd4fe43Sopenharmony_ci
2331bd4fe43Sopenharmony_ci    port = udd->private;
2341bd4fe43Sopenharmony_ci    udd->attr.cts = attribute->cts;
2351bd4fe43Sopenharmony_ci    udd->attr.dataBits = attribute->dataBits;
2361bd4fe43Sopenharmony_ci    udd->attr.fifoRxEn = attribute->fifoRxEn;
2371bd4fe43Sopenharmony_ci    udd->attr.fifoTxEn = attribute->fifoTxEn;
2381bd4fe43Sopenharmony_ci    udd->attr.parity = attribute->parity;
2391bd4fe43Sopenharmony_ci    udd->attr.rts = attribute->rts;
2401bd4fe43Sopenharmony_ci    udd->attr.stopBits = attribute->stopBits;
2411bd4fe43Sopenharmony_ci    if (udd->ops->Config == NULL) {
2421bd4fe43Sopenharmony_ci        HDF_LOGE("%s: not support", __func__);
2431bd4fe43Sopenharmony_ci        return HDF_ERR_NOT_SUPPORT;
2441bd4fe43Sopenharmony_ci    }
2451bd4fe43Sopenharmony_ci    if (udd->ops->Config(udd) != HDF_SUCCESS) {
2461bd4fe43Sopenharmony_ci        HDF_LOGE("%s: config failed", __func__);
2471bd4fe43Sopenharmony_ci        UartDumperDump(port);
2481bd4fe43Sopenharmony_ci        return HDF_FAILURE;
2491bd4fe43Sopenharmony_ci    }
2501bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
2511bd4fe43Sopenharmony_ci}
2521bd4fe43Sopenharmony_ci
2531bd4fe43Sopenharmony_cistatic int32_t Hi35xxSetTransMode(struct UartHost *host, enum UartTransMode mode)
2541bd4fe43Sopenharmony_ci{
2551bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
2561bd4fe43Sopenharmony_ci
2571bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
2581bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
2591bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
2601bd4fe43Sopenharmony_ci    }
2611bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
2621bd4fe43Sopenharmony_ci    if (udd->state != UART_STATE_USEABLE) {
2631bd4fe43Sopenharmony_ci        return HDF_FAILURE;
2641bd4fe43Sopenharmony_ci    }
2651bd4fe43Sopenharmony_ci    if (mode == UART_MODE_RD_BLOCK) {
2661bd4fe43Sopenharmony_ci        udd->flags |= UART_FLG_RD_BLOCK;
2671bd4fe43Sopenharmony_ci    } else if (mode == UART_MODE_RD_NONBLOCK) {
2681bd4fe43Sopenharmony_ci        udd->flags &= ~UART_FLG_RD_BLOCK;
2691bd4fe43Sopenharmony_ci        (void)LOS_EventWrite(&udd->wait.stEvent, 0x1);
2701bd4fe43Sopenharmony_ci    }
2711bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
2721bd4fe43Sopenharmony_ci}
2731bd4fe43Sopenharmony_ci
2741bd4fe43Sopenharmony_cistatic int32_t Hi35xxInit(struct UartHost *host)
2751bd4fe43Sopenharmony_ci{
2761bd4fe43Sopenharmony_ci    int32_t ret = 0;
2771bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
2781bd4fe43Sopenharmony_ci    struct UartPl011Port *port = NULL;
2791bd4fe43Sopenharmony_ci    struct wait_queue_head *wait = NULL;
2801bd4fe43Sopenharmony_ci
2811bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
2821bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
2831bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
2841bd4fe43Sopenharmony_ci    }
2851bd4fe43Sopenharmony_ci
2861bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
2871bd4fe43Sopenharmony_ci    if (udd->private == NULL) {
2881bd4fe43Sopenharmony_ci        HDF_LOGE("%s:udd private is NULL", __func__);
2891bd4fe43Sopenharmony_ci        return HDF_FAILURE;
2901bd4fe43Sopenharmony_ci    }
2911bd4fe43Sopenharmony_ci    port = udd->private;
2921bd4fe43Sopenharmony_ci
2931bd4fe43Sopenharmony_ci    wait = &udd->wait;
2941bd4fe43Sopenharmony_ci    if (udd->state == UART_STATE_NOT_OPENED) {
2951bd4fe43Sopenharmony_ci        udd->state = UART_STATE_OPENING;
2961bd4fe43Sopenharmony_ci        (void)LOS_EventInit(&wait->stEvent);
2971bd4fe43Sopenharmony_ci        spin_lock_init(&wait->lock);
2981bd4fe43Sopenharmony_ci        LOS_ListInit(&wait->poll_queue);
2991bd4fe43Sopenharmony_ci        udd->rxTransfer = (struct UartTransfer *)OsalMemCalloc(sizeof(struct UartTransfer));
3001bd4fe43Sopenharmony_ci        if (udd->rxTransfer == NULL) {
3011bd4fe43Sopenharmony_ci            HDF_LOGE("%s: alloc transfer failed", __func__);
3021bd4fe43Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
3031bd4fe43Sopenharmony_ci        }
3041bd4fe43Sopenharmony_ci        if (udd->ops->StartUp == NULL) {
3051bd4fe43Sopenharmony_ci            HDF_LOGE("%s: not support", __func__);
3061bd4fe43Sopenharmony_ci            ret = HDF_ERR_NOT_SUPPORT;
3071bd4fe43Sopenharmony_ci            goto FREE_TRANSFER;
3081bd4fe43Sopenharmony_ci        }
3091bd4fe43Sopenharmony_ci        if (udd->ops->StartUp(udd) != HDF_SUCCESS) {
3101bd4fe43Sopenharmony_ci            HDF_LOGE("%s: StartUp failed", __func__);
3111bd4fe43Sopenharmony_ci            UartDumperDump(port);
3121bd4fe43Sopenharmony_ci            ret = HDF_FAILURE;
3131bd4fe43Sopenharmony_ci            goto FREE_TRANSFER;
3141bd4fe43Sopenharmony_ci        }
3151bd4fe43Sopenharmony_ci    }
3161bd4fe43Sopenharmony_ci    udd->state = UART_STATE_USEABLE;
3171bd4fe43Sopenharmony_ci    udd->count++;
3181bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
3191bd4fe43Sopenharmony_ci
3201bd4fe43Sopenharmony_ciFREE_TRANSFER:
3211bd4fe43Sopenharmony_ci    OsalMemFree(udd->rxTransfer);
3221bd4fe43Sopenharmony_ci    udd->rxTransfer = NULL;
3231bd4fe43Sopenharmony_ci    return ret;
3241bd4fe43Sopenharmony_ci}
3251bd4fe43Sopenharmony_ci
3261bd4fe43Sopenharmony_cistatic int32_t Hi35xxDeinit(struct UartHost *host)
3271bd4fe43Sopenharmony_ci{
3281bd4fe43Sopenharmony_ci    struct wait_queue_head *wait = NULL;
3291bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
3301bd4fe43Sopenharmony_ci
3311bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
3321bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
3331bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
3341bd4fe43Sopenharmony_ci    }
3351bd4fe43Sopenharmony_ci
3361bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
3371bd4fe43Sopenharmony_ci    if ((--udd->count) != 0) {
3381bd4fe43Sopenharmony_ci        return HDF_SUCCESS;
3391bd4fe43Sopenharmony_ci    }
3401bd4fe43Sopenharmony_ci    wait = &udd->wait;
3411bd4fe43Sopenharmony_ci    if (udd->flags & UART_FLG_DMA_RX) {
3421bd4fe43Sopenharmony_ci        if (udd->ops->DmaShutDown != NULL) {
3431bd4fe43Sopenharmony_ci            udd->ops->DmaShutDown(udd, UART_DMA_DIR_RX);
3441bd4fe43Sopenharmony_ci        }
3451bd4fe43Sopenharmony_ci    }
3461bd4fe43Sopenharmony_ci    if (udd->flags & UART_FLG_DMA_TX) {
3471bd4fe43Sopenharmony_ci        if (udd->ops->DmaShutDown != NULL) {
3481bd4fe43Sopenharmony_ci            udd->ops->DmaShutDown(udd, UART_DMA_DIR_TX);
3491bd4fe43Sopenharmony_ci        }
3501bd4fe43Sopenharmony_ci    }
3511bd4fe43Sopenharmony_ci    LOS_ListDelete(&wait->poll_queue);
3521bd4fe43Sopenharmony_ci    LOS_EventDestroy(&wait->stEvent);
3531bd4fe43Sopenharmony_ci    if (udd->ops->ShutDown != NULL) {
3541bd4fe43Sopenharmony_ci        udd->ops->ShutDown(udd);
3551bd4fe43Sopenharmony_ci    }
3561bd4fe43Sopenharmony_ci    if (udd->rxTransfer != NULL) {
3571bd4fe43Sopenharmony_ci        OsalMemFree(udd->rxTransfer);
3581bd4fe43Sopenharmony_ci        udd->rxTransfer = NULL;
3591bd4fe43Sopenharmony_ci    }
3601bd4fe43Sopenharmony_ci    udd->state = UART_STATE_NOT_OPENED;
3611bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
3621bd4fe43Sopenharmony_ci}
3631bd4fe43Sopenharmony_ci
3641bd4fe43Sopenharmony_cistatic int32_t Hi35xxPollEvent(struct UartHost *host, void *filep, void *table)
3651bd4fe43Sopenharmony_ci{
3661bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
3671bd4fe43Sopenharmony_ci
3681bd4fe43Sopenharmony_ci    if (host == NULL || host->priv == NULL) {
3691bd4fe43Sopenharmony_ci        HDF_LOGE("%s: host is NULL", __func__);
3701bd4fe43Sopenharmony_ci        return HDF_FAILURE;
3711bd4fe43Sopenharmony_ci    }
3721bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)host->priv;
3731bd4fe43Sopenharmony_ci    if (UART_STATE_USEABLE != udd->state) {
3741bd4fe43Sopenharmony_ci        return -EFAULT;
3751bd4fe43Sopenharmony_ci    }
3761bd4fe43Sopenharmony_ci
3771bd4fe43Sopenharmony_ci    poll_wait((struct file *)filep, &udd->wait, (poll_table *)table);
3781bd4fe43Sopenharmony_ci
3791bd4fe43Sopenharmony_ci    if (!PL011UartRxBufEmpty(udd)) {
3801bd4fe43Sopenharmony_ci        return POLLIN | POLLRDNORM;
3811bd4fe43Sopenharmony_ci    }
3821bd4fe43Sopenharmony_ci    return 0;
3831bd4fe43Sopenharmony_ci}
3841bd4fe43Sopenharmony_ci
3851bd4fe43Sopenharmony_cistruct UartHostMethod g_uartHostMethod = {
3861bd4fe43Sopenharmony_ci    .Init = Hi35xxInit,
3871bd4fe43Sopenharmony_ci    .Deinit = Hi35xxDeinit,
3881bd4fe43Sopenharmony_ci    .Read = Hi35xxRead,
3891bd4fe43Sopenharmony_ci    .Write = Hi35xxWrite,
3901bd4fe43Sopenharmony_ci    .SetBaud = Hi35xxSetBaud,
3911bd4fe43Sopenharmony_ci    .GetBaud = Hi35xxGetBaud,
3921bd4fe43Sopenharmony_ci    .SetAttribute = Hi35xxSetAttribute,
3931bd4fe43Sopenharmony_ci    .GetAttribute = Hi35xxGetAttribute,
3941bd4fe43Sopenharmony_ci    .SetTransMode = Hi35xxSetTransMode,
3951bd4fe43Sopenharmony_ci    .pollEvent = Hi35xxPollEvent,
3961bd4fe43Sopenharmony_ci};
3971bd4fe43Sopenharmony_ci
3981bd4fe43Sopenharmony_cistatic int32_t UartGetConfigFromHcs(struct UartPl011Port *port, const struct DeviceResourceNode *node)
3991bd4fe43Sopenharmony_ci{
4001bd4fe43Sopenharmony_ci    uint32_t tmp, regPbase, iomemCount;
4011bd4fe43Sopenharmony_ci    struct UartDriverData *udd = port->udd;
4021bd4fe43Sopenharmony_ci    struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
4031bd4fe43Sopenharmony_ci    if (iface == NULL || iface->GetUint32 == NULL) {
4041bd4fe43Sopenharmony_ci        HDF_LOGE("%s: face is invalid", __func__);
4051bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4061bd4fe43Sopenharmony_ci    }
4071bd4fe43Sopenharmony_ci    if (iface->GetUint32(node, "num", &udd->num, 0) != HDF_SUCCESS) {
4081bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read busNum fail", __func__);
4091bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4101bd4fe43Sopenharmony_ci    }
4111bd4fe43Sopenharmony_ci    if (iface->GetUint32(node, "baudrate", &udd->baudrate, 0) != HDF_SUCCESS) {
4121bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read numCs fail", __func__);
4131bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4141bd4fe43Sopenharmony_ci    }
4151bd4fe43Sopenharmony_ci    if (iface->GetUint32(node, "fifoRxEn", &tmp, 0) != HDF_SUCCESS) {
4161bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read speed fail", __func__);
4171bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4181bd4fe43Sopenharmony_ci    }
4191bd4fe43Sopenharmony_ci    udd->attr.fifoRxEn = tmp;
4201bd4fe43Sopenharmony_ci    if (iface->GetUint32(node, "fifoTxEn", &tmp, 0) != HDF_SUCCESS) {
4211bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read fifoSize fail", __func__);
4221bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4231bd4fe43Sopenharmony_ci    }
4241bd4fe43Sopenharmony_ci    udd->attr.fifoTxEn = tmp;
4251bd4fe43Sopenharmony_ci    if (iface->GetUint32(node, "flags", &udd->flags, 0) != HDF_SUCCESS) {
4261bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read clkRate fail", __func__);
4271bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4281bd4fe43Sopenharmony_ci    }
4291bd4fe43Sopenharmony_ci    if (iface->GetUint32(node, "regPbase", &regPbase, 0) != HDF_SUCCESS) {
4301bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read mode fail", __func__);
4311bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4321bd4fe43Sopenharmony_ci    }
4331bd4fe43Sopenharmony_ci    if (iface->GetUint32(node, "iomemCount", &iomemCount, 0) != HDF_SUCCESS) {
4341bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read bitsPerWord fail", __func__);
4351bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4361bd4fe43Sopenharmony_ci    }
4371bd4fe43Sopenharmony_ci    port->physBase = (unsigned long)OsalIoRemap(regPbase, iomemCount);
4381bd4fe43Sopenharmony_ci    if (iface->GetUint32(node, "interrupt", &port->irqNum, 0) != HDF_SUCCESS) {
4391bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read comMode fail", __func__);
4401bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4411bd4fe43Sopenharmony_ci    }
4421bd4fe43Sopenharmony_ci    return 0;
4431bd4fe43Sopenharmony_ci}
4441bd4fe43Sopenharmony_ci
4451bd4fe43Sopenharmony_cistatic int32_t Hi35xxAttach(struct UartHost *host, struct HdfDeviceObject *device)
4461bd4fe43Sopenharmony_ci{
4471bd4fe43Sopenharmony_ci    int32_t ret;
4481bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
4491bd4fe43Sopenharmony_ci    struct UartPl011Port *port = NULL;
4501bd4fe43Sopenharmony_ci
4511bd4fe43Sopenharmony_ci    if (device->property == NULL) {
4521bd4fe43Sopenharmony_ci        HDF_LOGE("%s: property is null", __func__);
4531bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4541bd4fe43Sopenharmony_ci    }
4551bd4fe43Sopenharmony_ci    udd = (struct UartDriverData *)OsalMemCalloc(sizeof(*udd));
4561bd4fe43Sopenharmony_ci    if (udd == NULL) {
4571bd4fe43Sopenharmony_ci        HDF_LOGE("%s: OsalMemCalloc udd error", __func__);
4581bd4fe43Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
4591bd4fe43Sopenharmony_ci    }
4601bd4fe43Sopenharmony_ci    port = (struct UartPl011Port *)OsalMemCalloc(sizeof(struct UartPl011Port));
4611bd4fe43Sopenharmony_ci    if (port == NULL) {
4621bd4fe43Sopenharmony_ci        HDF_LOGE("%s: OsalMemCalloc port error", __func__);
4631bd4fe43Sopenharmony_ci        OsalMemFree(udd);
4641bd4fe43Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
4651bd4fe43Sopenharmony_ci    }
4661bd4fe43Sopenharmony_ci    udd->ops = Pl011GetOps();
4671bd4fe43Sopenharmony_ci    udd->recv = PL011UartRecvNotify;
4681bd4fe43Sopenharmony_ci    udd->count = 0;
4691bd4fe43Sopenharmony_ci    port->udd = udd;
4701bd4fe43Sopenharmony_ci    ret = UartGetConfigFromHcs(port, device->property);
4711bd4fe43Sopenharmony_ci    if (ret != 0 || port->physBase == 0) {
4721bd4fe43Sopenharmony_ci        OsalMemFree(port);
4731bd4fe43Sopenharmony_ci        OsalMemFree(udd);
4741bd4fe43Sopenharmony_ci        return HDF_FAILURE;
4751bd4fe43Sopenharmony_ci    }
4761bd4fe43Sopenharmony_ci    udd->private = port;
4771bd4fe43Sopenharmony_ci    host->priv = udd;
4781bd4fe43Sopenharmony_ci    host->num = udd->num;
4791bd4fe43Sopenharmony_ci    UartAddDev(host);
4801bd4fe43Sopenharmony_ci    ret = UartDumperCreate(port);
4811bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
4821bd4fe43Sopenharmony_ci        HDF_LOGE("%s: create dumper failed:%d", __func__, ret);
4831bd4fe43Sopenharmony_ci        OsalMemFree(port);
4841bd4fe43Sopenharmony_ci        OsalMemFree(udd);
4851bd4fe43Sopenharmony_ci        return ret;
4861bd4fe43Sopenharmony_ci    }
4871bd4fe43Sopenharmony_ci    UartDumperDump(port);
4881bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
4891bd4fe43Sopenharmony_ci}
4901bd4fe43Sopenharmony_ci
4911bd4fe43Sopenharmony_cistatic void Hi35xxDetach(struct UartHost *host)
4921bd4fe43Sopenharmony_ci{
4931bd4fe43Sopenharmony_ci    struct UartDriverData *udd = NULL;
4941bd4fe43Sopenharmony_ci    struct UartPl011Port *port = NULL;
4951bd4fe43Sopenharmony_ci
4961bd4fe43Sopenharmony_ci    if (host->priv == NULL) {
4971bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid parameter", __func__);
4981bd4fe43Sopenharmony_ci        return;
4991bd4fe43Sopenharmony_ci    }
5001bd4fe43Sopenharmony_ci    udd = host->priv;
5011bd4fe43Sopenharmony_ci    if (udd->state != UART_STATE_NOT_OPENED) {
5021bd4fe43Sopenharmony_ci        HDF_LOGE("%s: uart driver data state invalid", __func__);
5031bd4fe43Sopenharmony_ci        return;
5041bd4fe43Sopenharmony_ci    }
5051bd4fe43Sopenharmony_ci    UartRemoveDev(host);
5061bd4fe43Sopenharmony_ci    port = udd->private;
5071bd4fe43Sopenharmony_ci    if (port != NULL) {
5081bd4fe43Sopenharmony_ci        UartDumperDestroy(port);
5091bd4fe43Sopenharmony_ci        if (port->physBase != 0) {
5101bd4fe43Sopenharmony_ci            OsalIoUnmap((void *)port->physBase);
5111bd4fe43Sopenharmony_ci        }
5121bd4fe43Sopenharmony_ci        OsalMemFree(port);
5131bd4fe43Sopenharmony_ci        udd->private = NULL;
5141bd4fe43Sopenharmony_ci    }
5151bd4fe43Sopenharmony_ci    OsalMemFree(udd);
5161bd4fe43Sopenharmony_ci    host->priv = NULL;
5171bd4fe43Sopenharmony_ci}
5181bd4fe43Sopenharmony_ci
5191bd4fe43Sopenharmony_cistatic int32_t HdfUartDeviceBind(struct HdfDeviceObject *device)
5201bd4fe43Sopenharmony_ci{
5211bd4fe43Sopenharmony_ci    HDF_LOGI("%s: entry", __func__);
5221bd4fe43Sopenharmony_ci    if (device == NULL) {
5231bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
5241bd4fe43Sopenharmony_ci    }
5251bd4fe43Sopenharmony_ci    return (UartHostCreate(device) == NULL) ? HDF_FAILURE : HDF_SUCCESS;
5261bd4fe43Sopenharmony_ci}
5271bd4fe43Sopenharmony_ci
5281bd4fe43Sopenharmony_ciint32_t HdfUartDeviceInit(struct HdfDeviceObject *device)
5291bd4fe43Sopenharmony_ci{
5301bd4fe43Sopenharmony_ci    int32_t ret;
5311bd4fe43Sopenharmony_ci    struct UartHost *host = NULL;
5321bd4fe43Sopenharmony_ci
5331bd4fe43Sopenharmony_ci    if (device == NULL) {
5341bd4fe43Sopenharmony_ci        HDF_LOGE("%s: device is null", __func__);
5351bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
5361bd4fe43Sopenharmony_ci    }
5371bd4fe43Sopenharmony_ci    host = UartHostFromDevice(device);
5381bd4fe43Sopenharmony_ci    if (host == NULL) {
5391bd4fe43Sopenharmony_ci        HDF_LOGE("%s: host is null", __func__);
5401bd4fe43Sopenharmony_ci        return HDF_FAILURE;
5411bd4fe43Sopenharmony_ci    }
5421bd4fe43Sopenharmony_ci    ret = Hi35xxAttach(host, device);
5431bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
5441bd4fe43Sopenharmony_ci        HDF_LOGE("%s: attach error", __func__);
5451bd4fe43Sopenharmony_ci        return HDF_FAILURE;
5461bd4fe43Sopenharmony_ci    }
5471bd4fe43Sopenharmony_ci    host->method = &g_uartHostMethod;
5481bd4fe43Sopenharmony_ci    HDF_LOGI("%s: uart device init success.", __func__);
5491bd4fe43Sopenharmony_ci    return ret;
5501bd4fe43Sopenharmony_ci}
5511bd4fe43Sopenharmony_ci
5521bd4fe43Sopenharmony_civoid HdfUartDeviceRelease(struct HdfDeviceObject *device)
5531bd4fe43Sopenharmony_ci{
5541bd4fe43Sopenharmony_ci    struct UartHost *host = NULL;
5551bd4fe43Sopenharmony_ci
5561bd4fe43Sopenharmony_ci    HDF_LOGI("%s: entry", __func__);
5571bd4fe43Sopenharmony_ci    if (device == NULL) {
5581bd4fe43Sopenharmony_ci        HDF_LOGE("%s: device is null", __func__);
5591bd4fe43Sopenharmony_ci        return;
5601bd4fe43Sopenharmony_ci    }
5611bd4fe43Sopenharmony_ci    host = UartHostFromDevice(device);
5621bd4fe43Sopenharmony_ci    if (host == NULL) {
5631bd4fe43Sopenharmony_ci        HDF_LOGE("%s: host is null", __func__);
5641bd4fe43Sopenharmony_ci        return;
5651bd4fe43Sopenharmony_ci    }
5661bd4fe43Sopenharmony_ci    if (host->priv != NULL) {
5671bd4fe43Sopenharmony_ci        Hi35xxDetach(host);
5681bd4fe43Sopenharmony_ci    }
5691bd4fe43Sopenharmony_ci    UartHostDestroy(host);
5701bd4fe43Sopenharmony_ci}
5711bd4fe43Sopenharmony_ci
5721bd4fe43Sopenharmony_cistruct HdfDriverEntry g_hdfUartDevice = {
5731bd4fe43Sopenharmony_ci    .moduleVersion = 1,
5741bd4fe43Sopenharmony_ci    .moduleName = "HDF_PLATFORM_UART",
5751bd4fe43Sopenharmony_ci    .Bind = HdfUartDeviceBind,
5761bd4fe43Sopenharmony_ci    .Init = HdfUartDeviceInit,
5771bd4fe43Sopenharmony_ci    .Release = HdfUartDeviceRelease,
5781bd4fe43Sopenharmony_ci};
5791bd4fe43Sopenharmony_ci
5801bd4fe43Sopenharmony_ciHDF_INIT(g_hdfUartDevice);
581