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 irq; 24 /* Details accessed using local lock held */ 25 bool enable; 26 struct imsic_vector *move_next; 27 struct imsic_vector *move_prev; 28 }; 29 30 struct imsic_local_priv { 31 /* Local lock to protect vector enable/move variables and dirty bitmap */ 32 raw_spinlock_t lock; 33 34 /* Local dirty bitmap for synchronization */ 35 unsigned long *dirty_bitmap; 36 37 #ifdef CONFIG_SMP 38 /* Local timer for synchronization */ 39 struct timer_list timer; 40 #endif 41 42 /* Local vector table */ 43 struct imsic_vector *vectors; 44 }; 45 46 struct imsic_priv { 47 /* Device details */ 48 struct fwnode_handle *fwnode; 49 50 /* Global configuration common for all HARTs */ 51 struct imsic_global_config global; 52 53 /* Per-CPU state */ 54 struct imsic_local_priv __percpu *lpriv; 55 56 /* State of IRQ matrix allocator */ 57 raw_spinlock_t matrix_lock; 58 struct irq_matrix *matrix; 59 60 /* IRQ domains (created by platform driver) */ 61 struct irq_domain *base_domain; 62 }; 63 64 extern struct imsic_priv *imsic; 65 66 void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val); 67 68 static inline void __imsic_id_set_enable(unsigned long id) 69 { 70 __imsic_eix_update(id, 1, false, true); 71 } 72 73 static inline void __imsic_id_clear_enable(unsigned long id) 74 { 75 __imsic_eix_update(id, 1, false, false); 76 } 77 78 void imsic_local_sync_all(bool force_all); 79 void imsic_local_delivery(bool enable); 80 81 void imsic_vector_mask(struct imsic_vector *vec); 82 void imsic_vector_unmask(struct imsic_vector *vec); 83 84 static inline bool imsic_vector_isenabled(struct imsic_vector *vec) 85 { 86 return READ_ONCE(vec->enable); 87 } 88 89 static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec) 90 { 91 return READ_ONCE(vec->move_prev); 92 } 93 94 void imsic_vector_force_move_cleanup(struct imsic_vector *vec); 95 void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec); 96 97 struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id); 98 99 struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpumask *mask); 100 void imsic_vector_free(struct imsic_vector *vector); 101 102 void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind); 103 void imsic_vector_debug_show_summary(struct seq_file *m, int ind); 104 105 void imsic_state_online(void); 106 void imsic_state_offline(void); 107 int imsic_setup_state(struct fwnode_handle *fwnode, void *opaque); 108 int imsic_irqdomain_init(void); 109 110 #endif 111