Gabor Ambrus | 54a1008 | 2023-08-14 21:56:06 +0200 | [diff] [blame^] | 1 | /* |
| 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 | */ |
| 18 | static 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 | */ |
| 28 | static 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 | */ |
| 38 | int 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 | |
| 64 | void 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 | } |