1a0602052SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 2a0602052SJens Wiklander /* 3a0602052SJens Wiklander * Copyright (c) 2022, Linaro Limited 4a0602052SJens Wiklander */ 5a0602052SJens Wiklander 6a0602052SJens Wiklander #include <assert.h> 767e55c51SEtienne Carriere #include <compiler.h> 8a0602052SJens Wiklander #include <config.h> 9a0602052SJens Wiklander #include <drivers/hfic.h> 10a0602052SJens Wiklander #include <hafnium.h> 11a0602052SJens Wiklander #include <kernel/interrupt.h> 12a0602052SJens Wiklander #include <kernel/panic.h> 13a0602052SJens Wiklander #include <kernel/thread.h> 14a0602052SJens Wiklander 1567e55c51SEtienne Carriere struct hfic_data { 1667e55c51SEtienne Carriere struct itr_chip chip; 1767e55c51SEtienne Carriere }; 1867e55c51SEtienne Carriere 1967e55c51SEtienne Carriere static struct hfic_data hfic_data __nex_bss; 2067e55c51SEtienne Carriere 21a0602052SJens Wiklander static void hfic_op_add(struct itr_chip *chip __unused, size_t it __unused, 22a0602052SJens Wiklander uint32_t type __unused, uint32_t prio __unused) 23a0602052SJens Wiklander { 24a0602052SJens Wiklander } 25a0602052SJens Wiklander 26a0602052SJens Wiklander static void hfic_op_enable(struct itr_chip *chip __unused, size_t it) 27a0602052SJens Wiklander { 28a0602052SJens Wiklander uint32_t res __maybe_unused = 0; 29a0602052SJens Wiklander 30a0602052SJens Wiklander res = thread_hvc(HF_INTERRUPT_ENABLE, it, HF_ENABLE, 31a0602052SJens Wiklander HF_INTERRUPT_TYPE_IRQ); 32a0602052SJens Wiklander assert(!res); 33a0602052SJens Wiklander } 34a0602052SJens Wiklander 35a0602052SJens Wiklander static void hfic_op_disable(struct itr_chip *chip __unused, size_t it) 36a0602052SJens Wiklander { 37a0602052SJens Wiklander uint32_t res __maybe_unused = 0; 38a0602052SJens Wiklander 39a0602052SJens Wiklander res = thread_hvc(HF_INTERRUPT_ENABLE, it, HF_DISABLE, 40a0602052SJens Wiklander HF_INTERRUPT_TYPE_IRQ); 41a0602052SJens Wiklander assert(!res); 42a0602052SJens Wiklander } 43a0602052SJens Wiklander 44a0602052SJens Wiklander static void hfic_op_raise_pi(struct itr_chip *chip __unused, size_t it __unused) 45a0602052SJens Wiklander { 46a0602052SJens Wiklander panic(); 47a0602052SJens Wiklander } 48a0602052SJens Wiklander 49a0602052SJens Wiklander static void hfic_op_raise_sgi(struct itr_chip *chip __unused, 50a0602052SJens Wiklander size_t it __unused, uint8_t cpu_mask __unused) 51a0602052SJens Wiklander { 52a0602052SJens Wiklander panic(); 53a0602052SJens Wiklander } 54a0602052SJens Wiklander 55a0602052SJens Wiklander static void hfic_op_set_affinity(struct itr_chip *chip __unused, 56a0602052SJens Wiklander size_t it __unused, uint8_t cpu_mask __unused) 57a0602052SJens Wiklander { 58a0602052SJens Wiklander panic(); 59a0602052SJens Wiklander } 60a0602052SJens Wiklander 61a0602052SJens Wiklander static const struct itr_ops hfic_ops = { 62a0602052SJens Wiklander .add = hfic_op_add, 6359feef28SEtienne Carriere .mask = hfic_op_disable, 6459feef28SEtienne Carriere .unmask = hfic_op_enable, 65a0602052SJens Wiklander .enable = hfic_op_enable, 66a0602052SJens Wiklander .disable = hfic_op_disable, 67a0602052SJens Wiklander .raise_pi = hfic_op_raise_pi, 68a0602052SJens Wiklander .raise_sgi = hfic_op_raise_sgi, 69a0602052SJens Wiklander .set_affinity = hfic_op_set_affinity, 70a0602052SJens Wiklander }; 71a0602052SJens Wiklander 7267e55c51SEtienne Carriere void hfic_init(void) 73a0602052SJens Wiklander { 7467e55c51SEtienne Carriere hfic_data.chip.ops = &hfic_ops; 7501980f3fSEtienne Carriere interrupt_main_init(&hfic_data.chip); 76a0602052SJens Wiklander } 77a0602052SJens Wiklander 78358bf47cSEtienne Carriere /* Override interrupt_main_handler() with driver implementation */ 79358bf47cSEtienne Carriere void interrupt_main_handler(void) 80a0602052SJens Wiklander { 81a0602052SJens Wiklander uint32_t id = 0; 82a0602052SJens Wiklander uint32_t res __maybe_unused = 0; 83a0602052SJens Wiklander 84a0602052SJens Wiklander id = thread_hvc(HF_INTERRUPT_GET, 0, 0, 0); 85a0602052SJens Wiklander if (id == HF_INVALID_INTID) { 86a0602052SJens Wiklander DMSG("ignoring invalid interrupt %#"PRIx32, id); 87a0602052SJens Wiklander return; 88a0602052SJens Wiklander } 89a0602052SJens Wiklander 90*99e2612cSEtienne Carriere interrupt_call_handlers(&hfic_data.chip, id); 91*99e2612cSEtienne Carriere 92a0602052SJens Wiklander res = thread_hvc(HF_INTERRUPT_DEACTIVATE, id, id, 0); 93a0602052SJens Wiklander assert(!res); 94a0602052SJens Wiklander } 95