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> 11*47c16ac2SDave Jiang #include <linux/idr.h> 12bfe1d560SDave Jiang #include "registers.h" 13bfe1d560SDave Jiang 14bfe1d560SDave Jiang #define IDXD_DRIVER_VERSION "1.00" 15bfe1d560SDave Jiang 16bfe1d560SDave Jiang extern struct kmem_cache *idxd_desc_pool; 17bfe1d560SDave Jiang 1839786285SDave Jiang struct idxd_device; 1939786285SDave Jiang struct idxd_wq; 2039786285SDave Jiang 21bfe1d560SDave Jiang #define IDXD_REG_TIMEOUT 50 22bfe1d560SDave Jiang #define IDXD_DRAIN_TIMEOUT 5000 23bfe1d560SDave Jiang 24bfe1d560SDave Jiang enum idxd_type { 25bfe1d560SDave Jiang IDXD_TYPE_UNKNOWN = -1, 26bfe1d560SDave Jiang IDXD_TYPE_DSA = 0, 27f25b4638SDave Jiang IDXD_TYPE_IAX, 28f25b4638SDave Jiang IDXD_TYPE_MAX, 29bfe1d560SDave Jiang }; 30bfe1d560SDave Jiang 31bfe1d560SDave Jiang #define IDXD_NAME_SIZE 128 32bfe1d560SDave Jiang 33bfe1d560SDave Jiang struct idxd_device_driver { 34bfe1d560SDave Jiang struct device_driver drv; 35bfe1d560SDave Jiang }; 36bfe1d560SDave Jiang 37bfe1d560SDave Jiang struct idxd_irq_entry { 38bfe1d560SDave Jiang struct idxd_device *idxd; 39bfe1d560SDave Jiang int id; 405fc8e85fSDave Jiang int vector; 41bfe1d560SDave Jiang struct llist_head pending_llist; 42bfe1d560SDave Jiang struct list_head work_list; 43e4f4d8cdSDave Jiang /* 44e4f4d8cdSDave Jiang * Lock to protect access between irq thread process descriptor 45e4f4d8cdSDave Jiang * and irq thread processing error descriptor. 46e4f4d8cdSDave Jiang */ 47e4f4d8cdSDave Jiang spinlock_t list_lock; 48bfe1d560SDave Jiang }; 49bfe1d560SDave Jiang 50bfe1d560SDave Jiang struct idxd_group { 51bfe1d560SDave Jiang struct device conf_dev; 52bfe1d560SDave Jiang struct idxd_device *idxd; 53bfe1d560SDave Jiang struct grpcfg grpcfg; 54bfe1d560SDave Jiang int id; 55bfe1d560SDave Jiang int num_engines; 56bfe1d560SDave Jiang int num_wqs; 57bfe1d560SDave Jiang bool use_token_limit; 58bfe1d560SDave Jiang u8 tokens_allowed; 59bfe1d560SDave Jiang u8 tokens_reserved; 60bfe1d560SDave Jiang int tc_a; 61bfe1d560SDave Jiang int tc_b; 62bfe1d560SDave Jiang }; 63bfe1d560SDave Jiang 64bfe1d560SDave Jiang #define IDXD_MAX_PRIORITY 0xf 65bfe1d560SDave Jiang 66bfe1d560SDave Jiang enum idxd_wq_state { 67bfe1d560SDave Jiang IDXD_WQ_DISABLED = 0, 68bfe1d560SDave Jiang IDXD_WQ_ENABLED, 69bfe1d560SDave Jiang }; 70bfe1d560SDave Jiang 71bfe1d560SDave Jiang enum idxd_wq_flag { 72bfe1d560SDave Jiang WQ_FLAG_DEDICATED = 0, 738e50d392SDave Jiang WQ_FLAG_BLOCK_ON_FAULT, 74bfe1d560SDave Jiang }; 75bfe1d560SDave Jiang 76bfe1d560SDave Jiang enum idxd_wq_type { 77bfe1d560SDave Jiang IDXD_WQT_NONE = 0, 78bfe1d560SDave Jiang IDXD_WQT_KERNEL, 7942d279f9SDave Jiang IDXD_WQT_USER, 8042d279f9SDave Jiang }; 8142d279f9SDave Jiang 8242d279f9SDave Jiang struct idxd_cdev { 8342d279f9SDave Jiang struct cdev cdev; 8442d279f9SDave Jiang struct device *dev; 8542d279f9SDave Jiang int minor; 8642d279f9SDave Jiang struct wait_queue_head err_queue; 87bfe1d560SDave Jiang }; 88bfe1d560SDave Jiang 89bfe1d560SDave Jiang #define IDXD_ALLOCATED_BATCH_SIZE 128U 90bfe1d560SDave Jiang #define WQ_NAME_SIZE 1024 91bfe1d560SDave Jiang #define WQ_TYPE_SIZE 10 92bfe1d560SDave Jiang 93d1dfe5b8SDave Jiang enum idxd_op_type { 94d1dfe5b8SDave Jiang IDXD_OP_BLOCK = 0, 95d1dfe5b8SDave Jiang IDXD_OP_NONBLOCK = 1, 96d1dfe5b8SDave Jiang }; 97d1dfe5b8SDave Jiang 988f47d1a5SDave Jiang enum idxd_complete_type { 998f47d1a5SDave Jiang IDXD_COMPLETE_NORMAL = 0, 1008f47d1a5SDave Jiang IDXD_COMPLETE_ABORT, 1018e50d392SDave Jiang IDXD_COMPLETE_DEV_FAIL, 1028f47d1a5SDave Jiang }; 1038f47d1a5SDave Jiang 10439786285SDave Jiang struct idxd_dma_chan { 10539786285SDave Jiang struct dma_chan chan; 10639786285SDave Jiang struct idxd_wq *wq; 10739786285SDave Jiang }; 10839786285SDave Jiang 109bfe1d560SDave Jiang struct idxd_wq { 1108e50d392SDave Jiang void __iomem *portal; 111bfe1d560SDave Jiang struct device conf_dev; 11242d279f9SDave Jiang struct idxd_cdev idxd_cdev; 113bfe1d560SDave Jiang struct idxd_device *idxd; 114bfe1d560SDave Jiang int id; 115bfe1d560SDave Jiang enum idxd_wq_type type; 116bfe1d560SDave Jiang struct idxd_group *group; 117bfe1d560SDave Jiang int client_count; 118bfe1d560SDave Jiang struct mutex wq_lock; /* mutex for workqueue */ 119bfe1d560SDave Jiang u32 size; 120bfe1d560SDave Jiang u32 threshold; 121bfe1d560SDave Jiang u32 priority; 122bfe1d560SDave Jiang enum idxd_wq_state state; 123bfe1d560SDave Jiang unsigned long flags; 124d98793b5SDave Jiang union wqcfg *wqcfg; 125bfe1d560SDave Jiang u32 vec_ptr; /* interrupt steering */ 126bfe1d560SDave Jiang struct dsa_hw_desc **hw_descs; 127bfe1d560SDave Jiang int num_descs; 128f25b4638SDave Jiang union { 129bfe1d560SDave Jiang struct dsa_completion_record *compls; 130f25b4638SDave Jiang struct iax_completion_record *iax_compls; 131f25b4638SDave Jiang }; 132f25b4638SDave Jiang void *compls_raw; 133bfe1d560SDave Jiang dma_addr_t compls_addr; 134f25b4638SDave Jiang dma_addr_t compls_addr_raw; 135bfe1d560SDave Jiang int compls_size; 136bfe1d560SDave Jiang struct idxd_desc **descs; 1370705107fSDave Jiang struct sbitmap_queue sbq; 13839786285SDave Jiang struct idxd_dma_chan *idxd_chan; 139bfe1d560SDave Jiang char name[WQ_NAME_SIZE + 1]; 140d7aad555SDave Jiang u64 max_xfer_bytes; 141e7184b15SDave Jiang u32 max_batch_size; 14292de5fa2SDave Jiang bool ats_dis; 143bfe1d560SDave Jiang }; 144bfe1d560SDave Jiang 145bfe1d560SDave Jiang struct idxd_engine { 146bfe1d560SDave Jiang struct device conf_dev; 147bfe1d560SDave Jiang int id; 148bfe1d560SDave Jiang struct idxd_group *group; 149bfe1d560SDave Jiang struct idxd_device *idxd; 150bfe1d560SDave Jiang }; 151bfe1d560SDave Jiang 152bfe1d560SDave Jiang /* shadow registers */ 153bfe1d560SDave Jiang struct idxd_hw { 154bfe1d560SDave Jiang u32 version; 155bfe1d560SDave Jiang union gen_cap_reg gen_cap; 156bfe1d560SDave Jiang union wq_cap_reg wq_cap; 157bfe1d560SDave Jiang union group_cap_reg group_cap; 158bfe1d560SDave Jiang union engine_cap_reg engine_cap; 159bfe1d560SDave Jiang struct opcap opcap; 160bfe1d560SDave Jiang }; 161bfe1d560SDave Jiang 162bfe1d560SDave Jiang enum idxd_device_state { 163bfe1d560SDave Jiang IDXD_DEV_HALTED = -1, 164bfe1d560SDave Jiang IDXD_DEV_DISABLED = 0, 165bfe1d560SDave Jiang IDXD_DEV_CONF_READY, 166bfe1d560SDave Jiang IDXD_DEV_ENABLED, 167bfe1d560SDave Jiang }; 168bfe1d560SDave Jiang 169bfe1d560SDave Jiang enum idxd_device_flag { 170bfe1d560SDave Jiang IDXD_FLAG_CONFIGURABLE = 0, 1710d5c10b4SDave Jiang IDXD_FLAG_CMD_RUNNING, 1728e50d392SDave Jiang IDXD_FLAG_PASID_ENABLED, 173bfe1d560SDave Jiang }; 174bfe1d560SDave Jiang 17539786285SDave Jiang struct idxd_dma_dev { 17639786285SDave Jiang struct idxd_device *idxd; 17739786285SDave Jiang struct dma_device dma; 17839786285SDave Jiang }; 17939786285SDave Jiang 180bfe1d560SDave Jiang struct idxd_device { 181bfe1d560SDave Jiang enum idxd_type type; 182bfe1d560SDave Jiang struct device conf_dev; 183bfe1d560SDave Jiang struct list_head list; 184bfe1d560SDave Jiang struct idxd_hw hw; 185bfe1d560SDave Jiang enum idxd_device_state state; 186bfe1d560SDave Jiang unsigned long flags; 187bfe1d560SDave Jiang int id; 18842d279f9SDave Jiang int major; 189ff18de55SDave Jiang u8 cmd_status; 190bfe1d560SDave Jiang 191bfe1d560SDave Jiang struct pci_dev *pdev; 192bfe1d560SDave Jiang void __iomem *reg_base; 193bfe1d560SDave Jiang 194bfe1d560SDave Jiang spinlock_t dev_lock; /* spinlock for device */ 1950d5c10b4SDave Jiang struct completion *cmd_done; 196bfe1d560SDave Jiang struct idxd_group *groups; 197bfe1d560SDave Jiang struct idxd_wq *wqs; 198bfe1d560SDave Jiang struct idxd_engine *engines; 199bfe1d560SDave Jiang 2008e50d392SDave Jiang struct iommu_sva *sva; 2018e50d392SDave Jiang unsigned int pasid; 2028e50d392SDave Jiang 203bfe1d560SDave Jiang int num_groups; 204bfe1d560SDave Jiang 205bfe1d560SDave Jiang u32 msix_perm_offset; 206bfe1d560SDave Jiang u32 wqcfg_offset; 207bfe1d560SDave Jiang u32 grpcfg_offset; 208bfe1d560SDave Jiang u32 perfmon_offset; 209bfe1d560SDave Jiang 210bfe1d560SDave Jiang u64 max_xfer_bytes; 211bfe1d560SDave Jiang u32 max_batch_size; 212bfe1d560SDave Jiang int max_groups; 213bfe1d560SDave Jiang int max_engines; 214bfe1d560SDave Jiang int max_tokens; 215bfe1d560SDave Jiang int max_wqs; 216bfe1d560SDave Jiang int max_wq_size; 217bfe1d560SDave Jiang int token_limit; 218c52ca478SDave Jiang int nr_tokens; /* non-reserved tokens */ 219d98793b5SDave Jiang unsigned int wqcfg_size; 220f25b4638SDave Jiang int compl_size; 221bfe1d560SDave Jiang 222bfe1d560SDave Jiang union sw_err_reg sw_err; 2230d5c10b4SDave Jiang wait_queue_head_t cmd_waitq; 224bfe1d560SDave Jiang int num_wq_irqs; 225bfe1d560SDave Jiang struct idxd_irq_entry *irq_entries; 2268f47d1a5SDave Jiang 22739786285SDave Jiang struct idxd_dma_dev *idxd_dma; 2280d5c10b4SDave Jiang struct workqueue_struct *wq; 2290d5c10b4SDave Jiang struct work_struct work; 230bfe1d560SDave Jiang }; 231bfe1d560SDave Jiang 232bfe1d560SDave Jiang /* IDXD software descriptor */ 233bfe1d560SDave Jiang struct idxd_desc { 234f25b4638SDave Jiang union { 235bfe1d560SDave Jiang struct dsa_hw_desc *hw; 236f25b4638SDave Jiang struct iax_hw_desc *iax_hw; 237f25b4638SDave Jiang }; 238bfe1d560SDave Jiang dma_addr_t desc_dma; 239f25b4638SDave Jiang union { 240bfe1d560SDave Jiang struct dsa_completion_record *completion; 241f25b4638SDave Jiang struct iax_completion_record *iax_completion; 242f25b4638SDave Jiang }; 243bfe1d560SDave Jiang dma_addr_t compl_dma; 2448f47d1a5SDave Jiang struct dma_async_tx_descriptor txd; 245bfe1d560SDave Jiang struct llist_node llnode; 246bfe1d560SDave Jiang struct list_head list; 247bfe1d560SDave Jiang int id; 2480705107fSDave Jiang int cpu; 249bfe1d560SDave Jiang struct idxd_wq *wq; 250bfe1d560SDave Jiang }; 251bfe1d560SDave Jiang 252bfe1d560SDave Jiang #define confdev_to_idxd(dev) container_of(dev, struct idxd_device, conf_dev) 253bfe1d560SDave Jiang #define confdev_to_wq(dev) container_of(dev, struct idxd_wq, conf_dev) 254bfe1d560SDave Jiang 25542d279f9SDave Jiang extern struct bus_type dsa_bus_type; 256f25b4638SDave Jiang extern struct bus_type iax_bus_type; 25742d279f9SDave Jiang 2588e50d392SDave Jiang extern bool support_enqcmd; 259*47c16ac2SDave Jiang extern struct device_type dsa_device_type; 260*47c16ac2SDave Jiang extern struct device_type iax_device_type; 261*47c16ac2SDave Jiang 262*47c16ac2SDave Jiang static inline bool is_dsa_dev(struct device *dev) 263*47c16ac2SDave Jiang { 264*47c16ac2SDave Jiang return dev->type == &dsa_device_type; 265*47c16ac2SDave Jiang } 266*47c16ac2SDave Jiang 267*47c16ac2SDave Jiang static inline bool is_iax_dev(struct device *dev) 268*47c16ac2SDave Jiang { 269*47c16ac2SDave Jiang return dev->type == &iax_device_type; 270*47c16ac2SDave Jiang } 271*47c16ac2SDave Jiang 272*47c16ac2SDave Jiang static inline bool is_idxd_dev(struct device *dev) 273*47c16ac2SDave Jiang { 274*47c16ac2SDave Jiang return is_dsa_dev(dev) || is_iax_dev(dev); 275*47c16ac2SDave Jiang } 2768e50d392SDave Jiang 277bfe1d560SDave Jiang static inline bool wq_dedicated(struct idxd_wq *wq) 278bfe1d560SDave Jiang { 279bfe1d560SDave Jiang return test_bit(WQ_FLAG_DEDICATED, &wq->flags); 280bfe1d560SDave Jiang } 281bfe1d560SDave Jiang 2828e50d392SDave Jiang static inline bool wq_shared(struct idxd_wq *wq) 2838e50d392SDave Jiang { 2848e50d392SDave Jiang return !test_bit(WQ_FLAG_DEDICATED, &wq->flags); 2858e50d392SDave Jiang } 2868e50d392SDave Jiang 2878e50d392SDave Jiang static inline bool device_pasid_enabled(struct idxd_device *idxd) 2888e50d392SDave Jiang { 2898e50d392SDave Jiang return test_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags); 2908e50d392SDave Jiang } 2918e50d392SDave Jiang 2928e50d392SDave Jiang static inline bool device_swq_supported(struct idxd_device *idxd) 2938e50d392SDave Jiang { 2948e50d392SDave Jiang return (support_enqcmd && device_pasid_enabled(idxd)); 2958e50d392SDave Jiang } 2968e50d392SDave Jiang 29742d279f9SDave Jiang enum idxd_portal_prot { 29842d279f9SDave Jiang IDXD_PORTAL_UNLIMITED = 0, 29942d279f9SDave Jiang IDXD_PORTAL_LIMITED, 30042d279f9SDave Jiang }; 30142d279f9SDave Jiang 30242d279f9SDave Jiang static inline int idxd_get_wq_portal_offset(enum idxd_portal_prot prot) 30342d279f9SDave Jiang { 30442d279f9SDave Jiang return prot * 0x1000; 30542d279f9SDave Jiang } 30642d279f9SDave Jiang 30742d279f9SDave Jiang static inline int idxd_get_wq_portal_full_offset(int wq_id, 30842d279f9SDave Jiang enum idxd_portal_prot prot) 30942d279f9SDave Jiang { 31042d279f9SDave Jiang return ((wq_id * 4) << PAGE_SHIFT) + idxd_get_wq_portal_offset(prot); 31142d279f9SDave Jiang } 31242d279f9SDave Jiang 313c52ca478SDave Jiang static inline void idxd_wq_get(struct idxd_wq *wq) 314c52ca478SDave Jiang { 315c52ca478SDave Jiang wq->client_count++; 316c52ca478SDave Jiang } 317c52ca478SDave Jiang 318c52ca478SDave Jiang static inline void idxd_wq_put(struct idxd_wq *wq) 319c52ca478SDave Jiang { 320c52ca478SDave Jiang wq->client_count--; 321c52ca478SDave Jiang } 322c52ca478SDave Jiang 323c52ca478SDave Jiang static inline int idxd_wq_refcount(struct idxd_wq *wq) 324c52ca478SDave Jiang { 325c52ca478SDave Jiang return wq->client_count; 326c52ca478SDave Jiang }; 327c52ca478SDave Jiang 328*47c16ac2SDave Jiang struct ida *idxd_ida(struct idxd_device *idxd); 329bfe1d560SDave Jiang const char *idxd_get_dev_name(struct idxd_device *idxd); 330c52ca478SDave Jiang int idxd_register_bus_type(void); 331c52ca478SDave Jiang void idxd_unregister_bus_type(void); 332*47c16ac2SDave Jiang int idxd_register_devices(struct idxd_device *idxd); 333*47c16ac2SDave Jiang void idxd_unregister_devices(struct idxd_device *idxd); 334c52ca478SDave Jiang int idxd_register_driver(void); 335c52ca478SDave Jiang void idxd_unregister_driver(void); 33642d279f9SDave Jiang struct bus_type *idxd_get_bus_type(struct idxd_device *idxd); 337*47c16ac2SDave Jiang struct device_type *idxd_get_device_type(struct idxd_device *idxd); 338bfe1d560SDave Jiang 339bfe1d560SDave Jiang /* device interrupt control */ 3406df0e6c5SDave Jiang void idxd_msix_perm_setup(struct idxd_device *idxd); 3416df0e6c5SDave Jiang void idxd_msix_perm_clear(struct idxd_device *idxd); 342bfe1d560SDave Jiang irqreturn_t idxd_irq_handler(int vec, void *data); 343bfe1d560SDave Jiang irqreturn_t idxd_misc_thread(int vec, void *data); 344bfe1d560SDave Jiang irqreturn_t idxd_wq_thread(int irq, void *data); 345bfe1d560SDave Jiang void idxd_mask_error_interrupts(struct idxd_device *idxd); 346bfe1d560SDave Jiang void idxd_unmask_error_interrupts(struct idxd_device *idxd); 347bfe1d560SDave Jiang void idxd_mask_msix_vectors(struct idxd_device *idxd); 3484548a6adSDave Jiang void idxd_mask_msix_vector(struct idxd_device *idxd, int vec_id); 3494548a6adSDave Jiang void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id); 350bfe1d560SDave Jiang 351bfe1d560SDave Jiang /* device control */ 35289e3becdSDave Jiang int idxd_device_init_reset(struct idxd_device *idxd); 353bfe1d560SDave Jiang int idxd_device_enable(struct idxd_device *idxd); 354bfe1d560SDave Jiang int idxd_device_disable(struct idxd_device *idxd); 3550d5c10b4SDave Jiang void idxd_device_reset(struct idxd_device *idxd); 356bfe1d560SDave Jiang void idxd_device_cleanup(struct idxd_device *idxd); 357bfe1d560SDave Jiang int idxd_device_config(struct idxd_device *idxd); 358bfe1d560SDave Jiang void idxd_device_wqs_clear_state(struct idxd_device *idxd); 3598e50d392SDave Jiang void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid); 360bfe1d560SDave Jiang 361bfe1d560SDave Jiang /* work queue control */ 362bfe1d560SDave Jiang int idxd_wq_alloc_resources(struct idxd_wq *wq); 363bfe1d560SDave Jiang void idxd_wq_free_resources(struct idxd_wq *wq); 364bfe1d560SDave Jiang int idxd_wq_enable(struct idxd_wq *wq); 365bfe1d560SDave Jiang int idxd_wq_disable(struct idxd_wq *wq); 3660d5c10b4SDave Jiang void idxd_wq_drain(struct idxd_wq *wq); 367ea9aadc0SDave Jiang void idxd_wq_reset(struct idxd_wq *wq); 368c52ca478SDave Jiang int idxd_wq_map_portal(struct idxd_wq *wq); 369c52ca478SDave Jiang void idxd_wq_unmap_portal(struct idxd_wq *wq); 370da32b28cSDave Jiang void idxd_wq_disable_cleanup(struct idxd_wq *wq); 3718e50d392SDave Jiang int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid); 3728e50d392SDave Jiang int idxd_wq_disable_pasid(struct idxd_wq *wq); 373bfe1d560SDave Jiang 374d1dfe5b8SDave Jiang /* submission */ 375d1dfe5b8SDave Jiang int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc); 376d1dfe5b8SDave Jiang struct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype); 377d1dfe5b8SDave Jiang void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc); 378d1dfe5b8SDave Jiang 3798f47d1a5SDave Jiang /* dmaengine */ 3808f47d1a5SDave Jiang int idxd_register_dma_device(struct idxd_device *idxd); 3818f47d1a5SDave Jiang void idxd_unregister_dma_device(struct idxd_device *idxd); 3828f47d1a5SDave Jiang int idxd_register_dma_channel(struct idxd_wq *wq); 3838f47d1a5SDave Jiang void idxd_unregister_dma_channel(struct idxd_wq *wq); 3848f47d1a5SDave Jiang void idxd_parse_completion_status(u8 status, enum dmaengine_tx_result *res); 3858f47d1a5SDave Jiang void idxd_dma_complete_txd(struct idxd_desc *desc, 3868f47d1a5SDave Jiang enum idxd_complete_type comp_type); 3878f47d1a5SDave Jiang 38842d279f9SDave Jiang /* cdev */ 38942d279f9SDave Jiang int idxd_cdev_register(void); 39042d279f9SDave Jiang void idxd_cdev_remove(void); 39142d279f9SDave Jiang int idxd_cdev_get_major(struct idxd_device *idxd); 39242d279f9SDave Jiang int idxd_wq_add_cdev(struct idxd_wq *wq); 39342d279f9SDave Jiang void idxd_wq_del_cdev(struct idxd_wq *wq); 39442d279f9SDave Jiang 395bfe1d560SDave Jiang #endif 396