1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright (C) 2021 Western Digital Corporation or its affiliates. 4 * Copyright (C) 2022 Ventana Micro Systems Inc. 5 */ 6 7#ifndef _IRQ_RISCV_IMSIC_STATE_H 8#define _IRQ_RISCV_IMSIC_STATE_H 9 10#include <linux/irqchip/riscv-imsic.h> 11#include <linux/irqdomain.h> 12#include <linux/fwnode.h> 13#include <linux/timer.h> 14 15#define IMSIC_IPI_ID 1 16#define IMSIC_NR_IPI 8 17 18struct imsic_vector { 19 /* Fixed details of the vector */ 20 unsigned int cpu; 21 unsigned int local_id; 22 /* Details saved by driver in the vector */ 23 unsigned int hwirq; 24 /* Details accessed using local lock held */ 25 bool enable; 26 struct imsic_vector *move; 27}; 28 29struct imsic_local_priv { 30 /* Local lock to protect vector enable/move variables and dirty bitmap */ 31 raw_spinlock_t lock; 32 33 /* Local dirty bitmap for synchronization */ 34 unsigned long *dirty_bitmap; 35 36#ifdef CONFIG_SMP 37 /* Local timer for synchronization */ 38 struct timer_list timer; 39#endif 40 41 /* Local vector table */ 42 struct imsic_vector *vectors; 43}; 44 45struct imsic_priv { 46 /* Device details */ 47 struct fwnode_handle *fwnode; 48 49 /* Global configuration common for all HARTs */ 50 struct imsic_global_config global; 51 52 /* Per-CPU state */ 53 struct imsic_local_priv __percpu *lpriv; 54 55 /* State of IRQ matrix allocator */ 56 raw_spinlock_t matrix_lock; 57 struct irq_matrix *matrix; 58 59 /* IRQ domains (created by platform driver) */ 60 struct irq_domain *base_domain; 61}; 62 63extern struct imsic_priv *imsic; 64 65void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val); 66 67static inline void __imsic_id_set_enable(unsigned long id) 68{ 69 __imsic_eix_update(id, 1, false, true); 70} 71 72static inline void __imsic_id_clear_enable(unsigned long id) 73{ 74 __imsic_eix_update(id, 1, false, false); 75} 76 77void imsic_local_sync_all(void); 78void imsic_local_delivery(bool enable); 79 80void imsic_vector_mask(struct imsic_vector *vec); 81void imsic_vector_unmask(struct imsic_vector *vec); 82 83static inline bool imsic_vector_isenabled(struct imsic_vector *vec) 84{ 85 return READ_ONCE(vec->enable); 86} 87 88static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec) 89{ 90 return READ_ONCE(vec->move); 91} 92 93void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec); 94 95struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id); 96 97struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask); 98void imsic_vector_free(struct imsic_vector *vector); 99 100void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind); 101void imsic_vector_debug_show_summary(struct seq_file *m, int ind); 102 103void imsic_state_online(void); 104void imsic_state_offline(void); 105int imsic_setup_state(struct fwnode_handle *fwnode); 106int imsic_irqdomain_init(void); 107 108#endif 109