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

source code of linux/drivers/irqchip/irq-riscv-imsic-state.h