1/* 2 * Copyright 2019, 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 <libfdt.h> 16 17#include <platsupport/irq.h> 18#include <platsupport/fdt.h> 19#include <utils/util.h> 20 21/* Macro to streamline process of declaring new interrupt parsing modules */ 22#define DEFINE_IRQCHIP_PARSER(instance, compatible_strings, parser_func) \ 23 static ps_irqchip_t instance = { \ 24 .compatible_list = compatible_strings, \ 25 .parser_fn = parser_func \ 26 }; \ 27 USED SECTION("_ps_irqchips") ps_irqchip_t *instance##_ptr = &instance 28 29/* 30 * Expected function type of the interrupt parsing functions. 31 * 32 * Given offset of the device node in the FDT, this should read the interrupts 33 * property, parse it and call the callback function on each interrupt instance 34 * of the property. 35 * 36 * @param dtb_blob A blob of a platform's FDT. 37 * @param node_offset Offset to the device node to be parsed. 38 * @param intr_controller_phandle Phandle to the interrupt controller that handles the interrupts of the device. 39 * @param callback Pointer to a callback function that is called at each interrupt instance in the property. 40 * @param token Pointer to a token that is passed into the callback each time it is called. 41 * 42 * @returns 0 on success, otherwise an error code 43 */ 44typedef int (*ps_irqchip_parse_fn_t)(char *dtb_blob, int node_offset, int intr_controller_phandle, 45 irq_walk_cb_fn_t callback, void *token); 46 47/* 48 * Struct describing a IRQ parser module. 49 */ 50typedef struct ps_irqchip { 51 /* Array of compatibility strings for interrupt 52 * controllers that the module can handle, should be NULL terminated, e.g. 53 * foo = { "abc", NULL } */ 54 char **compatible_list; 55 /* Pointer to the parser function for this module */ 56 ps_irqchip_parse_fn_t parser_fn; 57} ps_irqchip_t; 58 59/* 60 * Helper function that retrieves a pointer to the interrupts property of a device. 61 * 62 * @param dtb_blob A blob of a platform's FDT. 63 * @param node_offset Offset to the desired device node. 64 * @param is_extended Pointer to a boolean that will have true written to it if the 'interrupts-extended' property was found, false otherwise 65 * @param prop_len Pointer to an int that will have the total length of the interrupts property written to it 66 */ 67static inline const void *get_interrupts_prop(char *dtb_blob, int node_offset, bool *is_extended, int *prop_len) 68{ 69 ZF_LOGF_IF(!is_extended || !prop_len, "Ret args are NULL!"); 70 const void *interrupts_prop = fdt_getprop(dtb_blob, node_offset, "interrupts-extended", prop_len); 71 if (interrupts_prop) { 72 *is_extended = true; 73 return interrupts_prop; 74 } 75 76 interrupts_prop = fdt_getprop(dtb_blob, node_offset, "interrupts", prop_len); 77 if (interrupts_prop) { 78 *is_extended = false; 79 return interrupts_prop; 80 } 81 82 return NULL; 83} 84