• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
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 #include "device_resource_if.h"
16 #include "hdf_device_desc.h"
17 #include "osal_io.h"
18 #include "osal.h"
19 
20 #include "uart_if.h"
21 #include "uart_core.h"
22 #include "uart_dev.h"
23 
24 #include "securec.h"
25 
26 #include "stm32mp1_uart_hw.h"
27 
28 #define HDF_LOG_TAG Mp1xxUart
29 
30 #ifdef LOSCFG_QUICK_START
31 __attribute__((section(".data"))) uint32_t g_uart_fputc_en = 0;
32 #else
33 __attribute__((section(".data"))) uint32_t g_uart_fputc_en = 1;
34 #endif
35 
36 static SPIN_LOCK_INIT(g_uartOutputSpin);
37 
38 // for default out put
UartPuts(const CHAR * s,UINT32 len,BOOL isLock)39 VOID UartPuts(const CHAR *s, UINT32 len, BOOL isLock)
40 {
41     uint32_t intSave;
42     void *base = (void *)IO_DEVICE_ADDR(DEBUG_UART_BASE);
43 
44     if (isLock) {
45         LOS_SpinLockSave(&g_uartOutputSpin, &intSave);
46     }
47 
48     Mp1xxUartHwPuts(base, (char *)s, len);
49 
50     if (isLock) {
51         LOS_SpinUnlockRestore(&g_uartOutputSpin, intSave);
52     }
53 }
54 
stm32mp1_uart_recv_data_handle(struct Mp1xxUart * uart,char * buf,uint32_t size)55 static uint32_t stm32mp1_uart_recv_data_handle(struct Mp1xxUart *uart, char *buf, uint32_t size)
56 {
57     uint32_t ret;
58     struct Mp1xxUartRxCtl *rx_ctl = &(uart->rx_ctl);
59 
60     // write data to recv buf
61     ret = KRecvBufWrite(&(rx_ctl->rx_krb), buf, size);
62     // if write success, post sem
63     if (ret != 0)
64         OsalSemPost(&(rx_ctl->rx_sem));
65 
66     return HDF_SUCCESS;
67 }
68 
stm32mp1_uart_rx_ctl_init(struct Mp1xxUartRxCtl * rx_ctl,uint32_t buf_size)69 static int32_t stm32mp1_uart_rx_ctl_init(struct Mp1xxUartRxCtl *rx_ctl, uint32_t buf_size)
70 {
71     char *buf = NULL;
72 
73     // 获取接收缓冲区
74     buf = OsalMemAlloc(buf_size);
75     if (buf == NULL) {
76         HDF_LOGE("%s: create recv buf fail.\r\n", __func__);
77         return HDF_FAILURE;
78     }
79     rx_ctl->fifo = buf;
80 
81     OsalSemInit(&(rx_ctl->rx_sem), 0);
82 
83     // 初始化KRecvBuf
84     KRecvBufInit(&(rx_ctl->rx_krb), rx_ctl->fifo, buf_size);
85 
86     // 串口数据接收处理函数
87     rx_ctl->stm32mp1_uart_recv_hook = stm32mp1_uart_recv_data_handle;
88 
89     return HDF_SUCCESS;
90 }
91 
stm32mp1_uart_rx_ctl_deinit(struct Mp1xxUartRxCtl * rx_ctl)92 static int32_t stm32mp1_uart_rx_ctl_deinit(struct Mp1xxUartRxCtl *rx_ctl)
93 {
94     char *buf = rx_ctl->fifo;
95 
96     rx_ctl->stm32mp1_uart_recv_hook = NULL;
97 
98     KRecvBufDeinit(&(rx_ctl->rx_krb));
99     OsalSemDestroy(&(rx_ctl->rx_sem));
100 
101     if (buf) {
102         OsalMemFree(buf);
103     }
104 
105     return HDF_SUCCESS;
106 }
107 
108 // update regs
stm32mp1_uart_config(struct Mp1xxUart * uart)109 static int32_t stm32mp1_uart_config(struct Mp1xxUart *uart)
110 {
111     int32_t ret;
112     struct UartAttribute *attr = (struct UartAttribute *)uart->priv;
113 
114     // set bits
115     ret = Mp1xxUartHwDataBits(uart, attr->dataBits);
116 
117     // set stop bits
118     ret |= Mp1xxUartHwStopBits(uart, attr->stopBits);
119 
120     // set parity
121     ret |= Mp1xxUartHwParity(uart, attr->parity);
122 
123     return ret;
124 }
125 
126 // get clock source real rate
Mp1xxUartGetClock(struct Mp1xxUart * uart)127 static inline int32_t Mp1xxUartGetClock(struct Mp1xxUart *uart)
128 {
129     int ret = HDF_SUCCESS;
130 
131     /*
132         if "clock_source" is set, use the real rate of clock source
133         otherwise, use the default clock rate
134     */
135     if (uart->clock_source != NULL) {
136         ret = HDF_SUCCESS;
137     }
138 
139     return ret;
140 }
141 
Mp1xxUartOpen(struct UartHost * host)142 static int32_t Mp1xxUartOpen(struct UartHost *host)
143 {
144     int32_t ret = HDF_SUCCESS;
145     struct Mp1xxUart *uart = (struct Mp1xxUart *)host->priv;
146     struct Mp1xxUartRxCtl *rx_ctl = &(uart->rx_ctl);
147 
148     OsalSpinLock(&(uart->lock));
149 
150     if (uart->state == UART_STATE_NOT_OPENED) {
151         uart->state = UART_STATE_OPENING;
152 
153         // 1. disable
154         Mp1xxUartHwEnable(uart, false);
155 
156         // 2. update attr
157         ret = stm32mp1_uart_config(uart);
158         if (ret != HDF_SUCCESS) {
159             HDF_LOGE("%s: uart config fail.", __func__);
160             goto stm32mp1_uart_open_out;
161         }
162 
163         // 3. update baudrate
164         Mp1xxUartHwBaudrate(uart, uart->baudrate);
165 
166         // 4. init rx_ctl
167         ret = stm32mp1_uart_rx_ctl_init(rx_ctl, uart->rx_buf_size);
168         if (ret != HDF_SUCCESS) {
169             HDF_LOGE("%s: rx ctl init fail.", __func__);
170             goto stm32mp1_uart_open_out;
171         }
172 
173         // 5. enable uart rx
174         ret = Mp1xxUartHwRxEnable(uart, true);
175         if (ret != HDF_SUCCESS) {
176             HDF_LOGE("%s: rx enable fail.", __func__);
177             goto stm32mp1_uart_open_out;
178         }
179 
180         // 6. enable uart
181         Mp1xxUartHwEnable(uart, true);
182 
183         Mp1xxUartDump(uart);
184     }
185 
186 stm32mp1_uart_open_out:
187 
188     // current uart is opened
189     if (ret == HDF_SUCCESS) {
190         uart->state = UART_STATE_USEABLE;
191         uart->open_count++;
192     } else {
193         uart->state = UART_STATE_NOT_OPENED;
194     }
195 
196     OsalSpinUnlock(&(uart->lock));
197 
198     return ret;
199 }
200 
Mp1xxUartClose(struct UartHost * host)201 static int32_t Mp1xxUartClose(struct UartHost *host)
202 {
203     int32_t ret = HDF_SUCCESS;
204     struct Mp1xxUart *uart = (struct Mp1xxUart *)host->priv;
205     struct Mp1xxUartRxCtl *rx_ctl = &(uart->rx_ctl);
206 
207     OsalSpinLock(&(uart->lock));
208 
209     if (--uart->open_count > 0) {
210         goto stm32mp1_uart_close_out;
211     }
212 
213     // 失能设备
214     Mp1xxUartHwEnable(uart, false);
215 
216     // 关闭串口接收
217     Mp1xxUartHwRxEnable(uart, false);
218 
219     // 注销接收控制器
220     ret = stm32mp1_uart_rx_ctl_deinit(rx_ctl);
221 
222     uart->state = UART_STATE_NOT_OPENED;
223 
224 stm32mp1_uart_close_out:
225 
226     OsalSpinUnlock(&(uart->lock));
227 
228     return ret;
229 }
230 
Mp1xxUartRead(struct UartHost * host,uint8_t * data,uint32_t size)231 static int32_t Mp1xxUartRead(struct UartHost *host, uint8_t *data, uint32_t size)
232 {
233     int32_t ret = HDF_SUCCESS;
234     struct Mp1xxUart *uart = (struct Mp1xxUart *)host->priv;
235     struct Mp1xxUartRxCtl *rx_ctl = &(uart->rx_ctl);
236 
237     OsalSpinLock(&(uart->lock));
238 
239     if (uart->state != UART_STATE_USEABLE) {
240         HDF_LOGE("%s: device not opened.\r\n", __func__);
241         ret = HDF_ERR_IO;
242         goto stm32mp1_uart_read_out;
243     }
244 
245     // 如果缓冲区中没有数据可以读取, 且当前是阻塞模式, 等待数据接收
246     while ((KRecvBufUsedSize(&(rx_ctl->rx_krb)) == 0)
247                 && (uart->flags & UART_FLG_RD_BLOCK)) {
248         OsalSpinUnlock(&(uart->lock));
249         OsalSemWait(&(rx_ctl->rx_sem), OSAL_WAIT_FOREVER);
250         OsalSpinLock(&(uart->lock));
251     }
252 
253     // 接收数据
254     ret = KRecvBufRead(&(rx_ctl->rx_krb), (char *)data, size);
255 
256 stm32mp1_uart_read_out:
257 
258     OsalSpinUnlock(&(uart->lock));
259 
260     return ret;
261 }
262 
Mp1xxUartWrite(struct UartHost * host,uint8_t * data,uint32_t size)263 static int32_t Mp1xxUartWrite(struct UartHost *host, uint8_t *data, uint32_t size)
264 {
265     int32_t ret;
266     uint32_t intSave;
267     uint32_t send_size = 0, cur_size = 0;
268     struct Mp1xxUart *uart = (struct Mp1xxUart *)host->priv;
269 
270     if (host == NULL || host->priv == NULL || data == NULL) {
271         HDF_LOGE("%s: invalid parameter.\r\n", __func__);
272         return HDF_ERR_INVALID_PARAM;
273     }
274 
275     OsalSpinLock(&(uart->lock));
276 
277     // current device is debug uart, get global output lock
278     if (uart->debug_uart) {
279         LOS_SpinLockSave(&g_uartOutputSpin, &intSave);
280     }
281 
282     if (uart->state != UART_STATE_USEABLE) {
283         HDF_LOGE("%s: device not opened.\r\n", __func__);
284         ret = HDF_ERR_IO;
285         goto stm32mp1_uart_write_out;
286     }
287 
288     while (send_size < size) {
289         // 获取本次传输的大小
290         cur_size = ((size - send_size) >= TX_BUF_SIZE) ? TX_BUF_SIZE : (size - send_size);
291 
292         ret = LOS_CopyToKernel((void *)uart->tx_buf, TX_BUF_SIZE, (void *)(data + send_size), cur_size);
293         if (ret != 0) {
294             HDF_LOGE("%s: CopyToKernel fail, size : %d, ret : %d.\r\n", __func__, cur_size, ret);
295             ret = HDF_FAILURE;
296             goto stm32mp1_uart_write_out;
297         }
298 
299         Mp1xxUartHwPuts((void *)uart->base, uart->tx_buf, cur_size);
300 
301         send_size += cur_size;
302     }
303 
304 stm32mp1_uart_write_out:
305 
306     if (uart->debug_uart) {
307         LOS_SpinUnlockRestore(&g_uartOutputSpin, intSave);
308     }
309 
310     OsalSpinUnlock(&(uart->lock));
311 
312     return ret;
313 }
314 
Mp1xxUartGetBaud(struct UartHost * host,uint32_t * baudRate)315 static int32_t Mp1xxUartGetBaud(struct UartHost *host, uint32_t *baudRate)
316 {
317     int32_t ret = HDF_SUCCESS;
318     struct Mp1xxUart *uart = NULL;
319     if (host == NULL || host->priv == NULL || baudRate == NULL) {
320         HDF_LOGE("%s: invalid parameter", __func__);
321         return HDF_ERR_INVALID_PARAM;
322     }
323     uart = (struct Mp1xxUart *)host->priv;
324 
325     OsalSpinLock(&(uart->lock));
326 
327     if (uart->state != UART_STATE_USEABLE) {
328         ret = HDF_FAILURE;
329         goto stm32mp1_uart_get_baud_out;
330     }
331 
332     *baudRate = uart->baudrate;
333 
334 stm32mp1_uart_get_baud_out:
335     OsalSpinUnlock(&(uart->lock));
336     return ret;
337 }
338 
Mp1xxUartSetBaud(struct UartHost * host,uint32_t baudRate)339 static int32_t Mp1xxUartSetBaud(struct UartHost *host, uint32_t baudRate)
340 {
341     int32_t ret = HDF_SUCCESS;
342     struct Mp1xxUart *uart = (struct Mp1xxUart *)host->priv;
343 
344     OsalSpinLock(&(uart->lock));
345 
346     if (uart->state != UART_STATE_USEABLE) {
347         ret = HDF_FAILURE;
348         goto stm32mp1_uart_set_baud_out;
349     }
350 
351     // set new baudrate
352     if (uart->baudrate != baudRate) {
353         // 1. disable uart
354         Mp1xxUartHwEnable(uart, false);
355 
356         // 2. update clock rate
357         Mp1xxUartGetClock(uart);
358 
359         // 3. set regs
360         Mp1xxUartHwBaudrate(uart, baudRate);
361 
362         // 4. enable uart
363         Mp1xxUartHwEnable(uart, true);
364 
365         uart->baudrate = baudRate;
366     }
367 
368 stm32mp1_uart_set_baud_out:
369     OsalSpinUnlock(&(uart->lock));
370     return ret;
371 }
372 
Mp1xxUartGetAttribute(struct UartHost * host,struct UartAttribute * attribute)373 static int32_t Mp1xxUartGetAttribute(struct UartHost *host, struct UartAttribute *attribute)
374 {
375     int32_t ret = HDF_SUCCESS;
376     struct Mp1xxUart *uart = NULL;
377     struct UartAttribute *attr = NULL;
378     if (host == NULL || host->priv == NULL || attribute == NULL) {
379         HDF_LOGE("%s: invalid parameter", __func__);
380         return HDF_ERR_INVALID_PARAM;
381     }
382     uart = (struct Mp1xxUart *)host->priv;
383     attr = (struct UartAttribute *)uart->priv;
384 
385     OsalSpinLock(&(uart->lock));
386 
387     memcpy_s(attribute, sizeof(struct UartAttribute), attr, sizeof(struct UartAttribute));
388 
389     OsalSpinUnlock(&(uart->lock));
390 
391     return ret;
392 }
393 
Mp1xxUartSetAttribute(struct UartHost * host,struct UartAttribute * attribute)394 static int32_t Mp1xxUartSetAttribute(struct UartHost *host, struct UartAttribute *attribute)
395 {
396     int32_t ret = HDF_SUCCESS;
397     struct Mp1xxUart *uart = NULL;
398     struct UartAttribute *attr = NULL;
399     if (host == NULL || host->priv == NULL || attribute == NULL) {
400         HDF_LOGE("%s: invalid parameter", __func__);
401         return HDF_ERR_INVALID_PARAM;
402     }
403     uart = (struct Mp1xxUart *)host->priv;
404     attr = (struct UartAttribute *)uart->priv;
405 
406     OsalSpinLock(&(uart->lock));
407 
408     // 保存新配置
409     memcpy_s(attr, sizeof(struct UartAttribute), attribute, sizeof(struct UartAttribute));
410 
411     // 根据新配置,更新寄存器
412     ret = stm32mp1_uart_config(uart);
413 
414     OsalSpinUnlock(&(uart->lock));
415     return ret;
416 }
417 
Mp1xxUartSetTransMode(struct UartHost * host,enum UartTransMode mode)418 static int32_t Mp1xxUartSetTransMode(struct UartHost *host, enum UartTransMode mode)
419 {
420     int32_t ret = HDF_SUCCESS;
421     struct Mp1xxUart *uart = (struct Mp1xxUart *)host->priv;
422     struct Mp1xxUartRxCtl *rx_ctl = &(uart->rx_ctl);
423 
424     OsalSpinLock(&(uart->lock));
425 
426     switch (mode) {
427         case UART_MODE_RD_BLOCK:
428             uart->flags |= UART_FLG_RD_BLOCK;
429             break;
430         case UART_MODE_RD_NONBLOCK:
431             uart->flags &= ~UART_FLG_RD_BLOCK;
432             OsalSemPost(&(rx_ctl->rx_sem));
433             break;
434         default:
435             HDF_LOGE("%s: unsupport mode %#x.\r\n", __func__, mode);
436             break;
437     }
438 
439     OsalSpinUnlock(&(uart->lock));
440 
441     return ret;
442 }
443 
444 struct UartHostMethod g_stm32mp1_uart_ops = {
445     .Init = Mp1xxUartOpen,
446     .Deinit = Mp1xxUartClose,
447     .Read = Mp1xxUartRead,
448     .Write = Mp1xxUartWrite,
449     .GetBaud = Mp1xxUartGetBaud,
450     .SetBaud = Mp1xxUartSetBaud,
451     .GetAttribute = Mp1xxUartGetAttribute,
452     .SetAttribute = Mp1xxUartSetAttribute,
453     .SetTransMode = Mp1xxUartSetTransMode,
454     .pollEvent = NULL
455 };
456 
stm32mp1_uart_read_drs(struct Mp1xxUart * uart,const struct DeviceResourceNode * node)457 static int32_t stm32mp1_uart_read_drs(struct Mp1xxUart *uart, const struct DeviceResourceNode *node)
458 {
459     int32_t ret;
460     struct DeviceResourceIface *drsOps = NULL;
461 
462     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
463     if (drsOps == NULL || drsOps->GetUint32 == NULL) {
464         HDF_LOGE("%s: invalid drs ops!\r\n", __func__);
465         return HDF_FAILURE;
466     }
467 
468     // num
469     ret = drsOps->GetUint32(node, "num", &uart->num, 0);
470     if (ret != HDF_SUCCESS) {
471         HDF_LOGE("%s: read num fail!\r\n", __func__);
472         return ret;
473     }
474 
475     // reg_base
476     ret = drsOps->GetUint32(node, "reg_base", &uart->phy_base, 0);
477     if (ret != HDF_SUCCESS) {
478         HDF_LOGE("%s: read reg_base fail!\r\n", __func__);
479         return ret;
480     }
481 
482     // reg_step
483     ret = drsOps->GetUint32(node, "reg_step", &uart->reg_step, 0);
484     if (ret != HDF_SUCCESS) {
485         HDF_LOGE("%s: read reg_step fail!\r\n", __func__);
486         return ret;
487     }
488 
489     // flags
490     ret = drsOps->GetUint32(node, "flags", &uart->flags, 0);
491     if (ret != HDF_SUCCESS) {
492         HDF_LOGE("%s: read flags fail!\r\n", __func__);
493         return ret;
494     }
495 
496     // baudrate
497     ret = drsOps->GetUint32(node, "baudrate", &uart->baudrate, 0);
498     if (ret != HDF_SUCCESS) {
499         HDF_LOGE("%s: read baudrate fail!\r\n", __func__);
500         return ret;
501     }
502 
503     // rx_buf_size
504     ret = drsOps->GetUint32(node, "rx_buf_size", &uart->rx_buf_size, RX_BUF_SIZE);
505     if (ret != HDF_SUCCESS) {
506         HDF_LOGE("%s: read rx_buf_size fail!\r\n", __func__);
507         return ret;
508     }
509 
510     // irq_num
511     ret = drsOps->GetUint32(node, "interrupt", &uart->irq_num, 0);
512     if (ret != HDF_SUCCESS) {
513         HDF_LOGE("%s: read interrupt fail!\r\n", __func__);
514         return ret;
515     }
516 
517     // clock_rate
518     ret = drsOps->GetUint32(node, "clock_rate", &uart->clock_rate, 0);
519     if (ret != HDF_SUCCESS) {
520         HDF_LOGE("%s: read clock_rate fail!\r\n", __func__);
521         return ret;
522     }
523 
524     // fifo_en
525     uart->fifo_en = drsOps->GetBool(node, "fifo_en");
526 
527     return HDF_SUCCESS;
528 }
529 
Mp1xxUartBind(struct HdfDeviceObject * device)530 static int32_t Mp1xxUartBind(struct HdfDeviceObject *device)
531 {
532     int32_t ret;
533     struct UartHost *host = NULL;
534     struct Mp1xxUart *uart = NULL;
535     struct UartAttribute *attr = NULL;
536 
537     if (device == NULL || device->property == NULL) {
538         HDF_LOGE("%s: device or property is null!.\r\n", __func__);
539         return HDF_ERR_INVALID_OBJECT;
540     }
541 
542     // 创建UartHost
543     host = UartHostCreate(device);
544     if (host == NULL) {
545         HDF_LOGE("%s: UartHostCreate fail!.\r\n", __func__);
546         return HDF_ERR_MALLOC_FAIL;
547     }
548 
549     // 申请内存空间
550     uart = (struct Mp1xxUart *)OsalMemCalloc(sizeof(struct Mp1xxUart));
551     if (uart == NULL) {
552         HDF_LOGE("%s: malloc uart fail!.\r\n", __func__);
553         return HDF_ERR_MALLOC_FAIL;
554     }
555 
556     // attr
557     attr = (struct UartAttribute *)OsalMemCalloc(sizeof(struct UartAttribute));
558     if (uart == NULL) {
559         HDF_LOGE("%s: malloc attr fail!.\r\n", __func__);
560         OsalMemFree(uart);
561         return HDF_ERR_MALLOC_FAIL;
562     }
563     uart->priv = (void *)attr;
564 
565     // 解析配置
566     ret = stm32mp1_uart_read_drs(uart, device->property);
567     if (ret != HDF_SUCCESS) {
568         HDF_LOGE("%s: read drs fail:%d.\r\n", __func__, ret);
569         OsalMemFree(attr);
570         OsalMemFree(uart);
571         return ret;
572     }
573 
574     // 寄存器映射
575     uart->base = OsalIoRemap(uart->phy_base, uart->reg_step);
576     if (uart->base == NULL) {
577         HDF_LOGE("%s: ioremap regbase fail!.\r\n", __func__);
578         OsalMemFree(attr);
579         OsalMemFree(uart);
580         return HDF_ERR_IO;
581     }
582 
583     // 填充私有属性
584     host->method = &g_stm32mp1_uart_ops;
585     host->priv = uart;
586     host->num = uart->num;
587 
588     return HDF_SUCCESS;
589 }
590 
Mp1xxUartInit(struct HdfDeviceObject * device)591 static int32_t Mp1xxUartInit(struct HdfDeviceObject *device)
592 {
593     int32_t ret = HDF_SUCCESS;
594     struct UartHost *host = NULL;
595     struct Mp1xxUart *uart = NULL;
596 
597     if (device == NULL) {
598         HDF_LOGE("%s: device is null.\r\n", __func__);
599         return HDF_FAILURE;
600     }
601 
602     host = UartHostFromDevice(device);
603     if (host == NULL) {
604         HDF_LOGE("%s: host is null.\r\n", __func__);
605         return HDF_FAILURE;
606     }
607 
608     uart = (struct Mp1xxUart *)host->priv;
609     if (uart == NULL) {
610         HDF_LOGE("%s: uart is null.\r\n", __func__);
611         return HDF_FAILURE;
612     }
613 
614     // 1. spin init
615     ret = OsalSpinInit(&(uart->lock));
616     if (ret != HDF_SUCCESS) {
617         HDF_LOGE("%s: OsalSpinInit fail.\r\n", __func__);
618         return HDF_FAILURE;
619     }
620     OsalSpinLock(&(uart->lock));
621 
622     Mp1xxUartDump(uart);
623 
624     // 2. get new clock rate
625     Mp1xxUartGetClock(uart);
626 
627     // 3. disable uart
628     Mp1xxUartHwEnable(uart, false);
629 
630     // 4. fifo mode enable
631     Mp1xxUartHwFifoEnable(uart, uart->fifo_en);
632 
633     // 5. register irq
634     snprintf_s(uart->irq_name, UART_IRQ_NAME_SIZE, UART_IRQ_NAME_SIZE - 1, "uart%d_irq", uart->num);
635     ret = OsalRegisterIrq(uart->irq_num, 0, Mp1xxUartIrqHandler, uart->irq_name, uart);
636     if (ret != HDF_SUCCESS) {
637         HDF_LOGE("%s: OsalRegisterIrq fail.\r\n", __func__);
638         ret = HDF_FAILURE;
639         goto stm32mp1_uart_init_out;
640     }
641 
642     // 6. register uart device
643     UartAddDev(host);
644 
645     // 7. 当前串口是否作为调试串口(如果是调试串口,打印时需要获取全局锁)
646     if (uart->phy_base == DEBUG_UART_BASE)
647         uart->debug_uart = true;
648 
649 stm32mp1_uart_init_out:
650     OsalSpinUnlock(&(uart->lock));
651     return ret;
652 }
653 
Mp1xxUartRelease(struct HdfDeviceObject * device)654 static void Mp1xxUartRelease(struct HdfDeviceObject *device)
655 {
656     struct UartHost *host = NULL;
657     struct Mp1xxUart *uart = NULL;
658 
659     if (device == NULL) {
660         HDF_LOGE("%s: device is null.\r\n", __func__);
661         return;
662     }
663 
664     host = UartHostFromDevice(device);
665     if (host == NULL) {
666         HDF_LOGE("%s: host is null.\r\n", __func__);
667         return;
668     }
669 
670     uart = (struct Mp1xxUart *)host->priv;
671     if (uart == NULL) {
672         HDF_LOGE("%s: uart is null.\r\n", __func__);
673         return;
674     }
675 
676     OsalSpinLock(&(uart->lock));
677 
678     if (uart->state != UART_STATE_NOT_OPENED) {
679         HDF_LOGE("%s: device is opened!!!.\r\n", __func__);
680         OsalSpinUnlock(&(uart->lock));
681         return;
682     }
683 
684     UartRemoveDev(host);
685 
686     OsalUnregisterIrq(uart->irq_num, uart);
687 
688     // disable
689     Mp1xxUartHwEnable(uart, false);
690 
691     OsalSpinUnlock(&(uart->lock));
692     OsalSpinDestroy(&(uart->lock));
693 
694     // unmap
695     OsalIoUnmap((void *)uart->base);
696 
697     OsalMemFree(uart->priv);
698     OsalMemFree(uart);
699 
700     UartHostDestroy(host);
701 }
702 
703 struct HdfDriverEntry g_hdf_driver_uart_entry = {
704     .moduleVersion = 1,
705     .Bind = Mp1xxUartBind,
706     .Init = Mp1xxUartInit,
707     .Release = Mp1xxUartRelease,
708     .moduleName = "stm32mp1_uart",
709 };
710 HDF_INIT(g_hdf_driver_uart_entry);