1 /* 2 * Intel MIC Platform Software Stack (MPSS) 3 * 4 * Copyright(c) 2013 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License, version 2, as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * The full GNU General Public License is included in this distribution in 16 * the file called "COPYING". 17 * 18 * Intel MIC Host driver. 19 * 20 */ 21 #ifndef _MIC_INTR_H_ 22 #define _MIC_INTR_H_ 23 24 #include <linux/bitops.h> 25 #include <linux/interrupt.h> 26 /* 27 * The minimum number of msix vectors required for normal operation. 28 * 3 for virtio network, console and block devices. 29 * 1 for card shutdown notifications. 30 * 4 for host owned DMA channels. 31 */ 32 #define MIC_MIN_MSIX 8 33 #define MIC_NUM_OFFSETS 32 34 35 /** 36 * mic_intr_source - The type of source that will generate 37 * the interrupt.The number of types needs to be in sync with 38 * MIC_NUM_INTR_TYPES 39 * 40 * MIC_INTR_DB: The source is a doorbell 41 * MIC_INTR_DMA: The source is a DMA channel 42 * MIC_INTR_ERR: The source is an error interrupt e.g. SBOX ERR 43 * MIC_NUM_INTR_TYPES: Total number of interrupt sources. 44 */ 45 enum mic_intr_type { 46 MIC_INTR_DB = 0, 47 MIC_INTR_DMA, 48 MIC_INTR_ERR, 49 MIC_NUM_INTR_TYPES 50 }; 51 52 /** 53 * struct mic_intr_info - Contains h/w specific interrupt sources 54 * information. 55 * 56 * @intr_start_idx: Contains the starting indexes of the 57 * interrupt types. 58 * @intr_len: Contains the length of the interrupt types. 59 */ 60 struct mic_intr_info { 61 u16 intr_start_idx[MIC_NUM_INTR_TYPES]; 62 u16 intr_len[MIC_NUM_INTR_TYPES]; 63 }; 64 65 /** 66 * struct mic_irq_info - OS specific irq information 67 * 68 * @next_avail_src: next available doorbell that can be assigned. 69 * @msix_entries: msix entries allocated while setting up MSI-x 70 * @mic_msi_map: The MSI/MSI-x mapping information. 71 * @num_vectors: The number of MSI/MSI-x vectors that have been allocated. 72 * @cb_ida: callback ID allocator to track the callbacks registered. 73 * @mic_intr_lock: spinlock to protect the interrupt callback list. 74 * @mic_thread_lock: spinlock to protect the thread callback list. 75 * This lock is used to protect against thread_fn while 76 * mic_intr_lock is used to protect against interrupt handler. 77 * @cb_list: Array of callback lists one for each source. 78 * @mask: Mask used by the main thread fn to call the underlying thread fns. 79 */ 80 struct mic_irq_info { 81 int next_avail_src; 82 struct msix_entry *msix_entries; 83 u32 *mic_msi_map; 84 u16 num_vectors; 85 struct ida cb_ida; 86 spinlock_t mic_intr_lock; 87 spinlock_t mic_thread_lock; 88 struct list_head *cb_list; 89 unsigned long mask; 90 }; 91 92 /** 93 * struct mic_intr_cb - Interrupt callback structure. 94 * 95 * @handler: The callback function 96 * @thread_fn: The thread_fn. 97 * @data: Private data of the requester. 98 * @cb_id: The callback id. Identifies this callback. 99 * @list: list head pointing to the next callback structure. 100 */ 101 struct mic_intr_cb { 102 irq_handler_t handler; 103 irq_handler_t thread_fn; 104 void *data; 105 int cb_id; 106 struct list_head list; 107 }; 108 109 /** 110 * struct mic_irq - opaque pointer used as cookie 111 */ 112 struct mic_irq; 113 114 /* Forward declaration */ 115 struct mic_device; 116 117 /** 118 * struct mic_hw_intr_ops: MIC HW specific interrupt operations 119 * @intr_init: Initialize H/W specific interrupt information. 120 * @enable_interrupts: Enable interrupts from the hardware. 121 * @disable_interrupts: Disable interrupts from the hardware. 122 * @program_msi_to_src_map: Update MSI mapping registers with 123 * irq information. 124 * @read_msi_to_src_map: Read MSI mapping registers containing 125 * irq information. 126 */ 127 struct mic_hw_intr_ops { 128 void (*intr_init)(struct mic_device *mdev); 129 void (*enable_interrupts)(struct mic_device *mdev); 130 void (*disable_interrupts)(struct mic_device *mdev); 131 void (*program_msi_to_src_map) (struct mic_device *mdev, 132 int idx, int intr_src, bool set); 133 u32 (*read_msi_to_src_map) (struct mic_device *mdev, 134 int idx); 135 }; 136 137 int mic_next_db(struct mic_device *mdev); 138 struct mic_irq * 139 mic_request_threaded_irq(struct mic_device *mdev, 140 irq_handler_t handler, irq_handler_t thread_fn, 141 const char *name, void *data, int intr_src, 142 enum mic_intr_type type); 143 void mic_free_irq(struct mic_device *mdev, 144 struct mic_irq *cookie, void *data); 145 int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev); 146 void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev); 147 void mic_intr_restore(struct mic_device *mdev); 148 #endif 149