1 // SPDX-License-Identifier: GPL-2.0-only
3 * Intel MIC Platform Software Stack (MPSS)
5 * Copyright(c) 2013 Intel Corporation.
7 * Intel MIC Host driver.
10 #include <linux/interrupt.h>
12 #include "../common/mic_dev.h"
13 #include "mic_device.h"
15 static irqreturn_t mic_thread_fn(int irq, void *dev)
17 struct mic_device *mdev = dev;
18 struct mic_intr_info *intr_info = mdev->intr_info;
19 struct mic_irq_info *irq_info = &mdev->irq_info;
20 struct mic_intr_cb *intr_cb;
21 struct pci_dev *pdev = mdev->pdev;
24 spin_lock(&irq_info->mic_thread_lock);
25 for (i = intr_info->intr_start_idx[MIC_INTR_DB];
26 i < intr_info->intr_len[MIC_INTR_DB]; i++)
27 if (test_and_clear_bit(i, &irq_info->mask)) {
28 list_for_each_entry(intr_cb, &irq_info->cb_list[i],
30 if (intr_cb->thread_fn)
31 intr_cb->thread_fn(pdev->irq,
34 spin_unlock(&irq_info->mic_thread_lock);
38 * mic_interrupt - Generic interrupt handler for
39 * MSI and INTx based interrupts.
40 * @irq: interrupt to handle (unused)
41 * @dev: pointer to the mic_device instance
43 static irqreturn_t mic_interrupt(int irq, void *dev)
45 struct mic_device *mdev = dev;
46 struct mic_intr_info *intr_info = mdev->intr_info;
47 struct mic_irq_info *irq_info = &mdev->irq_info;
48 struct mic_intr_cb *intr_cb;
49 struct pci_dev *pdev = mdev->pdev;
53 mask = mdev->ops->ack_interrupt(mdev);
57 spin_lock(&irq_info->mic_intr_lock);
58 for (i = intr_info->intr_start_idx[MIC_INTR_DB];
59 i < intr_info->intr_len[MIC_INTR_DB]; i++)
61 list_for_each_entry(intr_cb, &irq_info->cb_list[i],
64 intr_cb->handler(pdev->irq,
66 set_bit(i, &irq_info->mask);
68 spin_unlock(&irq_info->mic_intr_lock);
69 return IRQ_WAKE_THREAD;
72 /* Return the interrupt offset from the index. Index is 0 based. */
73 static u16 mic_map_src_to_offset(struct mic_device *mdev,
74 int intr_src, enum mic_intr_type type)
76 if (type >= MIC_NUM_INTR_TYPES)
77 return MIC_NUM_OFFSETS;
78 if (intr_src >= mdev->intr_info->intr_len[type])
79 return MIC_NUM_OFFSETS;
81 return mdev->intr_info->intr_start_idx[type] + intr_src;
84 /* Return next available msix_entry. */
85 static struct msix_entry *mic_get_available_vector(struct mic_device *mdev)
88 struct mic_irq_info *info = &mdev->irq_info;
90 for (i = 0; i < info->num_vectors; i++)
91 if (!info->mic_msi_map[i])
92 return &info->msix_entries[i];
97 * mic_register_intr_callback - Register a callback handler for the
100 * @mdev: pointer to the mic_device instance
101 * @idx: The source id to be registered.
102 * @handler: The function to be called when the source id receives
104 * @thread_fn: thread fn. corresponding to the handler
105 * @data: Private data of the requester.
106 * Return the callback structure that was registered or an
107 * appropriate error on failure.
109 static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
110 u8 idx, irq_handler_t handler, irq_handler_t thread_fn,
113 struct mic_intr_cb *intr_cb;
116 intr_cb = kmalloc(sizeof(*intr_cb), GFP_KERNEL);
119 return ERR_PTR(-ENOMEM);
121 intr_cb->handler = handler;
122 intr_cb->thread_fn = thread_fn;
123 intr_cb->data = data;
124 intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida,
126 if (intr_cb->cb_id < 0) {
131 spin_lock(&mdev->irq_info.mic_thread_lock);
132 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
133 list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]);
134 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
135 spin_unlock(&mdev->irq_info.mic_thread_lock);
144 * mic_unregister_intr_callback - Unregister the callback handler
145 * identified by its callback id.
147 * @mdev: pointer to the mic_device instance
148 * @idx: The callback structure id to be unregistered.
149 * Return the source id that was unregistered or MIC_NUM_OFFSETS if no
150 * such callback handler was found.
152 static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
154 struct list_head *pos, *tmp;
155 struct mic_intr_cb *intr_cb;
159 spin_lock(&mdev->irq_info.mic_thread_lock);
160 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
161 for (i = 0; i < MIC_NUM_OFFSETS; i++) {
162 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
163 intr_cb = list_entry(pos, struct mic_intr_cb, list);
164 if (intr_cb->cb_id == idx) {
166 ida_simple_remove(&mdev->irq_info.cb_ida,
169 spin_unlock_irqrestore(
170 &mdev->irq_info.mic_intr_lock, flags);
171 spin_unlock(&mdev->irq_info.mic_thread_lock);
176 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
177 spin_unlock(&mdev->irq_info.mic_thread_lock);
178 return MIC_NUM_OFFSETS;
182 * mic_setup_msix - Initializes MSIx interrupts.
184 * @mdev: pointer to mic_device instance
185 * @pdev: PCI device structure
187 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
189 static int mic_setup_msix(struct mic_device *mdev, struct pci_dev *pdev)
192 int entry_size = sizeof(*mdev->irq_info.msix_entries);
194 mdev->irq_info.msix_entries = kmalloc_array(MIC_MIN_MSIX,
195 entry_size, GFP_KERNEL);
196 if (!mdev->irq_info.msix_entries) {
201 for (i = 0; i < MIC_MIN_MSIX; i++)
202 mdev->irq_info.msix_entries[i].entry = i;
204 rc = pci_enable_msix_exact(pdev, mdev->irq_info.msix_entries,
207 dev_dbg(&pdev->dev, "Error enabling MSIx. rc = %d\n", rc);
208 goto err_enable_msix;
211 mdev->irq_info.num_vectors = MIC_MIN_MSIX;
212 mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
213 mdev->irq_info.num_vectors), GFP_KERNEL);
215 if (!mdev->irq_info.mic_msi_map) {
220 dev_dbg(&mdev->pdev->dev,
221 "%d MSIx irqs setup\n", mdev->irq_info.num_vectors);
224 pci_disable_msix(pdev);
226 kfree(mdev->irq_info.msix_entries);
228 mdev->irq_info.num_vectors = 0;
233 * mic_setup_callbacks - Initialize data structures needed
234 * to handle callbacks.
236 * @mdev: pointer to mic_device instance
238 static int mic_setup_callbacks(struct mic_device *mdev)
242 mdev->irq_info.cb_list = kmalloc_array(MIC_NUM_OFFSETS,
243 sizeof(*mdev->irq_info.cb_list),
245 if (!mdev->irq_info.cb_list)
248 for (i = 0; i < MIC_NUM_OFFSETS; i++)
249 INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]);
250 ida_init(&mdev->irq_info.cb_ida);
251 spin_lock_init(&mdev->irq_info.mic_intr_lock);
252 spin_lock_init(&mdev->irq_info.mic_thread_lock);
257 * mic_release_callbacks - Uninitialize data structures needed
258 * to handle callbacks.
260 * @mdev: pointer to mic_device instance
262 static void mic_release_callbacks(struct mic_device *mdev)
265 struct list_head *pos, *tmp;
266 struct mic_intr_cb *intr_cb;
269 spin_lock(&mdev->irq_info.mic_thread_lock);
270 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
271 for (i = 0; i < MIC_NUM_OFFSETS; i++) {
272 if (list_empty(&mdev->irq_info.cb_list[i]))
275 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
276 intr_cb = list_entry(pos, struct mic_intr_cb, list);
278 ida_simple_remove(&mdev->irq_info.cb_ida,
283 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
284 spin_unlock(&mdev->irq_info.mic_thread_lock);
285 ida_destroy(&mdev->irq_info.cb_ida);
286 kfree(mdev->irq_info.cb_list);
290 * mic_setup_msi - Initializes MSI interrupts.
292 * @mdev: pointer to mic_device instance
293 * @pdev: PCI device structure
295 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
297 static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev)
301 rc = pci_enable_msi(pdev);
303 dev_dbg(&pdev->dev, "Error enabling MSI. rc = %d\n", rc);
307 mdev->irq_info.num_vectors = 1;
308 mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
309 mdev->irq_info.num_vectors), GFP_KERNEL);
311 if (!mdev->irq_info.mic_msi_map) {
316 rc = mic_setup_callbacks(mdev);
318 dev_err(&pdev->dev, "Error setting up callbacks\n");
322 rc = request_threaded_irq(pdev->irq, mic_interrupt, mic_thread_fn,
325 dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
326 goto err_irq_req_fail;
329 dev_dbg(&pdev->dev, "%d MSI irqs setup\n", mdev->irq_info.num_vectors);
332 mic_release_callbacks(mdev);
334 kfree(mdev->irq_info.mic_msi_map);
336 pci_disable_msi(pdev);
337 mdev->irq_info.num_vectors = 0;
342 * mic_setup_intx - Initializes legacy interrupts.
344 * @mdev: pointer to mic_device instance
345 * @pdev: PCI device structure
347 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
349 static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev)
355 rc = mic_setup_callbacks(mdev);
357 dev_err(&pdev->dev, "Error setting up callbacks\n");
361 rc = request_threaded_irq(pdev->irq, mic_interrupt, mic_thread_fn,
362 IRQF_SHARED, "mic-intx", mdev);
366 dev_dbg(&pdev->dev, "intx irq setup\n");
369 mic_release_callbacks(mdev);
375 * mic_next_db - Retrieve the next doorbell interrupt source id.
376 * The id is picked sequentially from the available pool of
379 * @mdev: pointer to the mic_device instance.
381 * Returns the next doorbell interrupt source.
383 int mic_next_db(struct mic_device *mdev)
387 next_db = mdev->irq_info.next_avail_src %
388 mdev->intr_info->intr_len[MIC_INTR_DB];
389 mdev->irq_info.next_avail_src++;
393 #define COOKIE_ID_SHIFT 16
394 #define GET_ENTRY(cookie) ((cookie) & 0xFFFF)
395 #define GET_OFFSET(cookie) ((cookie) >> COOKIE_ID_SHIFT)
396 #define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT)
399 * mic_request_threaded_irq - request an irq. mic_mutex needs
400 * to be held before calling this function.
402 * @mdev: pointer to mic_device instance
403 * @handler: The callback function that handles the interrupt.
404 * The function needs to call ack_interrupts
405 * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts.
406 * @thread_fn: thread fn required by request_threaded_irq.
407 * @name: The ASCII name of the callee requesting the irq.
408 * @data: private data that is returned back when calling the
410 * @intr_src: The source id of the requester. Its the doorbell id
411 * for Doorbell interrupts and DMA channel id for DMA interrupts.
412 * @type: The type of interrupt. Values defined in mic_intr_type
414 * returns: The cookie that is transparent to the caller. Passed
415 * back when calling mic_free_irq. An appropriate error code
416 * is returned on failure. Caller needs to use IS_ERR(return_val)
417 * to check for failure and PTR_ERR(return_val) to obtained the
422 mic_request_threaded_irq(struct mic_device *mdev,
423 irq_handler_t handler, irq_handler_t thread_fn,
424 const char *name, void *data, int intr_src,
425 enum mic_intr_type type)
429 struct msix_entry *msix = NULL;
430 unsigned long cookie = 0;
432 struct mic_intr_cb *intr_cb;
433 struct pci_dev *pdev = mdev->pdev;
435 offset = mic_map_src_to_offset(mdev, intr_src, type);
436 if (offset >= MIC_NUM_OFFSETS) {
437 dev_err(&mdev->pdev->dev,
438 "Error mapping index %d to a valid source id.\n",
444 if (mdev->irq_info.num_vectors > 1) {
445 msix = mic_get_available_vector(mdev);
447 dev_err(&mdev->pdev->dev,
448 "No MSIx vectors available for use.\n");
453 rc = request_threaded_irq(msix->vector, handler, thread_fn,
456 dev_dbg(&mdev->pdev->dev,
457 "request irq failed rc = %d\n", rc);
461 mdev->irq_info.mic_msi_map[entry] |= BIT(offset);
462 mdev->intr_ops->program_msi_to_src_map(mdev,
463 entry, offset, true);
464 cookie = MK_COOKIE(entry, offset);
465 dev_dbg(&mdev->pdev->dev, "irq: %d assigned for src: %d\n",
466 msix->vector, intr_src);
468 intr_cb = mic_register_intr_callback(mdev, offset, handler,
470 if (IS_ERR(intr_cb)) {
471 dev_err(&mdev->pdev->dev,
472 "No available callback entries for use\n");
473 rc = PTR_ERR(intr_cb);
478 if (pci_dev_msi_enabled(pdev)) {
479 mdev->irq_info.mic_msi_map[entry] |= (1 << offset);
480 mdev->intr_ops->program_msi_to_src_map(mdev,
481 entry, offset, true);
483 cookie = MK_COOKIE(entry, intr_cb->cb_id);
484 dev_dbg(&mdev->pdev->dev, "callback %d registered for src: %d\n",
485 intr_cb->cb_id, intr_src);
487 return (struct mic_irq *)cookie;
493 * mic_free_irq - free irq. mic_mutex
494 * needs to be held before calling this function.
496 * @mdev: pointer to mic_device instance
497 * @cookie: cookie obtained during a successful call to mic_request_threaded_irq
498 * @data: private data specified by the calling function during the
499 * mic_request_threaded_irq
503 void mic_free_irq(struct mic_device *mdev,
504 struct mic_irq *cookie, void *data)
510 struct pci_dev *pdev = mdev->pdev;
512 entry = GET_ENTRY((unsigned long)cookie);
513 offset = GET_OFFSET((unsigned long)cookie);
514 if (mdev->irq_info.num_vectors > 1) {
515 if (entry >= mdev->irq_info.num_vectors) {
516 dev_warn(&mdev->pdev->dev,
517 "entry %d should be < num_irq %d\n",
518 entry, mdev->irq_info.num_vectors);
521 irq = mdev->irq_info.msix_entries[entry].vector;
523 mdev->irq_info.mic_msi_map[entry] &= ~(BIT(offset));
524 mdev->intr_ops->program_msi_to_src_map(mdev,
525 entry, offset, false);
527 dev_dbg(&mdev->pdev->dev, "irq: %d freed\n", irq);
530 src_id = mic_unregister_intr_callback(mdev, offset);
531 if (src_id >= MIC_NUM_OFFSETS) {
532 dev_warn(&mdev->pdev->dev, "Error unregistering callback\n");
535 if (pci_dev_msi_enabled(pdev)) {
536 mdev->irq_info.mic_msi_map[entry] &= ~(BIT(src_id));
537 mdev->intr_ops->program_msi_to_src_map(mdev,
538 entry, src_id, false);
540 dev_dbg(&mdev->pdev->dev, "callback %d unregistered for src: %d\n",
546 * mic_setup_interrupts - Initializes interrupts.
548 * @mdev: pointer to mic_device instance
549 * @pdev: PCI device structure
551 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
553 int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
557 rc = mic_setup_msix(mdev, pdev);
561 rc = mic_setup_msi(mdev, pdev);
565 rc = mic_setup_intx(mdev, pdev);
567 dev_err(&mdev->pdev->dev, "no usable interrupts\n");
571 mdev->intr_ops->enable_interrupts(mdev);
576 * mic_free_interrupts - Frees interrupts setup by mic_setup_interrupts
578 * @mdev: pointer to mic_device instance
579 * @pdev: PCI device structure
583 void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
587 mdev->intr_ops->disable_interrupts(mdev);
588 if (mdev->irq_info.num_vectors > 1) {
589 for (i = 0; i < mdev->irq_info.num_vectors; i++) {
590 if (mdev->irq_info.mic_msi_map[i])
591 dev_warn(&pdev->dev, "irq %d may still be in use.\n",
592 mdev->irq_info.msix_entries[i].vector);
594 kfree(mdev->irq_info.mic_msi_map);
595 kfree(mdev->irq_info.msix_entries);
596 pci_disable_msix(pdev);
598 if (pci_dev_msi_enabled(pdev)) {
599 free_irq(pdev->irq, mdev);
600 kfree(mdev->irq_info.mic_msi_map);
601 pci_disable_msi(pdev);
603 free_irq(pdev->irq, mdev);
605 mic_release_callbacks(mdev);
610 * mic_intr_restore - Restore MIC interrupt registers.
612 * @mdev: pointer to mic_device instance.
614 * Restore the interrupt registers to values previously
615 * stored in the SW data structures. mic_mutex needs to
616 * be held before calling this function.
620 void mic_intr_restore(struct mic_device *mdev)
623 struct pci_dev *pdev = mdev->pdev;
625 if (!pci_dev_msi_enabled(pdev))
628 for (entry = 0; entry < mdev->irq_info.num_vectors; entry++) {
629 for (offset = 0; offset < MIC_NUM_OFFSETS; offset++) {
630 if (mdev->irq_info.mic_msi_map[entry] & BIT(offset))
631 mdev->intr_ops->program_msi_to_src_map(mdev,
632 entry, offset, true);