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 18 struct 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 29 struct 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 45 struct 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 63 extern struct imsic_priv *imsic; 64 65 void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val); 66 67 static inline void __imsic_id_set_enable(unsigned long id) 68 { 69 __imsic_eix_update(id, 1, false, true); 70 } 71 72 static inline void __imsic_id_clear_enable(unsigned long id) 73 { 74 __imsic_eix_update(id, 1, false, false); 75 } 76 77 void imsic_local_sync_all(void); 78 void imsic_local_delivery(bool enable); 79 80 void imsic_vector_mask(struct imsic_vector *vec); 81 void imsic_vector_unmask(struct imsic_vector *vec); 82 83 static inline bool imsic_vector_isenabled(struct imsic_vector *vec) 84 { 85 return READ_ONCE(vec->enable); 86 } 87 88 static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec) 89 { 90 return READ_ONCE(vec->move); 91 } 92 93 void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec); 94 95 struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id); 96 97 struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask); 98 void imsic_vector_free(struct imsic_vector *vector); 99 100 void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind); 101 void imsic_vector_debug_show_summary(struct seq_file *m, int ind); 102 103 void imsic_state_online(void); 104 void imsic_state_offline(void); 105 int imsic_setup_state(struct fwnode_handle *fwnode); 106 int imsic_irqdomain_init(void); 107 108 #endif 109