1a4b16dadSTom Zanussi // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
2a4b16dadSTom Zanussi /* Copyright(c) 2014 - 2020 Intel Corporation */
3a4b16dadSTom Zanussi #include <linux/kernel.h>
4a4b16dadSTom Zanussi #include <linux/init.h>
5a4b16dadSTom Zanussi #include <linux/types.h>
6a4b16dadSTom Zanussi #include <linux/pci.h>
7a4b16dadSTom Zanussi #include <linux/slab.h>
8a4b16dadSTom Zanussi #include <linux/errno.h>
9a4b16dadSTom Zanussi #include <linux/interrupt.h>
10a4b16dadSTom Zanussi #include "adf_accel_devices.h"
11a4b16dadSTom Zanussi #include "adf_common_drv.h"
12a4b16dadSTom Zanussi #include "adf_cfg.h"
13a4b16dadSTom Zanussi #include "adf_cfg_strings.h"
14a4b16dadSTom Zanussi #include "adf_cfg_common.h"
15a4b16dadSTom Zanussi #include "adf_transport_access_macros.h"
16a4b16dadSTom Zanussi #include "adf_transport_internal.h"
17a4b16dadSTom Zanussi
18a4b16dadSTom Zanussi #define ADF_MAX_NUM_VFS 32
19a4b16dadSTom Zanussi static struct workqueue_struct *adf_misc_wq;
20a4b16dadSTom Zanussi
adf_enable_msix(struct adf_accel_dev * accel_dev)21a4b16dadSTom Zanussi static int adf_enable_msix(struct adf_accel_dev *accel_dev)
22a4b16dadSTom Zanussi {
23a4b16dadSTom Zanussi struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
24a4b16dadSTom Zanussi struct adf_hw_device_data *hw_data = accel_dev->hw_device;
25a4b16dadSTom Zanussi u32 msix_num_entries = hw_data->num_banks + 1;
26a4b16dadSTom Zanussi int ret;
27a4b16dadSTom Zanussi
28a4b16dadSTom Zanussi if (hw_data->set_msix_rttable)
29a4b16dadSTom Zanussi hw_data->set_msix_rttable(accel_dev);
30a4b16dadSTom Zanussi
31a4b16dadSTom Zanussi ret = pci_alloc_irq_vectors(pci_dev_info->pci_dev, msix_num_entries,
32a4b16dadSTom Zanussi msix_num_entries, PCI_IRQ_MSIX);
33a4b16dadSTom Zanussi if (unlikely(ret < 0)) {
34a4b16dadSTom Zanussi dev_err(&GET_DEV(accel_dev),
35a4b16dadSTom Zanussi "Failed to allocate %d MSI-X vectors\n",
36a4b16dadSTom Zanussi msix_num_entries);
37a4b16dadSTom Zanussi return ret;
38a4b16dadSTom Zanussi }
39a4b16dadSTom Zanussi return 0;
40a4b16dadSTom Zanussi }
41a4b16dadSTom Zanussi
adf_disable_msix(struct adf_accel_pci * pci_dev_info)42a4b16dadSTom Zanussi static void adf_disable_msix(struct adf_accel_pci *pci_dev_info)
43a4b16dadSTom Zanussi {
44a4b16dadSTom Zanussi pci_free_irq_vectors(pci_dev_info->pci_dev);
45a4b16dadSTom Zanussi }
46a4b16dadSTom Zanussi
adf_msix_isr_bundle(int irq,void * bank_ptr)47a4b16dadSTom Zanussi static irqreturn_t adf_msix_isr_bundle(int irq, void *bank_ptr)
48a4b16dadSTom Zanussi {
49a4b16dadSTom Zanussi struct adf_etr_bank_data *bank = bank_ptr;
50a4b16dadSTom Zanussi struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(bank->accel_dev);
51a4b16dadSTom Zanussi
52a4b16dadSTom Zanussi csr_ops->write_csr_int_flag_and_col(bank->csr_addr, bank->bank_number,
53a4b16dadSTom Zanussi 0);
54a4b16dadSTom Zanussi tasklet_hi_schedule(&bank->resp_handler);
55a4b16dadSTom Zanussi return IRQ_HANDLED;
56a4b16dadSTom Zanussi }
57a4b16dadSTom Zanussi
58a4b16dadSTom Zanussi #ifdef CONFIG_PCI_IOV
adf_enable_vf2pf_interrupts(struct adf_accel_dev * accel_dev,u32 vf_mask)59a4b16dadSTom Zanussi void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask)
60a4b16dadSTom Zanussi {
61a4b16dadSTom Zanussi void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
62a4b16dadSTom Zanussi unsigned long flags;
63a4b16dadSTom Zanussi
64a4b16dadSTom Zanussi spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags);
65a4b16dadSTom Zanussi GET_PFVF_OPS(accel_dev)->enable_vf2pf_interrupts(pmisc_addr, vf_mask);
66a4b16dadSTom Zanussi spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags);
67a4b16dadSTom Zanussi }
68a4b16dadSTom Zanussi
adf_disable_all_vf2pf_interrupts(struct adf_accel_dev * accel_dev)69a4b16dadSTom Zanussi void adf_disable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev)
70a4b16dadSTom Zanussi {
71a4b16dadSTom Zanussi void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
72a4b16dadSTom Zanussi unsigned long flags;
73a4b16dadSTom Zanussi
74a4b16dadSTom Zanussi spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags);
75a4b16dadSTom Zanussi GET_PFVF_OPS(accel_dev)->disable_all_vf2pf_interrupts(pmisc_addr);
76a4b16dadSTom Zanussi spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags);
77a4b16dadSTom Zanussi }
78a4b16dadSTom Zanussi
adf_disable_pending_vf2pf_interrupts(struct adf_accel_dev * accel_dev)79a4b16dadSTom Zanussi static u32 adf_disable_pending_vf2pf_interrupts(struct adf_accel_dev *accel_dev)
80a4b16dadSTom Zanussi {
81a4b16dadSTom Zanussi void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
82a4b16dadSTom Zanussi u32 pending;
83a4b16dadSTom Zanussi
84a4b16dadSTom Zanussi spin_lock(&accel_dev->pf.vf2pf_ints_lock);
85a4b16dadSTom Zanussi pending = GET_PFVF_OPS(accel_dev)->disable_pending_vf2pf_interrupts(pmisc_addr);
86a4b16dadSTom Zanussi spin_unlock(&accel_dev->pf.vf2pf_ints_lock);
87a4b16dadSTom Zanussi
88a4b16dadSTom Zanussi return pending;
89a4b16dadSTom Zanussi }
90a4b16dadSTom Zanussi
adf_handle_vf2pf_int(struct adf_accel_dev * accel_dev)91a4b16dadSTom Zanussi static bool adf_handle_vf2pf_int(struct adf_accel_dev *accel_dev)
92a4b16dadSTom Zanussi {
93a4b16dadSTom Zanussi bool irq_handled = false;
94a4b16dadSTom Zanussi unsigned long vf_mask;
95a4b16dadSTom Zanussi
96a4b16dadSTom Zanussi /* Get the interrupt sources triggered by VFs, except for those already disabled */
97a4b16dadSTom Zanussi vf_mask = adf_disable_pending_vf2pf_interrupts(accel_dev);
98a4b16dadSTom Zanussi if (vf_mask) {
99a4b16dadSTom Zanussi struct adf_accel_vf_info *vf_info;
100a4b16dadSTom Zanussi int i;
101a4b16dadSTom Zanussi
102a4b16dadSTom Zanussi /*
103a4b16dadSTom Zanussi * Handle VF2PF interrupt unless the VF is malicious and
104a4b16dadSTom Zanussi * is attempting to flood the host OS with VF2PF interrupts.
105a4b16dadSTom Zanussi */
106a4b16dadSTom Zanussi for_each_set_bit(i, &vf_mask, ADF_MAX_NUM_VFS) {
107a4b16dadSTom Zanussi vf_info = accel_dev->pf.vf_info + i;
108a4b16dadSTom Zanussi
109a4b16dadSTom Zanussi if (!__ratelimit(&vf_info->vf2pf_ratelimit)) {
110a4b16dadSTom Zanussi dev_info(&GET_DEV(accel_dev),
111a4b16dadSTom Zanussi "Too many ints from VF%d\n",
112a4b16dadSTom Zanussi vf_info->vf_nr);
113a4b16dadSTom Zanussi continue;
114a4b16dadSTom Zanussi }
115a4b16dadSTom Zanussi
116a4b16dadSTom Zanussi adf_schedule_vf2pf_handler(vf_info);
117a4b16dadSTom Zanussi irq_handled = true;
118a4b16dadSTom Zanussi }
119a4b16dadSTom Zanussi }
120a4b16dadSTom Zanussi return irq_handled;
121a4b16dadSTom Zanussi }
122a4b16dadSTom Zanussi #endif /* CONFIG_PCI_IOV */
123a4b16dadSTom Zanussi
adf_handle_pm_int(struct adf_accel_dev * accel_dev)124a4b16dadSTom Zanussi static bool adf_handle_pm_int(struct adf_accel_dev *accel_dev)
125a4b16dadSTom Zanussi {
126a4b16dadSTom Zanussi struct adf_hw_device_data *hw_data = accel_dev->hw_device;
127a4b16dadSTom Zanussi
128a4b16dadSTom Zanussi if (hw_data->handle_pm_interrupt &&
129a4b16dadSTom Zanussi hw_data->handle_pm_interrupt(accel_dev))
130a4b16dadSTom Zanussi return true;
131a4b16dadSTom Zanussi
132a4b16dadSTom Zanussi return false;
133a4b16dadSTom Zanussi }
134a4b16dadSTom Zanussi
adf_msix_isr_ae(int irq,void * dev_ptr)135a4b16dadSTom Zanussi static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
136a4b16dadSTom Zanussi {
137a4b16dadSTom Zanussi struct adf_accel_dev *accel_dev = dev_ptr;
138a4b16dadSTom Zanussi
139a4b16dadSTom Zanussi #ifdef CONFIG_PCI_IOV
140a4b16dadSTom Zanussi /* If SR-IOV is enabled (vf_info is non-NULL), check for VF->PF ints */
141a4b16dadSTom Zanussi if (accel_dev->pf.vf_info && adf_handle_vf2pf_int(accel_dev))
142a4b16dadSTom Zanussi return IRQ_HANDLED;
143a4b16dadSTom Zanussi #endif /* CONFIG_PCI_IOV */
144a4b16dadSTom Zanussi
145a4b16dadSTom Zanussi if (adf_handle_pm_int(accel_dev))
146a4b16dadSTom Zanussi return IRQ_HANDLED;
147a4b16dadSTom Zanussi
148a4b16dadSTom Zanussi dev_dbg(&GET_DEV(accel_dev), "qat_dev%d spurious AE interrupt\n",
149a4b16dadSTom Zanussi accel_dev->accel_id);
150a4b16dadSTom Zanussi
151a4b16dadSTom Zanussi return IRQ_NONE;
152a4b16dadSTom Zanussi }
153a4b16dadSTom Zanussi
adf_free_irqs(struct adf_accel_dev * accel_dev)154a4b16dadSTom Zanussi static void adf_free_irqs(struct adf_accel_dev *accel_dev)
155a4b16dadSTom Zanussi {
156a4b16dadSTom Zanussi struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
157a4b16dadSTom Zanussi struct adf_hw_device_data *hw_data = accel_dev->hw_device;
158a4b16dadSTom Zanussi struct adf_irq *irqs = pci_dev_info->msix_entries.irqs;
159a4b16dadSTom Zanussi struct adf_etr_data *etr_data = accel_dev->transport;
160a4b16dadSTom Zanussi int clust_irq = hw_data->num_banks;
161a4b16dadSTom Zanussi int irq, i = 0;
162a4b16dadSTom Zanussi
163a4b16dadSTom Zanussi if (pci_dev_info->msix_entries.num_entries > 1) {
164a4b16dadSTom Zanussi for (i = 0; i < hw_data->num_banks; i++) {
165a4b16dadSTom Zanussi if (irqs[i].enabled) {
166a4b16dadSTom Zanussi irq = pci_irq_vector(pci_dev_info->pci_dev, i);
167a4b16dadSTom Zanussi irq_set_affinity_hint(irq, NULL);
168a4b16dadSTom Zanussi free_irq(irq, &etr_data->banks[i]);
169a4b16dadSTom Zanussi }
170a4b16dadSTom Zanussi }
171a4b16dadSTom Zanussi }
172a4b16dadSTom Zanussi
173a4b16dadSTom Zanussi if (irqs[i].enabled) {
174a4b16dadSTom Zanussi irq = pci_irq_vector(pci_dev_info->pci_dev, clust_irq);
175a4b16dadSTom Zanussi free_irq(irq, accel_dev);
176a4b16dadSTom Zanussi }
177a4b16dadSTom Zanussi }
178a4b16dadSTom Zanussi
adf_request_irqs(struct adf_accel_dev * accel_dev)179a4b16dadSTom Zanussi static int adf_request_irqs(struct adf_accel_dev *accel_dev)
180a4b16dadSTom Zanussi {
181a4b16dadSTom Zanussi struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
182a4b16dadSTom Zanussi struct adf_hw_device_data *hw_data = accel_dev->hw_device;
183a4b16dadSTom Zanussi struct adf_irq *irqs = pci_dev_info->msix_entries.irqs;
184a4b16dadSTom Zanussi struct adf_etr_data *etr_data = accel_dev->transport;
185a4b16dadSTom Zanussi int clust_irq = hw_data->num_banks;
186a4b16dadSTom Zanussi int ret, irq, i = 0;
187a4b16dadSTom Zanussi char *name;
188a4b16dadSTom Zanussi
189a4b16dadSTom Zanussi /* Request msix irq for all banks unless SR-IOV enabled */
190a4b16dadSTom Zanussi if (!accel_dev->pf.vf_info) {
191a4b16dadSTom Zanussi for (i = 0; i < hw_data->num_banks; i++) {
192a4b16dadSTom Zanussi struct adf_etr_bank_data *bank = &etr_data->banks[i];
193a4b16dadSTom Zanussi unsigned int cpu, cpus = num_online_cpus();
194a4b16dadSTom Zanussi
195a4b16dadSTom Zanussi name = irqs[i].name;
196a4b16dadSTom Zanussi snprintf(name, ADF_MAX_MSIX_VECTOR_NAME,
197a4b16dadSTom Zanussi "qat%d-bundle%d", accel_dev->accel_id, i);
198a4b16dadSTom Zanussi irq = pci_irq_vector(pci_dev_info->pci_dev, i);
199a4b16dadSTom Zanussi if (unlikely(irq < 0)) {
200a4b16dadSTom Zanussi dev_err(&GET_DEV(accel_dev),
201a4b16dadSTom Zanussi "Failed to get IRQ number of device vector %d - %s\n",
202a4b16dadSTom Zanussi i, name);
203a4b16dadSTom Zanussi ret = irq;
204a4b16dadSTom Zanussi goto err;
205a4b16dadSTom Zanussi }
206a4b16dadSTom Zanussi ret = request_irq(irq, adf_msix_isr_bundle, 0,
207a4b16dadSTom Zanussi &name[0], bank);
208a4b16dadSTom Zanussi if (ret) {
209a4b16dadSTom Zanussi dev_err(&GET_DEV(accel_dev),
210a4b16dadSTom Zanussi "Failed to allocate IRQ %d for %s\n",
211a4b16dadSTom Zanussi irq, name);
212a4b16dadSTom Zanussi goto err;
213a4b16dadSTom Zanussi }
214a4b16dadSTom Zanussi
215a4b16dadSTom Zanussi cpu = ((accel_dev->accel_id * hw_data->num_banks) +
216a4b16dadSTom Zanussi i) % cpus;
217a4b16dadSTom Zanussi irq_set_affinity_hint(irq, get_cpu_mask(cpu));
218a4b16dadSTom Zanussi irqs[i].enabled = true;
219a4b16dadSTom Zanussi }
220a4b16dadSTom Zanussi }
221a4b16dadSTom Zanussi
222a4b16dadSTom Zanussi /* Request msix irq for AE */
223a4b16dadSTom Zanussi name = irqs[i].name;
224a4b16dadSTom Zanussi snprintf(name, ADF_MAX_MSIX_VECTOR_NAME,
225a4b16dadSTom Zanussi "qat%d-ae-cluster", accel_dev->accel_id);
226a4b16dadSTom Zanussi irq = pci_irq_vector(pci_dev_info->pci_dev, clust_irq);
227a4b16dadSTom Zanussi if (unlikely(irq < 0)) {
228a4b16dadSTom Zanussi dev_err(&GET_DEV(accel_dev),
229a4b16dadSTom Zanussi "Failed to get IRQ number of device vector %d - %s\n",
230a4b16dadSTom Zanussi i, name);
231a4b16dadSTom Zanussi ret = irq;
232a4b16dadSTom Zanussi goto err;
233a4b16dadSTom Zanussi }
234a4b16dadSTom Zanussi ret = request_irq(irq, adf_msix_isr_ae, 0, &name[0], accel_dev);
235a4b16dadSTom Zanussi if (ret) {
236a4b16dadSTom Zanussi dev_err(&GET_DEV(accel_dev),
237a4b16dadSTom Zanussi "Failed to allocate IRQ %d for %s\n", irq, name);
238a4b16dadSTom Zanussi goto err;
239a4b16dadSTom Zanussi }
240a4b16dadSTom Zanussi irqs[i].enabled = true;
241a4b16dadSTom Zanussi return ret;
242a4b16dadSTom Zanussi err:
243a4b16dadSTom Zanussi adf_free_irqs(accel_dev);
244a4b16dadSTom Zanussi return ret;
245a4b16dadSTom Zanussi }
246a4b16dadSTom Zanussi
adf_isr_alloc_msix_vectors_data(struct adf_accel_dev * accel_dev)247a4b16dadSTom Zanussi static int adf_isr_alloc_msix_vectors_data(struct adf_accel_dev *accel_dev)
248a4b16dadSTom Zanussi {
249a4b16dadSTom Zanussi struct adf_hw_device_data *hw_data = accel_dev->hw_device;
250a4b16dadSTom Zanussi u32 msix_num_entries = 1;
251a4b16dadSTom Zanussi struct adf_irq *irqs;
252a4b16dadSTom Zanussi
253a4b16dadSTom Zanussi /* If SR-IOV is disabled (vf_info is NULL), add entries for each bank */
254a4b16dadSTom Zanussi if (!accel_dev->pf.vf_info)
255a4b16dadSTom Zanussi msix_num_entries += hw_data->num_banks;
256a4b16dadSTom Zanussi
257a4b16dadSTom Zanussi irqs = kzalloc_node(msix_num_entries * sizeof(*irqs),
258a4b16dadSTom Zanussi GFP_KERNEL, dev_to_node(&GET_DEV(accel_dev)));
259a4b16dadSTom Zanussi if (!irqs)
260a4b16dadSTom Zanussi return -ENOMEM;
261a4b16dadSTom Zanussi
262a4b16dadSTom Zanussi accel_dev->accel_pci_dev.msix_entries.num_entries = msix_num_entries;
263a4b16dadSTom Zanussi accel_dev->accel_pci_dev.msix_entries.irqs = irqs;
264a4b16dadSTom Zanussi return 0;
265a4b16dadSTom Zanussi }
266a4b16dadSTom Zanussi
adf_isr_free_msix_vectors_data(struct adf_accel_dev * accel_dev)267a4b16dadSTom Zanussi static void adf_isr_free_msix_vectors_data(struct adf_accel_dev *accel_dev)
268a4b16dadSTom Zanussi {
269a4b16dadSTom Zanussi kfree(accel_dev->accel_pci_dev.msix_entries.irqs);
270a4b16dadSTom Zanussi accel_dev->accel_pci_dev.msix_entries.irqs = NULL;
271a4b16dadSTom Zanussi }
272a4b16dadSTom Zanussi
adf_setup_bh(struct adf_accel_dev * accel_dev)273a4b16dadSTom Zanussi static int adf_setup_bh(struct adf_accel_dev *accel_dev)
274a4b16dadSTom Zanussi {
275a4b16dadSTom Zanussi struct adf_etr_data *priv_data = accel_dev->transport;
276a4b16dadSTom Zanussi struct adf_hw_device_data *hw_data = accel_dev->hw_device;
277a4b16dadSTom Zanussi int i;
278a4b16dadSTom Zanussi
279a4b16dadSTom Zanussi for (i = 0; i < hw_data->num_banks; i++)
280a4b16dadSTom Zanussi tasklet_init(&priv_data->banks[i].resp_handler,
281a4b16dadSTom Zanussi adf_response_handler,
282a4b16dadSTom Zanussi (unsigned long)&priv_data->banks[i]);
283a4b16dadSTom Zanussi return 0;
284a4b16dadSTom Zanussi }
285a4b16dadSTom Zanussi
adf_cleanup_bh(struct adf_accel_dev * accel_dev)286a4b16dadSTom Zanussi static void adf_cleanup_bh(struct adf_accel_dev *accel_dev)
287a4b16dadSTom Zanussi {
288a4b16dadSTom Zanussi struct adf_etr_data *priv_data = accel_dev->transport;
289a4b16dadSTom Zanussi struct adf_hw_device_data *hw_data = accel_dev->hw_device;
290a4b16dadSTom Zanussi int i;
291a4b16dadSTom Zanussi
292a4b16dadSTom Zanussi for (i = 0; i < hw_data->num_banks; i++) {
293a4b16dadSTom Zanussi tasklet_disable(&priv_data->banks[i].resp_handler);
294a4b16dadSTom Zanussi tasklet_kill(&priv_data->banks[i].resp_handler);
295a4b16dadSTom Zanussi }
296a4b16dadSTom Zanussi }
297a4b16dadSTom Zanussi
298a4b16dadSTom Zanussi /**
299a4b16dadSTom Zanussi * adf_isr_resource_free() - Free IRQ for acceleration device
300a4b16dadSTom Zanussi * @accel_dev: Pointer to acceleration device.
301a4b16dadSTom Zanussi *
302a4b16dadSTom Zanussi * Function frees interrupts for acceleration device.
303a4b16dadSTom Zanussi */
adf_isr_resource_free(struct adf_accel_dev * accel_dev)304a4b16dadSTom Zanussi void adf_isr_resource_free(struct adf_accel_dev *accel_dev)
305a4b16dadSTom Zanussi {
306a4b16dadSTom Zanussi adf_free_irqs(accel_dev);
307a4b16dadSTom Zanussi adf_cleanup_bh(accel_dev);
308a4b16dadSTom Zanussi adf_disable_msix(&accel_dev->accel_pci_dev);
309a4b16dadSTom Zanussi adf_isr_free_msix_vectors_data(accel_dev);
310a4b16dadSTom Zanussi }
311a4b16dadSTom Zanussi EXPORT_SYMBOL_GPL(adf_isr_resource_free);
312a4b16dadSTom Zanussi
313a4b16dadSTom Zanussi /**
314a4b16dadSTom Zanussi * adf_isr_resource_alloc() - Allocate IRQ for acceleration device
315a4b16dadSTom Zanussi * @accel_dev: Pointer to acceleration device.
316a4b16dadSTom Zanussi *
317a4b16dadSTom Zanussi * Function allocates interrupts for acceleration device.
318a4b16dadSTom Zanussi *
319a4b16dadSTom Zanussi * Return: 0 on success, error code otherwise.
320a4b16dadSTom Zanussi */
adf_isr_resource_alloc(struct adf_accel_dev * accel_dev)321a4b16dadSTom Zanussi int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev)
322a4b16dadSTom Zanussi {
323a4b16dadSTom Zanussi int ret;
324a4b16dadSTom Zanussi
325a4b16dadSTom Zanussi ret = adf_isr_alloc_msix_vectors_data(accel_dev);
326a4b16dadSTom Zanussi if (ret)
327a4b16dadSTom Zanussi goto err_out;
328a4b16dadSTom Zanussi
329a4b16dadSTom Zanussi ret = adf_enable_msix(accel_dev);
330a4b16dadSTom Zanussi if (ret)
331a4b16dadSTom Zanussi goto err_free_msix_table;
332a4b16dadSTom Zanussi
333a4b16dadSTom Zanussi ret = adf_setup_bh(accel_dev);
334a4b16dadSTom Zanussi if (ret)
335a4b16dadSTom Zanussi goto err_disable_msix;
336a4b16dadSTom Zanussi
337a4b16dadSTom Zanussi ret = adf_request_irqs(accel_dev);
338a4b16dadSTom Zanussi if (ret)
339a4b16dadSTom Zanussi goto err_cleanup_bh;
340a4b16dadSTom Zanussi
341a4b16dadSTom Zanussi return 0;
342a4b16dadSTom Zanussi
343a4b16dadSTom Zanussi err_cleanup_bh:
344a4b16dadSTom Zanussi adf_cleanup_bh(accel_dev);
345a4b16dadSTom Zanussi
346a4b16dadSTom Zanussi err_disable_msix:
347a4b16dadSTom Zanussi adf_disable_msix(&accel_dev->accel_pci_dev);
348a4b16dadSTom Zanussi
349a4b16dadSTom Zanussi err_free_msix_table:
350a4b16dadSTom Zanussi adf_isr_free_msix_vectors_data(accel_dev);
351a4b16dadSTom Zanussi
352a4b16dadSTom Zanussi err_out:
353a4b16dadSTom Zanussi return ret;
354a4b16dadSTom Zanussi }
355a4b16dadSTom Zanussi EXPORT_SYMBOL_GPL(adf_isr_resource_alloc);
356a4b16dadSTom Zanussi
357a4b16dadSTom Zanussi /**
358a4b16dadSTom Zanussi * adf_init_misc_wq() - Init misc workqueue
359a4b16dadSTom Zanussi *
360a4b16dadSTom Zanussi * Function init workqueue 'qat_misc_wq' for general purpose.
361a4b16dadSTom Zanussi *
362a4b16dadSTom Zanussi * Return: 0 on success, error code otherwise.
363a4b16dadSTom Zanussi */
adf_init_misc_wq(void)364a4b16dadSTom Zanussi int __init adf_init_misc_wq(void)
365a4b16dadSTom Zanussi {
366a4b16dadSTom Zanussi adf_misc_wq = alloc_workqueue("qat_misc_wq", WQ_MEM_RECLAIM, 0);
367a4b16dadSTom Zanussi
368a4b16dadSTom Zanussi return !adf_misc_wq ? -ENOMEM : 0;
369a4b16dadSTom Zanussi }
370a4b16dadSTom Zanussi
adf_exit_misc_wq(void)371a4b16dadSTom Zanussi void adf_exit_misc_wq(void)
372a4b16dadSTom Zanussi {
373a4b16dadSTom Zanussi if (adf_misc_wq)
374a4b16dadSTom Zanussi destroy_workqueue(adf_misc_wq);
375a4b16dadSTom Zanussi
376a4b16dadSTom Zanussi adf_misc_wq = NULL;
377a4b16dadSTom Zanussi }
378a4b16dadSTom Zanussi
adf_misc_wq_queue_work(struct work_struct * work)379a4b16dadSTom Zanussi bool adf_misc_wq_queue_work(struct work_struct *work)
380a4b16dadSTom Zanussi {
381a4b16dadSTom Zanussi return queue_work(adf_misc_wq, work);
382a4b16dadSTom Zanussi }
383*fd77d8daSDamian Muszynski
adf_misc_wq_queue_delayed_work(struct delayed_work * work,unsigned long delay)384*fd77d8daSDamian Muszynski bool adf_misc_wq_queue_delayed_work(struct delayed_work *work,
385*fd77d8daSDamian Muszynski unsigned long delay)
386*fd77d8daSDamian Muszynski {
387*fd77d8daSDamian Muszynski return queue_delayed_work(adf_misc_wq, work, delay);
388*fd77d8daSDamian Muszynski }
389