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);