1/* SPDX-License-Identifier: MIT */
2#ifndef __NVKM_INTR_H__
3#define __NVKM_INTR_H__
4#include <core/os.h>
5struct nvkm_device;
6struct nvkm_subdev;
7
8enum nvkm_intr_prio {
9	NVKM_INTR_PRIO_VBLANK = 0,
10	NVKM_INTR_PRIO_NORMAL,
11	NVKM_INTR_PRIO_NR
12};
13
14enum nvkm_intr_type {
15	NVKM_INTR_SUBDEV   = -1, /* lookup vector by requesting subdev, in mapping table. */
16	NVKM_INTR_VECTOR_0 = 0,
17};
18
19struct nvkm_intr {
20	const struct nvkm_intr_func {
21		bool (*pending)(struct nvkm_intr *);
22		void (*unarm)(struct nvkm_intr *);
23		void (*rearm)(struct nvkm_intr *);
24		void (*block)(struct nvkm_intr *, int leaf, u32 mask);
25		void (*allow)(struct nvkm_intr *, int leaf, u32 mask);
26		void (*reset)(struct nvkm_intr *, int leaf, u32 mask);
27	} *func;
28	const struct nvkm_intr_data {
29		int type; /* enum nvkm_subdev_type (+ve), enum nvkm_intr_type (-ve) */
30		int inst;
31		int leaf;
32		u32 mask; /* 0-terminated. */
33		bool legacy; /* auto-create "legacy" nvkm_subdev_intr() handler */
34	} *data;
35
36	struct nvkm_subdev *subdev;
37	int leaves;
38	u32 *stat;
39	u32 *mask;
40
41	struct list_head head;
42};
43
44void nvkm_intr_ctor(struct nvkm_device *);
45void nvkm_intr_dtor(struct nvkm_device *);
46int nvkm_intr_install(struct nvkm_device *);
47void nvkm_intr_unarm(struct nvkm_device *);
48void nvkm_intr_rearm(struct nvkm_device *);
49
50int nvkm_intr_add(const struct nvkm_intr_func *, const struct nvkm_intr_data *,
51		  struct nvkm_subdev *, int leaves, struct nvkm_intr *);
52void nvkm_intr_block(struct nvkm_subdev *, enum nvkm_intr_type);
53void nvkm_intr_allow(struct nvkm_subdev *, enum nvkm_intr_type);
54
55struct nvkm_inth;
56typedef irqreturn_t (*nvkm_inth_func)(struct nvkm_inth *);
57
58struct nvkm_inth {
59	struct nvkm_intr *intr;
60	int leaf;
61	u32 mask;
62	nvkm_inth_func func;
63
64	atomic_t allowed;
65
66	struct list_head head;
67};
68
69int nvkm_inth_add(struct nvkm_intr *, enum nvkm_intr_type, enum nvkm_intr_prio,
70		  struct nvkm_subdev *, nvkm_inth_func, struct nvkm_inth *);
71void nvkm_inth_allow(struct nvkm_inth *);
72void nvkm_inth_block(struct nvkm_inth *);
73#endif
74