/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2021 Western Digital Corporation or its affiliates. * Copyright (C) 2022 Ventana Micro Systems Inc. */ #ifndef _IRQ_RISCV_IMSIC_STATE_H #define _IRQ_RISCV_IMSIC_STATE_H #include #include #include #include #define IMSIC_IPI_ID 1 #define IMSIC_NR_IPI 8 struct imsic_vector { /* Fixed details of the vector */ unsigned int cpu; unsigned int local_id; /* Details saved by driver in the vector */ unsigned int hwirq; /* Details accessed using local lock held */ bool enable; struct imsic_vector *move; }; struct imsic_local_priv { /* Local lock to protect vector enable/move variables and dirty bitmap */ raw_spinlock_t lock; /* Local dirty bitmap for synchronization */ unsigned long *dirty_bitmap; #ifdef CONFIG_SMP /* Local timer for synchronization */ struct timer_list timer; #endif /* Local vector table */ struct imsic_vector *vectors; }; struct imsic_priv { /* Device details */ struct fwnode_handle *fwnode; /* Global configuration common for all HARTs */ struct imsic_global_config global; /* Per-CPU state */ struct imsic_local_priv __percpu *lpriv; /* State of IRQ matrix allocator */ raw_spinlock_t matrix_lock; struct irq_matrix *matrix; /* IRQ domains (created by platform driver) */ struct irq_domain *base_domain; }; extern struct imsic_priv *imsic; void __imsic_eix_update(unsigned long base_id, unsigned long num_id, bool pend, bool val); static inline void __imsic_id_set_enable(unsigned long id) { __imsic_eix_update(id, 1, false, true); } static inline void __imsic_id_clear_enable(unsigned long id) { __imsic_eix_update(id, 1, false, false); } void imsic_local_sync_all(void); void imsic_local_delivery(bool enable); void imsic_vector_mask(struct imsic_vector *vec); void imsic_vector_unmask(struct imsic_vector *vec); static inline bool imsic_vector_isenabled(struct imsic_vector *vec) { return READ_ONCE(vec->enable); } static inline struct imsic_vector *imsic_vector_get_move(struct imsic_vector *vec) { return READ_ONCE(vec->move); } void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *new_vec); struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned int local_id); struct imsic_vector *imsic_vector_alloc(unsigned int hwirq, const struct cpumask *mask); void imsic_vector_free(struct imsic_vector *vector); void imsic_vector_debug_show(struct seq_file *m, struct imsic_vector *vec, int ind); void imsic_vector_debug_show_summary(struct seq_file *m, int ind); void imsic_state_online(void); void imsic_state_offline(void); int imsic_setup_state(struct fwnode_handle *fwnode); int imsic_irqdomain_init(void); #endif