blob: 8f43214357ddeca8d0077948d2ac27e04cfd24d5 [file] [log] [blame]
Gabor Ambrus54a10082023-08-14 21:56:06 +02001/*
2 * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <assert.h>
7#include <config/interface/config_store.h>
8#include <platform/interface/device_region.h>
9#include <platform/interface/uart.h>
10#include <psa/error.h>
11#include <stdlib.h>
12
13#include "uart_decl.h"
14
15/*
16 * Flush the UART
17 */
18static int uart_flush(platform_uart_context *context)
19{
20 uflush(context->base_address);
21
22 return 0;
23}
24
25/*
26 * Send character to UART
27 */
28static int uart_putc(platform_uart_context *context, uint8_t ch)
29{
30 uputc(ch, context->base_address);
31
32 return 0;
33}
34
35/*
36 * Initialize the driver for the UART
37 */
38int platform_uart_create(struct platform_uart_driver *driver, int instance)
39{
40 static const struct platform_uart_iface iface = { .uart_flush = uart_flush,
41 .uart_putc = uart_putc };
42
43 struct device_region device_region;
44
45 if (!config_store_query(CONFIG_CLASSIFIER_DEVICE_REGION, "uart", instance, &device_region,
46 sizeof(device_region)))
47 return PSA_STATUS_HARDWARE_FAILURE;
48
49 driver->context = malloc(sizeof(platform_uart_context));
50
51 if (driver->context) {
52 /* Set only if context was created */
53 driver->iface = &iface;
54
55 /* A device region has been provided, possibly from an external configuration. */
56 ((platform_uart_context *)driver->context)->base_address = device_region.base_addr;
57
58 return uart_init(device_region.base_addr);
59 }
60
61 return -1;
62}
63
64void platform_uart_destroy(struct platform_uart_driver *driver)
65{
66 if (driver->context) {
67 uart_deinit(((platform_uart_context *) driver->context)->base_address);
68 free(driver->context);
69 driver->context = NULL;
70 }
71
72 driver->iface = NULL;
73}