xref: /linux/drivers/dma/idxd/idxd.h (revision 2442b7473ad03671378d2d95651bd6bbe09a0943)
1bfe1d560SDave Jiang /* SPDX-License-Identifier: GPL-2.0 */
2bfe1d560SDave Jiang /* Copyright(c) 2019 Intel Corporation. All rights rsvd. */
3bfe1d560SDave Jiang #ifndef _IDXD_H_
4bfe1d560SDave Jiang #define _IDXD_H_
5bfe1d560SDave Jiang 
6bfe1d560SDave Jiang #include <linux/sbitmap.h>
78f47d1a5SDave Jiang #include <linux/dmaengine.h>
8bfe1d560SDave Jiang #include <linux/percpu-rwsem.h>
9bfe1d560SDave Jiang #include <linux/wait.h>
1042d279f9SDave Jiang #include <linux/cdev.h>
1147c16ac2SDave Jiang #include <linux/idr.h>
1281dd4d4dSTom Zanussi #include <linux/pci.h>
138b67426eSDave Jiang #include <linux/ioasid.h>
14de5819b9SJerry Snitselaar #include <linux/bitmap.h>
1581dd4d4dSTom Zanussi #include <linux/perf_event.h>
16a9c17152SDave Jiang #include <uapi/linux/idxd.h>
17bfe1d560SDave Jiang #include "registers.h"
18bfe1d560SDave Jiang 
19bfe1d560SDave Jiang #define IDXD_DRIVER_VERSION	"1.00"
20bfe1d560SDave Jiang 
21bfe1d560SDave Jiang extern struct kmem_cache *idxd_desc_pool;
22ade8a86bSDave Jiang extern bool tc_override;
23bfe1d560SDave Jiang 
2439786285SDave Jiang struct idxd_wq;
25700af3a0SDave Jiang struct idxd_dev;
26700af3a0SDave Jiang 
27700af3a0SDave Jiang enum idxd_dev_type {
28700af3a0SDave Jiang 	IDXD_DEV_NONE = -1,
29700af3a0SDave Jiang 	IDXD_DEV_DSA = 0,
30700af3a0SDave Jiang 	IDXD_DEV_IAX,
31700af3a0SDave Jiang 	IDXD_DEV_WQ,
32700af3a0SDave Jiang 	IDXD_DEV_GROUP,
33700af3a0SDave Jiang 	IDXD_DEV_ENGINE,
34700af3a0SDave Jiang 	IDXD_DEV_CDEV,
35700af3a0SDave Jiang 	IDXD_DEV_MAX_TYPE,
36700af3a0SDave Jiang };
37700af3a0SDave Jiang 
38700af3a0SDave Jiang struct idxd_dev {
39700af3a0SDave Jiang 	struct device conf_dev;
40700af3a0SDave Jiang 	enum idxd_dev_type type;
41700af3a0SDave Jiang };
4239786285SDave Jiang 
43bfe1d560SDave Jiang #define IDXD_REG_TIMEOUT	50
44bfe1d560SDave Jiang #define IDXD_DRAIN_TIMEOUT	5000
45bfe1d560SDave Jiang 
46bfe1d560SDave Jiang enum idxd_type {
47bfe1d560SDave Jiang 	IDXD_TYPE_UNKNOWN = -1,
48bfe1d560SDave Jiang 	IDXD_TYPE_DSA = 0,
49f25b4638SDave Jiang 	IDXD_TYPE_IAX,
50f25b4638SDave Jiang 	IDXD_TYPE_MAX,
51bfe1d560SDave Jiang };
52bfe1d560SDave Jiang 
53bfe1d560SDave Jiang #define IDXD_NAME_SIZE		128
5481dd4d4dSTom Zanussi #define IDXD_PMU_EVENT_MAX	64
55bfe1d560SDave Jiang 
567930d855SDave Jiang #define IDXD_ENQCMDS_RETRIES		32
577930d855SDave Jiang #define IDXD_ENQCMDS_MAX_RETRIES	64
587930d855SDave Jiang 
59bfe1d560SDave Jiang struct idxd_device_driver {
60da5a11d7SDave Jiang 	const char *name;
615fee6567SDave Jiang 	enum idxd_dev_type *type;
62fcc2281bSDave Jiang 	int (*probe)(struct idxd_dev *idxd_dev);
63fcc2281bSDave Jiang 	void (*remove)(struct idxd_dev *idxd_dev);
64bfe1d560SDave Jiang 	struct device_driver drv;
65bfe1d560SDave Jiang };
66bfe1d560SDave Jiang 
67c05257b5SDave Jiang extern struct idxd_device_driver dsa_drv;
68034b3290SDave Jiang extern struct idxd_device_driver idxd_drv;
690cda4f69SDave Jiang extern struct idxd_device_driver idxd_dmaengine_drv;
70448c3de8SDave Jiang extern struct idxd_device_driver idxd_user_drv;
71c05257b5SDave Jiang 
728b67426eSDave Jiang #define INVALID_INT_HANDLE	-1
73bfe1d560SDave Jiang struct idxd_irq_entry {
74bfe1d560SDave Jiang 	int id;
755fc8e85fSDave Jiang 	int vector;
76bfe1d560SDave Jiang 	struct llist_head pending_llist;
77bfe1d560SDave Jiang 	struct list_head work_list;
78e4f4d8cdSDave Jiang 	/*
79e4f4d8cdSDave Jiang 	 * Lock to protect access between irq thread process descriptor
80e4f4d8cdSDave Jiang 	 * and irq thread processing error descriptor.
81e4f4d8cdSDave Jiang 	 */
82e4f4d8cdSDave Jiang 	spinlock_t list_lock;
838b67426eSDave Jiang 	int int_handle;
848b67426eSDave Jiang 	ioasid_t pasid;
85bfe1d560SDave Jiang };
86bfe1d560SDave Jiang 
87bfe1d560SDave Jiang struct idxd_group {
88700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
89bfe1d560SDave Jiang 	struct idxd_device *idxd;
90bfe1d560SDave Jiang 	struct grpcfg grpcfg;
91bfe1d560SDave Jiang 	int id;
92bfe1d560SDave Jiang 	int num_engines;
93bfe1d560SDave Jiang 	int num_wqs;
947ed6f1b8SDave Jiang 	bool use_rdbuf_limit;
957ed6f1b8SDave Jiang 	u8 rdbufs_allowed;
967ed6f1b8SDave Jiang 	u8 rdbufs_reserved;
97bfe1d560SDave Jiang 	int tc_a;
98bfe1d560SDave Jiang 	int tc_b;
991f273752SDave Jiang 	int desc_progress_limit;
1007ca68fa3SDave Jiang 	int batch_progress_limit;
101bfe1d560SDave Jiang };
102bfe1d560SDave Jiang 
10381dd4d4dSTom Zanussi struct idxd_pmu {
10481dd4d4dSTom Zanussi 	struct idxd_device *idxd;
10581dd4d4dSTom Zanussi 
10681dd4d4dSTom Zanussi 	struct perf_event *event_list[IDXD_PMU_EVENT_MAX];
10781dd4d4dSTom Zanussi 	int n_events;
10881dd4d4dSTom Zanussi 
10981dd4d4dSTom Zanussi 	DECLARE_BITMAP(used_mask, IDXD_PMU_EVENT_MAX);
11081dd4d4dSTom Zanussi 
11181dd4d4dSTom Zanussi 	struct pmu pmu;
11281dd4d4dSTom Zanussi 	char name[IDXD_NAME_SIZE];
11381dd4d4dSTom Zanussi 	int cpu;
11481dd4d4dSTom Zanussi 
11581dd4d4dSTom Zanussi 	int n_counters;
11681dd4d4dSTom Zanussi 	int counter_width;
11781dd4d4dSTom Zanussi 	int n_event_categories;
11881dd4d4dSTom Zanussi 
11981dd4d4dSTom Zanussi 	bool per_counter_caps_supported;
12081dd4d4dSTom Zanussi 	unsigned long supported_event_categories;
12181dd4d4dSTom Zanussi 
12281dd4d4dSTom Zanussi 	unsigned long supported_filters;
12381dd4d4dSTom Zanussi 	int n_filters;
12481dd4d4dSTom Zanussi 
12581dd4d4dSTom Zanussi 	struct hlist_node cpuhp_node;
12681dd4d4dSTom Zanussi };
12781dd4d4dSTom Zanussi 
128bfe1d560SDave Jiang #define IDXD_MAX_PRIORITY	0xf
129bfe1d560SDave Jiang 
130bfe1d560SDave Jiang enum idxd_wq_state {
131bfe1d560SDave Jiang 	IDXD_WQ_DISABLED = 0,
132bfe1d560SDave Jiang 	IDXD_WQ_ENABLED,
133bfe1d560SDave Jiang };
134bfe1d560SDave Jiang 
135bfe1d560SDave Jiang enum idxd_wq_flag {
136bfe1d560SDave Jiang 	WQ_FLAG_DEDICATED = 0,
1378e50d392SDave Jiang 	WQ_FLAG_BLOCK_ON_FAULT,
13822bd0df8SDave Jiang 	WQ_FLAG_ATS_DISABLE,
139bfe1d560SDave Jiang };
140bfe1d560SDave Jiang 
141bfe1d560SDave Jiang enum idxd_wq_type {
142bfe1d560SDave Jiang 	IDXD_WQT_NONE = 0,
143bfe1d560SDave Jiang 	IDXD_WQT_KERNEL,
14442d279f9SDave Jiang 	IDXD_WQT_USER,
14542d279f9SDave Jiang };
14642d279f9SDave Jiang 
14742d279f9SDave Jiang struct idxd_cdev {
14804922b74SDave Jiang 	struct idxd_wq *wq;
14942d279f9SDave Jiang 	struct cdev cdev;
150700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
15142d279f9SDave Jiang 	int minor;
152bfe1d560SDave Jiang };
153bfe1d560SDave Jiang 
154bfe1d560SDave Jiang #define IDXD_ALLOCATED_BATCH_SIZE	128U
155bfe1d560SDave Jiang #define WQ_NAME_SIZE   1024
156bfe1d560SDave Jiang #define WQ_TYPE_SIZE   10
157bfe1d560SDave Jiang 
15892452a72SDave Jiang #define WQ_DEFAULT_QUEUE_DEPTH		16
15992452a72SDave Jiang #define WQ_DEFAULT_MAX_XFER		SZ_2M
16092452a72SDave Jiang #define WQ_DEFAULT_MAX_BATCH		32
16192452a72SDave Jiang 
162d1dfe5b8SDave Jiang enum idxd_op_type {
163d1dfe5b8SDave Jiang 	IDXD_OP_BLOCK = 0,
164d1dfe5b8SDave Jiang 	IDXD_OP_NONBLOCK = 1,
165d1dfe5b8SDave Jiang };
166d1dfe5b8SDave Jiang 
1678f47d1a5SDave Jiang enum idxd_complete_type {
1688f47d1a5SDave Jiang 	IDXD_COMPLETE_NORMAL = 0,
1698f47d1a5SDave Jiang 	IDXD_COMPLETE_ABORT,
1708e50d392SDave Jiang 	IDXD_COMPLETE_DEV_FAIL,
1718f47d1a5SDave Jiang };
1728f47d1a5SDave Jiang 
17339786285SDave Jiang struct idxd_dma_chan {
17439786285SDave Jiang 	struct dma_chan chan;
17539786285SDave Jiang 	struct idxd_wq *wq;
17639786285SDave Jiang };
17739786285SDave Jiang 
178bfe1d560SDave Jiang struct idxd_wq {
1798e50d392SDave Jiang 	void __iomem *portal;
180a9c17152SDave Jiang 	u32 portal_offset;
1817930d855SDave Jiang 	unsigned int enqcmds_retries;
18293a40a6dSDave Jiang 	struct percpu_ref wq_active;
18393a40a6dSDave Jiang 	struct completion wq_dead;
18456fc39f5SDave Jiang 	struct completion wq_resurrect;
185700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
18604922b74SDave Jiang 	struct idxd_cdev *idxd_cdev;
18704922b74SDave Jiang 	struct wait_queue_head err_queue;
1882f30decdSDave Jiang 	struct workqueue_struct *wq;
189bfe1d560SDave Jiang 	struct idxd_device *idxd;
190bfe1d560SDave Jiang 	int id;
191ec0d6423SDave Jiang 	struct idxd_irq_entry ie;
192bfe1d560SDave Jiang 	enum idxd_wq_type type;
193bfe1d560SDave Jiang 	struct idxd_group *group;
194bfe1d560SDave Jiang 	int client_count;
195bfe1d560SDave Jiang 	struct mutex wq_lock;	/* mutex for workqueue */
196bfe1d560SDave Jiang 	u32 size;
197bfe1d560SDave Jiang 	u32 threshold;
198bfe1d560SDave Jiang 	u32 priority;
199bfe1d560SDave Jiang 	enum idxd_wq_state state;
200bfe1d560SDave Jiang 	unsigned long flags;
201d98793b5SDave Jiang 	union wqcfg *wqcfg;
202b0325aefSDave Jiang 	unsigned long *opcap_bmap;
203b0325aefSDave Jiang 
204bfe1d560SDave Jiang 	struct dsa_hw_desc **hw_descs;
205bfe1d560SDave Jiang 	int num_descs;
206f25b4638SDave Jiang 	union {
207bfe1d560SDave Jiang 		struct dsa_completion_record *compls;
208f25b4638SDave Jiang 		struct iax_completion_record *iax_compls;
209f25b4638SDave Jiang 	};
210bfe1d560SDave Jiang 	dma_addr_t compls_addr;
211bfe1d560SDave Jiang 	int compls_size;
212bfe1d560SDave Jiang 	struct idxd_desc **descs;
2130705107fSDave Jiang 	struct sbitmap_queue sbq;
21439786285SDave Jiang 	struct idxd_dma_chan *idxd_chan;
215bfe1d560SDave Jiang 	char name[WQ_NAME_SIZE + 1];
216d7aad555SDave Jiang 	u64 max_xfer_bytes;
217e7184b15SDave Jiang 	u32 max_batch_size;
218b022f597SFenghua Yu 
219b022f597SFenghua Yu 	/* Lock to protect upasid_xa access. */
220b022f597SFenghua Yu 	struct mutex uc_lock;
221b022f597SFenghua Yu 	struct xarray upasid_xa;
222bfe1d560SDave Jiang };
223bfe1d560SDave Jiang 
224bfe1d560SDave Jiang struct idxd_engine {
225700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
226bfe1d560SDave Jiang 	int id;
227bfe1d560SDave Jiang 	struct idxd_group *group;
228bfe1d560SDave Jiang 	struct idxd_device *idxd;
229bfe1d560SDave Jiang };
230bfe1d560SDave Jiang 
231bfe1d560SDave Jiang /* shadow registers */
232bfe1d560SDave Jiang struct idxd_hw {
233bfe1d560SDave Jiang 	u32 version;
234bfe1d560SDave Jiang 	union gen_cap_reg gen_cap;
235bfe1d560SDave Jiang 	union wq_cap_reg wq_cap;
236bfe1d560SDave Jiang 	union group_cap_reg group_cap;
237bfe1d560SDave Jiang 	union engine_cap_reg engine_cap;
238bfe1d560SDave Jiang 	struct opcap opcap;
239eb15e715SDave Jiang 	u32 cmd_cap;
2409f0d99b3SDave Jiang 	union iaa_cap_reg iaa_cap;
241bfe1d560SDave Jiang };
242bfe1d560SDave Jiang 
243bfe1d560SDave Jiang enum idxd_device_state {
244bfe1d560SDave Jiang 	IDXD_DEV_HALTED = -1,
245bfe1d560SDave Jiang 	IDXD_DEV_DISABLED = 0,
246bfe1d560SDave Jiang 	IDXD_DEV_ENABLED,
247bfe1d560SDave Jiang };
248bfe1d560SDave Jiang 
249bfe1d560SDave Jiang enum idxd_device_flag {
250bfe1d560SDave Jiang 	IDXD_FLAG_CONFIGURABLE = 0,
2510d5c10b4SDave Jiang 	IDXD_FLAG_CMD_RUNNING,
2528e50d392SDave Jiang 	IDXD_FLAG_PASID_ENABLED,
25342a1b738SDave Jiang 	IDXD_FLAG_USER_PASID_ENABLED,
254bfe1d560SDave Jiang };
255bfe1d560SDave Jiang 
25639786285SDave Jiang struct idxd_dma_dev {
25739786285SDave Jiang 	struct idxd_device *idxd;
25839786285SDave Jiang 	struct dma_device dma;
25939786285SDave Jiang };
26039786285SDave Jiang 
261435b512dSDave Jiang struct idxd_driver_data {
262435b512dSDave Jiang 	const char *name_prefix;
263bfe1d560SDave Jiang 	enum idxd_type type;
264435b512dSDave Jiang 	struct device_type *dev_type;
265435b512dSDave Jiang 	int compl_size;
266435b512dSDave Jiang 	int align;
267c40bd7d9SDave Jiang 	int evl_cr_off;
268*2442b747SDave Jiang 	int cr_status_off;
269*2442b747SDave Jiang 	int cr_result_off;
270435b512dSDave Jiang };
271435b512dSDave Jiang 
2721649091fSDave Jiang struct idxd_evl {
273244da66cSDave Jiang 	/* Lock to protect event log access. */
274244da66cSDave Jiang 	spinlock_t lock;
275244da66cSDave Jiang 	void *log;
276244da66cSDave Jiang 	dma_addr_t dma;
277244da66cSDave Jiang 	/* Total size of event log = number of entries * entry size. */
278244da66cSDave Jiang 	unsigned int log_size;
279244da66cSDave Jiang 	/* The number of entries in the event log. */
2801649091fSDave Jiang 	u16 size;
281244da66cSDave Jiang 	u16 head;
282c40bd7d9SDave Jiang 	unsigned long *bmap;
283*2442b747SDave Jiang 	bool batch_fail[IDXD_MAX_BATCH_IDENT];
2841649091fSDave Jiang };
2851649091fSDave Jiang 
286c2f156bfSDave Jiang struct idxd_evl_fault {
287c2f156bfSDave Jiang 	struct work_struct work;
288c2f156bfSDave Jiang 	struct idxd_wq *wq;
289c2f156bfSDave Jiang 	u8 status;
290c2f156bfSDave Jiang 
291c2f156bfSDave Jiang 	/* make this last member always */
292c2f156bfSDave Jiang 	struct __evl_entry entry[];
293c2f156bfSDave Jiang };
294c2f156bfSDave Jiang 
295435b512dSDave Jiang struct idxd_device {
296700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
297435b512dSDave Jiang 	struct idxd_driver_data *data;
298bfe1d560SDave Jiang 	struct list_head list;
299bfe1d560SDave Jiang 	struct idxd_hw hw;
300bfe1d560SDave Jiang 	enum idxd_device_state state;
301bfe1d560SDave Jiang 	unsigned long flags;
302bfe1d560SDave Jiang 	int id;
30342d279f9SDave Jiang 	int major;
304125d1037SDave Jiang 	u32 cmd_status;
305ec0d6423SDave Jiang 	struct idxd_irq_entry ie;	/* misc irq, msix 0 */
306bfe1d560SDave Jiang 
307bfe1d560SDave Jiang 	struct pci_dev *pdev;
308bfe1d560SDave Jiang 	void __iomem *reg_base;
309bfe1d560SDave Jiang 
310bfe1d560SDave Jiang 	spinlock_t dev_lock;	/* spinlock for device */
31153b2ee7fSDave Jiang 	spinlock_t cmd_lock;	/* spinlock for device commands */
3120d5c10b4SDave Jiang 	struct completion *cmd_done;
313defe49f9SDave Jiang 	struct idxd_group **groups;
3147c5dd23eSDave Jiang 	struct idxd_wq **wqs;
31575b91130SDave Jiang 	struct idxd_engine **engines;
316bfe1d560SDave Jiang 
3178e50d392SDave Jiang 	struct iommu_sva *sva;
3188e50d392SDave Jiang 	unsigned int pasid;
3198e50d392SDave Jiang 
320bfe1d560SDave Jiang 	int num_groups;
3218b67426eSDave Jiang 	int irq_cnt;
3228b67426eSDave Jiang 	bool request_int_handles;
323bfe1d560SDave Jiang 
324bfe1d560SDave Jiang 	u32 msix_perm_offset;
325bfe1d560SDave Jiang 	u32 wqcfg_offset;
326bfe1d560SDave Jiang 	u32 grpcfg_offset;
327bfe1d560SDave Jiang 	u32 perfmon_offset;
328bfe1d560SDave Jiang 
329bfe1d560SDave Jiang 	u64 max_xfer_bytes;
330bfe1d560SDave Jiang 	u32 max_batch_size;
331bfe1d560SDave Jiang 	int max_groups;
332bfe1d560SDave Jiang 	int max_engines;
3337ed6f1b8SDave Jiang 	int max_rdbufs;
334bfe1d560SDave Jiang 	int max_wqs;
335bfe1d560SDave Jiang 	int max_wq_size;
3367ed6f1b8SDave Jiang 	int rdbuf_limit;
3377ed6f1b8SDave Jiang 	int nr_rdbufs;		/* non-reserved read buffers */
338d98793b5SDave Jiang 	unsigned int wqcfg_size;
339de5819b9SJerry Snitselaar 	unsigned long *wq_enable_map;
340bfe1d560SDave Jiang 
341bfe1d560SDave Jiang 	union sw_err_reg sw_err;
3420d5c10b4SDave Jiang 	wait_queue_head_t cmd_waitq;
3438f47d1a5SDave Jiang 
34439786285SDave Jiang 	struct idxd_dma_dev *idxd_dma;
3450d5c10b4SDave Jiang 	struct workqueue_struct *wq;
3460d5c10b4SDave Jiang 	struct work_struct work;
347eb15e715SDave Jiang 
34881dd4d4dSTom Zanussi 	struct idxd_pmu *idxd_pmu;
349a8563a33SDave Jiang 
350a8563a33SDave Jiang 	unsigned long *opcap_bmap;
3511649091fSDave Jiang 	struct idxd_evl *evl;
352c2f156bfSDave Jiang 	struct kmem_cache *evl_cache;
3535fbe6503SDave Jiang 
3545fbe6503SDave Jiang 	struct dentry *dbgfs_dir;
3555fbe6503SDave Jiang 	struct dentry *dbgfs_evl_file;
356bfe1d560SDave Jiang };
357bfe1d560SDave Jiang 
358244da66cSDave Jiang static inline unsigned int evl_ent_size(struct idxd_device *idxd)
359244da66cSDave Jiang {
360244da66cSDave Jiang 	return idxd->hw.gen_cap.evl_support ?
361244da66cSDave Jiang 	       (32 * (1 << idxd->hw.gen_cap.evl_support)) : 0;
362244da66cSDave Jiang }
363244da66cSDave Jiang 
364244da66cSDave Jiang static inline unsigned int evl_size(struct idxd_device *idxd)
365244da66cSDave Jiang {
366244da66cSDave Jiang 	return idxd->evl->size * evl_ent_size(idxd);
367244da66cSDave Jiang }
368244da66cSDave Jiang 
369bfe1d560SDave Jiang /* IDXD software descriptor */
370bfe1d560SDave Jiang struct idxd_desc {
371f25b4638SDave Jiang 	union {
372bfe1d560SDave Jiang 		struct dsa_hw_desc *hw;
373f25b4638SDave Jiang 		struct iax_hw_desc *iax_hw;
374f25b4638SDave Jiang 	};
375bfe1d560SDave Jiang 	dma_addr_t desc_dma;
376f25b4638SDave Jiang 	union {
377bfe1d560SDave Jiang 		struct dsa_completion_record *completion;
378f25b4638SDave Jiang 		struct iax_completion_record *iax_completion;
379f25b4638SDave Jiang 	};
380bfe1d560SDave Jiang 	dma_addr_t compl_dma;
3818f47d1a5SDave Jiang 	struct dma_async_tx_descriptor txd;
382bfe1d560SDave Jiang 	struct llist_node llnode;
383bfe1d560SDave Jiang 	struct list_head list;
384bfe1d560SDave Jiang 	int id;
3850705107fSDave Jiang 	int cpu;
386bfe1d560SDave Jiang 	struct idxd_wq *wq;
387bfe1d560SDave Jiang };
388bfe1d560SDave Jiang 
3896b4b87f2SDave Jiang /*
3906b4b87f2SDave Jiang  * This is software defined error for the completion status. We overload the error code
3916b4b87f2SDave Jiang  * that will never appear in completion status and only SWERR register.
3926b4b87f2SDave Jiang  */
3936b4b87f2SDave Jiang enum idxd_completion_status {
3946b4b87f2SDave Jiang 	IDXD_COMP_DESC_ABORT = 0xff,
3956b4b87f2SDave Jiang };
3966b4b87f2SDave Jiang 
397700af3a0SDave Jiang #define idxd_confdev(idxd) &idxd->idxd_dev.conf_dev
398700af3a0SDave Jiang #define wq_confdev(wq) &wq->idxd_dev.conf_dev
399700af3a0SDave Jiang #define engine_confdev(engine) &engine->idxd_dev.conf_dev
400700af3a0SDave Jiang #define group_confdev(group) &group->idxd_dev.conf_dev
401700af3a0SDave Jiang #define cdev_dev(cdev) &cdev->idxd_dev.conf_dev
402700af3a0SDave Jiang 
403700af3a0SDave Jiang #define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev)
404fcc2281bSDave Jiang #define idxd_dev_to_idxd(idxd_dev) container_of(idxd_dev, struct idxd_device, idxd_dev)
405fcc2281bSDave Jiang #define idxd_dev_to_wq(idxd_dev) container_of(idxd_dev, struct idxd_wq, idxd_dev)
406700af3a0SDave Jiang 
407700af3a0SDave Jiang static inline struct idxd_device *confdev_to_idxd(struct device *dev)
408700af3a0SDave Jiang {
409700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
410700af3a0SDave Jiang 
411fcc2281bSDave Jiang 	return idxd_dev_to_idxd(idxd_dev);
412700af3a0SDave Jiang }
413700af3a0SDave Jiang 
414700af3a0SDave Jiang static inline struct idxd_wq *confdev_to_wq(struct device *dev)
415700af3a0SDave Jiang {
416700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
417700af3a0SDave Jiang 
418fcc2281bSDave Jiang 	return idxd_dev_to_wq(idxd_dev);
419700af3a0SDave Jiang }
420700af3a0SDave Jiang 
421700af3a0SDave Jiang static inline struct idxd_engine *confdev_to_engine(struct device *dev)
422700af3a0SDave Jiang {
423700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
424700af3a0SDave Jiang 
425700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_engine, idxd_dev);
426700af3a0SDave Jiang }
427700af3a0SDave Jiang 
428700af3a0SDave Jiang static inline struct idxd_group *confdev_to_group(struct device *dev)
429700af3a0SDave Jiang {
430700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
431700af3a0SDave Jiang 
432700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_group, idxd_dev);
433700af3a0SDave Jiang }
434700af3a0SDave Jiang 
435700af3a0SDave Jiang static inline struct idxd_cdev *dev_to_cdev(struct device *dev)
436700af3a0SDave Jiang {
437700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
438700af3a0SDave Jiang 
439700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_cdev, idxd_dev);
440700af3a0SDave Jiang }
441700af3a0SDave Jiang 
442700af3a0SDave Jiang static inline void idxd_dev_set_type(struct idxd_dev *idev, int type)
443700af3a0SDave Jiang {
444700af3a0SDave Jiang 	if (type >= IDXD_DEV_MAX_TYPE) {
445700af3a0SDave Jiang 		idev->type = IDXD_DEV_NONE;
446700af3a0SDave Jiang 		return;
447700af3a0SDave Jiang 	}
448700af3a0SDave Jiang 
449700af3a0SDave Jiang 	idev->type = type;
450700af3a0SDave Jiang }
451bfe1d560SDave Jiang 
452ec0d6423SDave Jiang static inline struct idxd_irq_entry *idxd_get_ie(struct idxd_device *idxd, int idx)
453ec0d6423SDave Jiang {
454ec0d6423SDave Jiang 	return (idx == 0) ? &idxd->ie : &idxd->wqs[idx - 1]->ie;
455ec0d6423SDave Jiang }
456ec0d6423SDave Jiang 
457ec0d6423SDave Jiang static inline struct idxd_wq *ie_to_wq(struct idxd_irq_entry *ie)
458ec0d6423SDave Jiang {
459ec0d6423SDave Jiang 	return container_of(ie, struct idxd_wq, ie);
460ec0d6423SDave Jiang }
461ec0d6423SDave Jiang 
462ec0d6423SDave Jiang static inline struct idxd_device *ie_to_idxd(struct idxd_irq_entry *ie)
463ec0d6423SDave Jiang {
464ec0d6423SDave Jiang 	return container_of(ie, struct idxd_device, ie);
465ec0d6423SDave Jiang }
466ec0d6423SDave Jiang 
46742d279f9SDave Jiang extern struct bus_type dsa_bus_type;
46842d279f9SDave Jiang 
4698e50d392SDave Jiang extern bool support_enqcmd;
4704b73e4ebSDave Jiang extern struct ida idxd_ida;
47147c16ac2SDave Jiang extern struct device_type dsa_device_type;
47247c16ac2SDave Jiang extern struct device_type iax_device_type;
4737c5dd23eSDave Jiang extern struct device_type idxd_wq_device_type;
47475b91130SDave Jiang extern struct device_type idxd_engine_device_type;
475defe49f9SDave Jiang extern struct device_type idxd_group_device_type;
47647c16ac2SDave Jiang 
477fcc2281bSDave Jiang static inline bool is_dsa_dev(struct idxd_dev *idxd_dev)
47847c16ac2SDave Jiang {
479fcc2281bSDave Jiang 	return idxd_dev->type == IDXD_DEV_DSA;
48047c16ac2SDave Jiang }
48147c16ac2SDave Jiang 
482fcc2281bSDave Jiang static inline bool is_iax_dev(struct idxd_dev *idxd_dev)
48347c16ac2SDave Jiang {
484fcc2281bSDave Jiang 	return idxd_dev->type == IDXD_DEV_IAX;
48547c16ac2SDave Jiang }
48647c16ac2SDave Jiang 
487fcc2281bSDave Jiang static inline bool is_idxd_dev(struct idxd_dev *idxd_dev)
48847c16ac2SDave Jiang {
489fcc2281bSDave Jiang 	return is_dsa_dev(idxd_dev) || is_iax_dev(idxd_dev);
49047c16ac2SDave Jiang }
4918e50d392SDave Jiang 
492fcc2281bSDave Jiang static inline bool is_idxd_wq_dev(struct idxd_dev *idxd_dev)
4937c5dd23eSDave Jiang {
494fcc2281bSDave Jiang 	return idxd_dev->type == IDXD_DEV_WQ;
4957c5dd23eSDave Jiang }
4967c5dd23eSDave Jiang 
4977c5dd23eSDave Jiang static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq)
4987c5dd23eSDave Jiang {
4997c5dd23eSDave Jiang 	if (wq->type == IDXD_WQT_KERNEL && strcmp(wq->name, "dmaengine") == 0)
5007c5dd23eSDave Jiang 		return true;
5017c5dd23eSDave Jiang 	return false;
5027c5dd23eSDave Jiang }
5037c5dd23eSDave Jiang 
5046e7f3ee9SDave Jiang static inline bool is_idxd_wq_user(struct idxd_wq *wq)
5057c5dd23eSDave Jiang {
5067c5dd23eSDave Jiang 	return wq->type == IDXD_WQT_USER;
5077c5dd23eSDave Jiang }
5087c5dd23eSDave Jiang 
5096e7f3ee9SDave Jiang static inline bool is_idxd_wq_kernel(struct idxd_wq *wq)
5106e7f3ee9SDave Jiang {
5116e7f3ee9SDave Jiang 	return wq->type == IDXD_WQT_KERNEL;
5126e7f3ee9SDave Jiang }
5136e7f3ee9SDave Jiang 
514bfe1d560SDave Jiang static inline bool wq_dedicated(struct idxd_wq *wq)
515bfe1d560SDave Jiang {
516bfe1d560SDave Jiang 	return test_bit(WQ_FLAG_DEDICATED, &wq->flags);
517bfe1d560SDave Jiang }
518bfe1d560SDave Jiang 
5198e50d392SDave Jiang static inline bool wq_shared(struct idxd_wq *wq)
5208e50d392SDave Jiang {
5218e50d392SDave Jiang 	return !test_bit(WQ_FLAG_DEDICATED, &wq->flags);
5228e50d392SDave Jiang }
5238e50d392SDave Jiang 
5248e50d392SDave Jiang static inline bool device_pasid_enabled(struct idxd_device *idxd)
5258e50d392SDave Jiang {
5268e50d392SDave Jiang 	return test_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags);
5278e50d392SDave Jiang }
5288e50d392SDave Jiang 
52942a1b738SDave Jiang static inline bool device_user_pasid_enabled(struct idxd_device *idxd)
5308e50d392SDave Jiang {
53142a1b738SDave Jiang 	return test_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags);
53242a1b738SDave Jiang }
53342a1b738SDave Jiang 
53442a1b738SDave Jiang static inline bool wq_pasid_enabled(struct idxd_wq *wq)
53542a1b738SDave Jiang {
53642a1b738SDave Jiang 	return (is_idxd_wq_kernel(wq) && device_pasid_enabled(wq->idxd)) ||
53742a1b738SDave Jiang 	       (is_idxd_wq_user(wq) && device_user_pasid_enabled(wq->idxd));
53842a1b738SDave Jiang }
53942a1b738SDave Jiang 
54042a1b738SDave Jiang static inline bool wq_shared_supported(struct idxd_wq *wq)
54142a1b738SDave Jiang {
54242a1b738SDave Jiang 	return (support_enqcmd && wq_pasid_enabled(wq));
5438e50d392SDave Jiang }
5448e50d392SDave Jiang 
54542d279f9SDave Jiang enum idxd_portal_prot {
54642d279f9SDave Jiang 	IDXD_PORTAL_UNLIMITED = 0,
54742d279f9SDave Jiang 	IDXD_PORTAL_LIMITED,
54842d279f9SDave Jiang };
54942d279f9SDave Jiang 
550eb15e715SDave Jiang enum idxd_interrupt_type {
551eb15e715SDave Jiang 	IDXD_IRQ_MSIX = 0,
552eb15e715SDave Jiang 	IDXD_IRQ_IMS,
553eb15e715SDave Jiang };
554eb15e715SDave Jiang 
55542d279f9SDave Jiang static inline int idxd_get_wq_portal_offset(enum idxd_portal_prot prot)
55642d279f9SDave Jiang {
55742d279f9SDave Jiang 	return prot * 0x1000;
55842d279f9SDave Jiang }
55942d279f9SDave Jiang 
56042d279f9SDave Jiang static inline int idxd_get_wq_portal_full_offset(int wq_id,
56142d279f9SDave Jiang 						 enum idxd_portal_prot prot)
56242d279f9SDave Jiang {
56342d279f9SDave Jiang 	return ((wq_id * 4) << PAGE_SHIFT) + idxd_get_wq_portal_offset(prot);
56442d279f9SDave Jiang }
56542d279f9SDave Jiang 
566a9c17152SDave Jiang #define IDXD_PORTAL_MASK	(PAGE_SIZE - 1)
567a9c17152SDave Jiang 
568a9c17152SDave Jiang /*
569a9c17152SDave Jiang  * Even though this function can be accessed by multiple threads, it is safe to use.
570a9c17152SDave Jiang  * At worst the address gets used more than once before it gets incremented. We don't
571a9c17152SDave Jiang  * hit a threshold until iops becomes many million times a second. So the occasional
572a9c17152SDave Jiang  * reuse of the same address is tolerable compare to using an atomic variable. This is
573a9c17152SDave Jiang  * safe on a system that has atomic load/store for 32bit integers. Given that this is an
574a9c17152SDave Jiang  * Intel iEP device, that should not be a problem.
575a9c17152SDave Jiang  */
576a9c17152SDave Jiang static inline void __iomem *idxd_wq_portal_addr(struct idxd_wq *wq)
577a9c17152SDave Jiang {
578a9c17152SDave Jiang 	int ofs = wq->portal_offset;
579a9c17152SDave Jiang 
580a9c17152SDave Jiang 	wq->portal_offset = (ofs + sizeof(struct dsa_raw_desc)) & IDXD_PORTAL_MASK;
581a9c17152SDave Jiang 	return wq->portal + ofs;
582a9c17152SDave Jiang }
583a9c17152SDave Jiang 
584c52ca478SDave Jiang static inline void idxd_wq_get(struct idxd_wq *wq)
585c52ca478SDave Jiang {
586c52ca478SDave Jiang 	wq->client_count++;
587c52ca478SDave Jiang }
588c52ca478SDave Jiang 
589c52ca478SDave Jiang static inline void idxd_wq_put(struct idxd_wq *wq)
590c52ca478SDave Jiang {
591c52ca478SDave Jiang 	wq->client_count--;
592c52ca478SDave Jiang }
593c52ca478SDave Jiang 
594c52ca478SDave Jiang static inline int idxd_wq_refcount(struct idxd_wq *wq)
595c52ca478SDave Jiang {
596c52ca478SDave Jiang 	return wq->client_count;
597c52ca478SDave Jiang };
598c52ca478SDave Jiang 
599e8dbd644SXiaochen Shen /*
600e8dbd644SXiaochen Shen  * Intel IAA does not support batch processing.
601e8dbd644SXiaochen Shen  * The max batch size of device, max batch size of wq and
602e8dbd644SXiaochen Shen  * max batch shift of wqcfg should be always 0 on IAA.
603e8dbd644SXiaochen Shen  */
604e8dbd644SXiaochen Shen static inline void idxd_set_max_batch_size(int idxd_type, struct idxd_device *idxd,
605e8dbd644SXiaochen Shen 					   u32 max_batch_size)
606e8dbd644SXiaochen Shen {
607e8dbd644SXiaochen Shen 	if (idxd_type == IDXD_TYPE_IAX)
608e8dbd644SXiaochen Shen 		idxd->max_batch_size = 0;
609e8dbd644SXiaochen Shen 	else
610e8dbd644SXiaochen Shen 		idxd->max_batch_size = max_batch_size;
611e8dbd644SXiaochen Shen }
612e8dbd644SXiaochen Shen 
613e8dbd644SXiaochen Shen static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq,
614e8dbd644SXiaochen Shen 					      u32 max_batch_size)
615e8dbd644SXiaochen Shen {
616e8dbd644SXiaochen Shen 	if (idxd_type == IDXD_TYPE_IAX)
617e8dbd644SXiaochen Shen 		wq->max_batch_size = 0;
618e8dbd644SXiaochen Shen 	else
619e8dbd644SXiaochen Shen 		wq->max_batch_size = max_batch_size;
620e8dbd644SXiaochen Shen }
621e8dbd644SXiaochen Shen 
622e8dbd644SXiaochen Shen static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg,
623e8dbd644SXiaochen Shen 						  u32 max_batch_shift)
624e8dbd644SXiaochen Shen {
625e8dbd644SXiaochen Shen 	if (idxd_type == IDXD_TYPE_IAX)
626e8dbd644SXiaochen Shen 		wqcfg->max_batch_shift = 0;
627e8dbd644SXiaochen Shen 	else
628e8dbd644SXiaochen Shen 		wqcfg->max_batch_shift = max_batch_shift;
629e8dbd644SXiaochen Shen }
630e8dbd644SXiaochen Shen 
6313ecfc913SDave Jiang int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv,
6323ecfc913SDave Jiang 					struct module *module, const char *mod_name);
6333ecfc913SDave Jiang #define idxd_driver_register(driver) \
6343ecfc913SDave Jiang 	__idxd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
6353ecfc913SDave Jiang 
6363ecfc913SDave Jiang void idxd_driver_unregister(struct idxd_device_driver *idxd_drv);
6373ecfc913SDave Jiang 
6386e7f3ee9SDave Jiang #define module_idxd_driver(__idxd_driver) \
6396e7f3ee9SDave Jiang 	module_driver(__idxd_driver, idxd_driver_register, idxd_driver_unregister)
6406e7f3ee9SDave Jiang 
641c52ca478SDave Jiang int idxd_register_bus_type(void);
642c52ca478SDave Jiang void idxd_unregister_bus_type(void);
64347c16ac2SDave Jiang int idxd_register_devices(struct idxd_device *idxd);
64447c16ac2SDave Jiang void idxd_unregister_devices(struct idxd_device *idxd);
645c52ca478SDave Jiang int idxd_register_driver(void);
646c52ca478SDave Jiang void idxd_unregister_driver(void);
6475b0c68c4SDave Jiang void idxd_wqs_quiesce(struct idxd_device *idxd);
648f6d442f7SDave Jiang bool idxd_queue_int_handle_resubmit(struct idxd_desc *desc);
64934ca0066SDave Jiang void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count);
650bfe1d560SDave Jiang 
651bfe1d560SDave Jiang /* device interrupt control */
652bfe1d560SDave Jiang irqreturn_t idxd_misc_thread(int vec, void *data);
653bfe1d560SDave Jiang irqreturn_t idxd_wq_thread(int irq, void *data);
654bfe1d560SDave Jiang void idxd_mask_error_interrupts(struct idxd_device *idxd);
655bfe1d560SDave Jiang void idxd_unmask_error_interrupts(struct idxd_device *idxd);
656bfe1d560SDave Jiang 
657bfe1d560SDave Jiang /* device control */
658034b3290SDave Jiang int idxd_register_idxd_drv(void);
659034b3290SDave Jiang void idxd_unregister_idxd_drv(void);
660bd42805bSDave Jiang int idxd_device_drv_probe(struct idxd_dev *idxd_dev);
661745e92a6SDave Jiang void idxd_device_drv_remove(struct idxd_dev *idxd_dev);
6621f2bb403SDave Jiang int drv_enable_wq(struct idxd_wq *wq);
66369e4f8beSDave Jiang void drv_disable_wq(struct idxd_wq *wq);
66489e3becdSDave Jiang int idxd_device_init_reset(struct idxd_device *idxd);
665bfe1d560SDave Jiang int idxd_device_enable(struct idxd_device *idxd);
666bfe1d560SDave Jiang int idxd_device_disable(struct idxd_device *idxd);
6670d5c10b4SDave Jiang void idxd_device_reset(struct idxd_device *idxd);
6680dcfe41eSDave Jiang void idxd_device_clear_state(struct idxd_device *idxd);
669bfe1d560SDave Jiang int idxd_device_config(struct idxd_device *idxd);
6708e50d392SDave Jiang void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid);
6718c66bbdcSDave Jiang int idxd_device_load_config(struct idxd_device *idxd);
672eb15e715SDave Jiang int idxd_device_request_int_handle(struct idxd_device *idxd, int idx, int *handle,
673eb15e715SDave Jiang 				   enum idxd_interrupt_type irq_type);
674eb15e715SDave Jiang int idxd_device_release_int_handle(struct idxd_device *idxd, int handle,
675eb15e715SDave Jiang 				   enum idxd_interrupt_type irq_type);
676bfe1d560SDave Jiang 
677bfe1d560SDave Jiang /* work queue control */
6785b0c68c4SDave Jiang void idxd_wqs_unmap_portal(struct idxd_device *idxd);
679bfe1d560SDave Jiang int idxd_wq_alloc_resources(struct idxd_wq *wq);
680bfe1d560SDave Jiang void idxd_wq_free_resources(struct idxd_wq *wq);
681bfe1d560SDave Jiang int idxd_wq_enable(struct idxd_wq *wq);
6820dcfe41eSDave Jiang int idxd_wq_disable(struct idxd_wq *wq, bool reset_config);
6830d5c10b4SDave Jiang void idxd_wq_drain(struct idxd_wq *wq);
684ea9aadc0SDave Jiang void idxd_wq_reset(struct idxd_wq *wq);
685c52ca478SDave Jiang int idxd_wq_map_portal(struct idxd_wq *wq);
686c52ca478SDave Jiang void idxd_wq_unmap_portal(struct idxd_wq *wq);
6878e50d392SDave Jiang int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid);
6888e50d392SDave Jiang int idxd_wq_disable_pasid(struct idxd_wq *wq);
689bd5970a0SDave Jiang void __idxd_wq_quiesce(struct idxd_wq *wq);
69093a40a6dSDave Jiang void idxd_wq_quiesce(struct idxd_wq *wq);
69193a40a6dSDave Jiang int idxd_wq_init_percpu_ref(struct idxd_wq *wq);
692403a2e23SDave Jiang void idxd_wq_free_irq(struct idxd_wq *wq);
693403a2e23SDave Jiang int idxd_wq_request_irq(struct idxd_wq *wq);
694bfe1d560SDave Jiang 
695d1dfe5b8SDave Jiang /* submission */
696d1dfe5b8SDave Jiang int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);
697d1dfe5b8SDave Jiang struct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype);
698d1dfe5b8SDave Jiang void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc);
6997930d855SDave Jiang int idxd_enqcmds(struct idxd_wq *wq, void __iomem *portal, const void *desc);
700d1dfe5b8SDave Jiang 
7018f47d1a5SDave Jiang /* dmaengine */
7028f47d1a5SDave Jiang int idxd_register_dma_device(struct idxd_device *idxd);
7038f47d1a5SDave Jiang void idxd_unregister_dma_device(struct idxd_device *idxd);
7048f47d1a5SDave Jiang void idxd_parse_completion_status(u8 status, enum dmaengine_tx_result *res);
7058f47d1a5SDave Jiang void idxd_dma_complete_txd(struct idxd_desc *desc,
7065d78abb6SDave Jiang 			   enum idxd_complete_type comp_type, bool free_desc);
7078f47d1a5SDave Jiang 
70842d279f9SDave Jiang /* cdev */
70942d279f9SDave Jiang int idxd_cdev_register(void);
71042d279f9SDave Jiang void idxd_cdev_remove(void);
71142d279f9SDave Jiang int idxd_cdev_get_major(struct idxd_device *idxd);
71242d279f9SDave Jiang int idxd_wq_add_cdev(struct idxd_wq *wq);
71342d279f9SDave Jiang void idxd_wq_del_cdev(struct idxd_wq *wq);
714b022f597SFenghua Yu int idxd_copy_cr(struct idxd_wq *wq, ioasid_t pasid, unsigned long addr,
715b022f597SFenghua Yu 		 void *buf, int len);
71642d279f9SDave Jiang 
71781dd4d4dSTom Zanussi /* perfmon */
71881dd4d4dSTom Zanussi #if IS_ENABLED(CONFIG_INTEL_IDXD_PERFMON)
71981dd4d4dSTom Zanussi int perfmon_pmu_init(struct idxd_device *idxd);
72081dd4d4dSTom Zanussi void perfmon_pmu_remove(struct idxd_device *idxd);
72181dd4d4dSTom Zanussi void perfmon_counter_overflow(struct idxd_device *idxd);
72281dd4d4dSTom Zanussi void perfmon_init(void);
72381dd4d4dSTom Zanussi void perfmon_exit(void);
72481dd4d4dSTom Zanussi #else
72581dd4d4dSTom Zanussi static inline int perfmon_pmu_init(struct idxd_device *idxd) { return 0; }
72681dd4d4dSTom Zanussi static inline void perfmon_pmu_remove(struct idxd_device *idxd) {}
72781dd4d4dSTom Zanussi static inline void perfmon_counter_overflow(struct idxd_device *idxd) {}
72881dd4d4dSTom Zanussi static inline void perfmon_init(void) {}
72981dd4d4dSTom Zanussi static inline void perfmon_exit(void) {}
73081dd4d4dSTom Zanussi #endif
73181dd4d4dSTom Zanussi 
7325fbe6503SDave Jiang /* debugfs */
7335fbe6503SDave Jiang int idxd_device_init_debugfs(struct idxd_device *idxd);
7345fbe6503SDave Jiang void idxd_device_remove_debugfs(struct idxd_device *idxd);
7355fbe6503SDave Jiang int idxd_init_debugfs(void);
7365fbe6503SDave Jiang void idxd_remove_debugfs(void);
7375fbe6503SDave Jiang 
738bfe1d560SDave Jiang #endif
739