1/* 2 * Copyright 2020, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#pragma once 14 15#include <utils/util.h> 16#include <platsupport/io.h> 17 18/* 19 * These macros are used to check if compat_list or init_func 20 * passed to PS_DRIVER_MODULE_DEFINE are not NULL or 0 21 */ 22#define PS_INVALID_ADDR_0 0, 23#define PS_INVALID_ADDR_NULL 0, 24#define __third_arg(_, __, val, ...) val 25#define IS_NULL(compat_list, init_func) \ 26 __IS_NULL(PS_INVALID_##compat_list, PS_INVALID_##init_func) 27// arg1 and arg2 will expand to real argument only when the pointers are NULL or 0 28// thus selecting the thrid arg will tell us whether one of them is NULL 29#define __IS_NULL(arg1, arg2) __third_arg(arg1 arg2 INVALID, INVALID, VALID) 30 31#define PS_DRIVER_MODULE_DEFINE(name, compat_list, init_func) \ 32 __PS_DRIVER_MODULE_DEFINE(IS_NULL(ADDR_##compat_list, ADDR_##init_func), \ 33 name, compat_list, init_func) 34#define __PS_DRIVER_MODULE_DEFINE(null, name, compat_list, init_func) \ 35 ____PS_DRIVER_MODULE_DEFINE(null, name, compat_list, init_func) 36#define ____PS_DRIVER_MODULE_DEFINE(null, name, compat_list, init_func) \ 37 PS_DRIVER_MODULE_DEFINE_##null(name, compat_list, init_func) 38#define PS_DRIVER_MODULE_DEFINE_INVALID(name, compat_list, init_func) \ 39 "compat_list and init_func must not be NULL" 40#define PS_DRIVER_MODULE_DEFINE_VALID(name, compat_list, init_func) \ 41 static ps_driver_module_t name = { \ 42 .compatible_list = compat_list, \ 43 .init = init_func \ 44 }; \ 45 USED SECTION("_driver_modules") ps_driver_module_t *name##_ptr = &name; 46 47#define PS_DRIVER_INIT_SUCCESS 0 48#define PS_DRIVER_INIT_DEFER 1 49 50/* 51 * Returns: 52 * - negative on error 53 * - PS_DRIVER_INIT_SUCCESS on success 54 * - PS_DRIVER_INIT_DEFER when you want to defer this initialisation function until later 55 */ 56typedef int (*ps_driver_init_fn_t)(ps_io_ops_t *io_ops, const char *device_path); 57 58typedef struct { 59 const char **compatible_list; 60 ps_driver_init_fn_t init; 61} ps_driver_module_t; 62