aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSiva Yerramreddy <yshivakrishna@gmail.com>2014-07-11 17:04:22 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-11 21:29:55 -0400
commitb8e439f48a19e5832c08b4656a3a8ebb1f4b05f8 (patch)
treeb1a3bb58c995bdf7caa5c00509683fa89e3327a0
parent726526c3552c5718d5aba11ac2e914b0081a5c88 (diff)
misc: mic: add threaded irq support in host driver
Convert mic_request_irq to mic_request_threaded_irq to support threaded irq for virtual devices on mic bus. Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Reviewed-by: Nikhil Rao <nikhil.rao@intel.com> Reviewed-by: Sudeep Dutt <sudeep.dutt@intel.com> Signed-off-by: Siva Yerramreddy <yshivakrishna@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/misc/mic/host/mic_intr.c121
-rw-r--r--drivers/misc/mic/host/mic_intr.h24
-rw-r--r--drivers/misc/mic/host/mic_main.c5
-rw-r--r--drivers/misc/mic/host/mic_virtio.c6
4 files changed, 96 insertions, 60 deletions
diff --git a/drivers/misc/mic/host/mic_intr.c b/drivers/misc/mic/host/mic_intr.c
index dbc5afde1392..d686f2846ac7 100644
--- a/drivers/misc/mic/host/mic_intr.c
+++ b/drivers/misc/mic/host/mic_intr.c
@@ -24,28 +24,29 @@
24#include "../common/mic_dev.h" 24#include "../common/mic_dev.h"
25#include "mic_device.h" 25#include "mic_device.h"
26 26
27/* 27static irqreturn_t mic_thread_fn(int irq, void *dev)
28 * mic_invoke_callback - Invoke callback functions registered for
29 * the corresponding source id.
30 *
31 * @mdev: pointer to the mic_device instance
32 * @idx: The interrupt source id.
33 *
34 * Returns none.
35 */
36static inline void mic_invoke_callback(struct mic_device *mdev, int idx)
37{ 28{
29 struct mic_device *mdev = dev;
30 struct mic_intr_info *intr_info = mdev->intr_info;
31 struct mic_irq_info *irq_info = &mdev->irq_info;
38 struct mic_intr_cb *intr_cb; 32 struct mic_intr_cb *intr_cb;
39 struct pci_dev *pdev = container_of(mdev->sdev->parent, 33 struct pci_dev *pdev = container_of(mdev->sdev->parent,
40 struct pci_dev, dev); 34 struct pci_dev, dev);
35 int i;
41 36
42 spin_lock(&mdev->irq_info.mic_intr_lock); 37 spin_lock(&irq_info->mic_thread_lock);
43 list_for_each_entry(intr_cb, &mdev->irq_info.cb_list[idx], list) 38 for (i = intr_info->intr_start_idx[MIC_INTR_DB];
44 if (intr_cb->func) 39 i < intr_info->intr_len[MIC_INTR_DB]; i++)
45 intr_cb->func(pdev->irq, intr_cb->data); 40 if (test_and_clear_bit(i, &irq_info->mask)) {
46 spin_unlock(&mdev->irq_info.mic_intr_lock); 41 list_for_each_entry(intr_cb, &irq_info->cb_list[i],
42 list)
43 if (intr_cb->thread_fn)
44 intr_cb->thread_fn(pdev->irq,
45 intr_cb->data);
46 }
47 spin_unlock(&irq_info->mic_thread_lock);
48 return IRQ_HANDLED;
47} 49}
48
49/** 50/**
50 * mic_interrupt - Generic interrupt handler for 51 * mic_interrupt - Generic interrupt handler for
51 * MSI and INTx based interrupts. 52 * MSI and INTx based interrupts.
@@ -53,7 +54,11 @@ static inline void mic_invoke_callback(struct mic_device *mdev, int idx)
53static irqreturn_t mic_interrupt(int irq, void *dev) 54static irqreturn_t mic_interrupt(int irq, void *dev)
54{ 55{
55 struct mic_device *mdev = dev; 56 struct mic_device *mdev = dev;
56 struct mic_intr_info *info = mdev->intr_info; 57 struct mic_intr_info *intr_info = mdev->intr_info;
58 struct mic_irq_info *irq_info = &mdev->irq_info;
59 struct mic_intr_cb *intr_cb;
60 struct pci_dev *pdev = container_of(mdev->sdev->parent,
61 struct pci_dev, dev);
57 u32 mask; 62 u32 mask;
58 int i; 63 int i;
59 64
@@ -61,12 +66,19 @@ static irqreturn_t mic_interrupt(int irq, void *dev)
61 if (!mask) 66 if (!mask)
62 return IRQ_NONE; 67 return IRQ_NONE;
63 68
64 for (i = info->intr_start_idx[MIC_INTR_DB]; 69 spin_lock(&irq_info->mic_intr_lock);
65 i < info->intr_len[MIC_INTR_DB]; i++) 70 for (i = intr_info->intr_start_idx[MIC_INTR_DB];
66 if (mask & BIT(i)) 71 i < intr_info->intr_len[MIC_INTR_DB]; i++)
67 mic_invoke_callback(mdev, i); 72 if (mask & BIT(i)) {
68 73 list_for_each_entry(intr_cb, &irq_info->cb_list[i],
69 return IRQ_HANDLED; 74 list)
75 if (intr_cb->handler)
76 intr_cb->handler(pdev->irq,
77 intr_cb->data);
78 set_bit(i, &irq_info->mask);
79 }
80 spin_unlock(&irq_info->mic_intr_lock);
81 return IRQ_WAKE_THREAD;
70} 82}
71 83
72/* Return the interrupt offset from the index. Index is 0 based. */ 84/* Return the interrupt offset from the index. Index is 0 based. */
@@ -99,14 +111,15 @@ static struct msix_entry *mic_get_available_vector(struct mic_device *mdev)
99 * 111 *
100 * @mdev: pointer to the mic_device instance 112 * @mdev: pointer to the mic_device instance
101 * @idx: The source id to be registered. 113 * @idx: The source id to be registered.
102 * @func: The function to be called when the source id receives 114 * @handler: The function to be called when the source id receives
103 * the interrupt. 115 * the interrupt.
116 * @thread_fn: thread fn. corresponding to the handler
104 * @data: Private data of the requester. 117 * @data: Private data of the requester.
105 * Return the callback structure that was registered or an 118 * Return the callback structure that was registered or an
106 * appropriate error on failure. 119 * appropriate error on failure.
107 */ 120 */
108static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev, 121static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
109 u8 idx, irqreturn_t (*func) (int irq, void *dev), 122 u8 idx, irq_handler_t handler, irq_handler_t thread_fn,
110 void *data) 123 void *data)
111{ 124{
112 struct mic_intr_cb *intr_cb; 125 struct mic_intr_cb *intr_cb;
@@ -117,7 +130,8 @@ static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
117 if (!intr_cb) 130 if (!intr_cb)
118 return ERR_PTR(-ENOMEM); 131 return ERR_PTR(-ENOMEM);
119 132
120 intr_cb->func = func; 133 intr_cb->handler = handler;
134 intr_cb->thread_fn = thread_fn;
121 intr_cb->data = data; 135 intr_cb->data = data;
122 intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida, 136 intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida,
123 0, 0, GFP_KERNEL); 137 0, 0, GFP_KERNEL);
@@ -126,9 +140,11 @@ static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
126 goto ida_fail; 140 goto ida_fail;
127 } 141 }
128 142
143 spin_lock(&mdev->irq_info.mic_thread_lock);
129 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags); 144 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
130 list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]); 145 list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]);
131 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags); 146 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
147 spin_unlock(&mdev->irq_info.mic_thread_lock);
132 148
133 return intr_cb; 149 return intr_cb;
134ida_fail: 150ida_fail:
@@ -152,8 +168,9 @@ static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
152 unsigned long flags; 168 unsigned long flags;
153 int i; 169 int i;
154 170
171 spin_lock(&mdev->irq_info.mic_thread_lock);
172 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
155 for (i = 0; i < MIC_NUM_OFFSETS; i++) { 173 for (i = 0; i < MIC_NUM_OFFSETS; i++) {
156 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
157 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) { 174 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
158 intr_cb = list_entry(pos, struct mic_intr_cb, list); 175 intr_cb = list_entry(pos, struct mic_intr_cb, list);
159 if (intr_cb->cb_id == idx) { 176 if (intr_cb->cb_id == idx) {
@@ -163,11 +180,13 @@ static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
163 kfree(intr_cb); 180 kfree(intr_cb);
164 spin_unlock_irqrestore( 181 spin_unlock_irqrestore(
165 &mdev->irq_info.mic_intr_lock, flags); 182 &mdev->irq_info.mic_intr_lock, flags);
183 spin_unlock(&mdev->irq_info.mic_thread_lock);
166 return i; 184 return i;
167 } 185 }
168 } 186 }
169 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
170 } 187 }
188 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
189 spin_unlock(&mdev->irq_info.mic_thread_lock);
171 return MIC_NUM_OFFSETS; 190 return MIC_NUM_OFFSETS;
172} 191}
173 192
@@ -242,6 +261,7 @@ static int mic_setup_callbacks(struct mic_device *mdev)
242 INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]); 261 INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]);
243 ida_init(&mdev->irq_info.cb_ida); 262 ida_init(&mdev->irq_info.cb_ida);
244 spin_lock_init(&mdev->irq_info.mic_intr_lock); 263 spin_lock_init(&mdev->irq_info.mic_intr_lock);
264 spin_lock_init(&mdev->irq_info.mic_thread_lock);
245 return 0; 265 return 0;
246} 266}
247 267
@@ -258,14 +278,12 @@ static void mic_release_callbacks(struct mic_device *mdev)
258 struct mic_intr_cb *intr_cb; 278 struct mic_intr_cb *intr_cb;
259 int i; 279 int i;
260 280
281 spin_lock(&mdev->irq_info.mic_thread_lock);
282 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
261 for (i = 0; i < MIC_NUM_OFFSETS; i++) { 283 for (i = 0; i < MIC_NUM_OFFSETS; i++) {
262 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
263 284
264 if (list_empty(&mdev->irq_info.cb_list[i])) { 285 if (list_empty(&mdev->irq_info.cb_list[i]))
265 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock,
266 flags);
267 break; 286 break;
268 }
269 287
270 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) { 288 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
271 intr_cb = list_entry(pos, struct mic_intr_cb, list); 289 intr_cb = list_entry(pos, struct mic_intr_cb, list);
@@ -274,8 +292,9 @@ static void mic_release_callbacks(struct mic_device *mdev)
274 intr_cb->cb_id); 292 intr_cb->cb_id);
275 kfree(intr_cb); 293 kfree(intr_cb);
276 } 294 }
277 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
278 } 295 }
296 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
297 spin_unlock(&mdev->irq_info.mic_thread_lock);
279 ida_destroy(&mdev->irq_info.cb_ida); 298 ida_destroy(&mdev->irq_info.cb_ida);
280 kfree(mdev->irq_info.cb_list); 299 kfree(mdev->irq_info.cb_list);
281} 300}
@@ -313,7 +332,8 @@ static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev)
313 goto err_nomem2; 332 goto err_nomem2;
314 } 333 }
315 334
316 rc = request_irq(pdev->irq, mic_interrupt, 0 , "mic-msi", mdev); 335 rc = request_threaded_irq(pdev->irq, mic_interrupt, mic_thread_fn,
336 0, "mic-msi", mdev);
317 if (rc) { 337 if (rc) {
318 dev_err(&pdev->dev, "Error allocating MSI interrupt\n"); 338 dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
319 goto err_irq_req_fail; 339 goto err_irq_req_fail;
@@ -353,8 +373,8 @@ static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev)
353 goto err_nomem; 373 goto err_nomem;
354 } 374 }
355 375
356 rc = request_irq(pdev->irq, mic_interrupt, 376 rc = request_threaded_irq(pdev->irq, mic_interrupt, mic_thread_fn,
357 IRQF_SHARED, "mic-intx", mdev); 377 IRQF_SHARED, "mic-intx", mdev);
358 if (rc) 378 if (rc)
359 goto err; 379 goto err;
360 380
@@ -391,13 +411,14 @@ int mic_next_db(struct mic_device *mdev)
391#define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT) 411#define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT)
392 412
393/** 413/**
394 * mic_request_irq - request an irq. mic_mutex needs 414 * mic_request_threaded_irq - request an irq. mic_mutex needs
395 * to be held before calling this function. 415 * to be held before calling this function.
396 * 416 *
397 * @mdev: pointer to mic_device instance 417 * @mdev: pointer to mic_device instance
398 * @func: The callback function that handles the interrupt. 418 * @handler: The callback function that handles the interrupt.
399 * The function needs to call ack_interrupts 419 * The function needs to call ack_interrupts
400 * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts. 420 * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts.
421 * @thread_fn: thread fn required by request_threaded_irq.
401 * @name: The ASCII name of the callee requesting the irq. 422 * @name: The ASCII name of the callee requesting the irq.
402 * @data: private data that is returned back when calling the 423 * @data: private data that is returned back when calling the
403 * function handler. 424 * function handler.
@@ -412,10 +433,11 @@ int mic_next_db(struct mic_device *mdev)
412 * error code. 433 * error code.
413 * 434 *
414 */ 435 */
415struct mic_irq *mic_request_irq(struct mic_device *mdev, 436struct mic_irq *
416 irqreturn_t (*func)(int irq, void *dev), 437mic_request_threaded_irq(struct mic_device *mdev,
417 const char *name, void *data, int intr_src, 438 irq_handler_t handler, irq_handler_t thread_fn,
418 enum mic_intr_type type) 439 const char *name, void *data, int intr_src,
440 enum mic_intr_type type)
419{ 441{
420 u16 offset; 442 u16 offset;
421 int rc = 0; 443 int rc = 0;
@@ -444,7 +466,8 @@ struct mic_irq *mic_request_irq(struct mic_device *mdev,
444 goto err; 466 goto err;
445 } 467 }
446 468
447 rc = request_irq(msix->vector, func, 0, name, data); 469 rc = request_threaded_irq(msix->vector, handler, thread_fn,
470 0, name, data);
448 if (rc) { 471 if (rc) {
449 dev_dbg(mdev->sdev->parent, 472 dev_dbg(mdev->sdev->parent,
450 "request irq failed rc = %d\n", rc); 473 "request irq failed rc = %d\n", rc);
@@ -458,8 +481,8 @@ struct mic_irq *mic_request_irq(struct mic_device *mdev,
458 dev_dbg(mdev->sdev->parent, "irq: %d assigned for src: %d\n", 481 dev_dbg(mdev->sdev->parent, "irq: %d assigned for src: %d\n",
459 msix->vector, intr_src); 482 msix->vector, intr_src);
460 } else { 483 } else {
461 intr_cb = mic_register_intr_callback(mdev, 484 intr_cb = mic_register_intr_callback(mdev, offset, handler,
462 offset, func, data); 485 thread_fn, data);
463 if (IS_ERR(intr_cb)) { 486 if (IS_ERR(intr_cb)) {
464 dev_err(mdev->sdev->parent, 487 dev_err(mdev->sdev->parent,
465 "No available callback entries for use\n"); 488 "No available callback entries for use\n");
@@ -487,9 +510,9 @@ err:
487 * needs to be held before calling this function. 510 * needs to be held before calling this function.
488 * 511 *
489 * @mdev: pointer to mic_device instance 512 * @mdev: pointer to mic_device instance
490 * @cookie: cookie obtained during a successful call to mic_request_irq 513 * @cookie: cookie obtained during a successful call to mic_request_threaded_irq
491 * @data: private data specified by the calling function during the 514 * @data: private data specified by the calling function during the
492 * mic_request_irq 515 * mic_request_threaded_irq
493 * 516 *
494 * returns: none. 517 * returns: none.
495 */ 518 */
diff --git a/drivers/misc/mic/host/mic_intr.h b/drivers/misc/mic/host/mic_intr.h
index 6091aa97e116..b1334dd9a0a1 100644
--- a/drivers/misc/mic/host/mic_intr.h
+++ b/drivers/misc/mic/host/mic_intr.h
@@ -21,6 +21,8 @@
21#ifndef _MIC_INTR_H_ 21#ifndef _MIC_INTR_H_
22#define _MIC_INTR_H_ 22#define _MIC_INTR_H_
23 23
24#include <linux/bitops.h>
25#include <linux/interrupt.h>
24/* 26/*
25 * The minimum number of msix vectors required for normal operation. 27 * The minimum number of msix vectors required for normal operation.
26 * 3 for virtio network, console and block devices. 28 * 3 for virtio network, console and block devices.
@@ -68,7 +70,11 @@ struct mic_intr_info {
68 * @num_vectors: The number of MSI/MSI-x vectors that have been allocated. 70 * @num_vectors: The number of MSI/MSI-x vectors that have been allocated.
69 * @cb_ida: callback ID allocator to track the callbacks registered. 71 * @cb_ida: callback ID allocator to track the callbacks registered.
70 * @mic_intr_lock: spinlock to protect the interrupt callback list. 72 * @mic_intr_lock: spinlock to protect the interrupt callback list.
73 * @mic_thread_lock: spinlock to protect the thread callback list.
74 * This lock is used to protect against thread_fn while
75 * mic_intr_lock is used to protect against interrupt handler.
71 * @cb_list: Array of callback lists one for each source. 76 * @cb_list: Array of callback lists one for each source.
77 * @mask: Mask used by the main thread fn to call the underlying thread fns.
72 */ 78 */
73struct mic_irq_info { 79struct mic_irq_info {
74 int next_avail_src; 80 int next_avail_src;
@@ -77,19 +83,23 @@ struct mic_irq_info {
77 u16 num_vectors; 83 u16 num_vectors;
78 struct ida cb_ida; 84 struct ida cb_ida;
79 spinlock_t mic_intr_lock; 85 spinlock_t mic_intr_lock;
86 spinlock_t mic_thread_lock;
80 struct list_head *cb_list; 87 struct list_head *cb_list;
88 unsigned long mask;
81}; 89};
82 90
83/** 91/**
84 * struct mic_intr_cb - Interrupt callback structure. 92 * struct mic_intr_cb - Interrupt callback structure.
85 * 93 *
86 * @func: The callback function 94 * @handler: The callback function
95 * @thread_fn: The thread_fn.
87 * @data: Private data of the requester. 96 * @data: Private data of the requester.
88 * @cb_id: The callback id. Identifies this callback. 97 * @cb_id: The callback id. Identifies this callback.
89 * @list: list head pointing to the next callback structure. 98 * @list: list head pointing to the next callback structure.
90 */ 99 */
91struct mic_intr_cb { 100struct mic_intr_cb {
92 irqreturn_t (*func) (int irq, void *data); 101 irq_handler_t handler;
102 irq_handler_t thread_fn;
93 void *data; 103 void *data;
94 int cb_id; 104 int cb_id;
95 struct list_head list; 105 struct list_head list;
@@ -124,11 +134,11 @@ struct mic_hw_intr_ops {
124}; 134};
125 135
126int mic_next_db(struct mic_device *mdev); 136int mic_next_db(struct mic_device *mdev);
127struct mic_irq *mic_request_irq(struct mic_device *mdev, 137struct mic_irq *
128 irqreturn_t (*func)(int irq, void *data), 138mic_request_threaded_irq(struct mic_device *mdev,
129 const char *name, void *data, int intr_src, 139 irq_handler_t handler, irq_handler_t thread_fn,
130 enum mic_intr_type type); 140 const char *name, void *data, int intr_src,
131 141 enum mic_intr_type type);
132void mic_free_irq(struct mic_device *mdev, 142void mic_free_irq(struct mic_device *mdev,
133 struct mic_irq *cookie, void *data); 143 struct mic_irq *cookie, void *data);
134int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev); 144int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c
index c04a021e20c7..fdc9c13430e7 100644
--- a/drivers/misc/mic/host/mic_main.c
+++ b/drivers/misc/mic/host/mic_main.c
@@ -389,8 +389,9 @@ static int mic_probe(struct pci_dev *pdev,
389 mutex_lock(&mdev->mic_mutex); 389 mutex_lock(&mdev->mic_mutex);
390 390
391 mdev->shutdown_db = mic_next_db(mdev); 391 mdev->shutdown_db = mic_next_db(mdev);
392 mdev->shutdown_cookie = mic_request_irq(mdev, mic_shutdown_db, 392 mdev->shutdown_cookie = mic_request_threaded_irq(mdev, mic_shutdown_db,
393 "shutdown-interrupt", mdev, mdev->shutdown_db, MIC_INTR_DB); 393 NULL, "shutdown-interrupt", mdev,
394 mdev->shutdown_db, MIC_INTR_DB);
394 if (IS_ERR(mdev->shutdown_cookie)) { 395 if (IS_ERR(mdev->shutdown_cookie)) {
395 rc = PTR_ERR(mdev->shutdown_cookie); 396 rc = PTR_ERR(mdev->shutdown_cookie);
396 mutex_unlock(&mdev->mic_mutex); 397 mutex_unlock(&mdev->mic_mutex);
diff --git a/drivers/misc/mic/host/mic_virtio.c b/drivers/misc/mic/host/mic_virtio.c
index 7e1ef0ebbb80..aba3e8324b82 100644
--- a/drivers/misc/mic/host/mic_virtio.c
+++ b/drivers/misc/mic/host/mic_virtio.c
@@ -594,8 +594,10 @@ int mic_virtio_add_device(struct mic_vdev *mvdev,
594 snprintf(irqname, sizeof(irqname), "mic%dvirtio%d", mdev->id, 594 snprintf(irqname, sizeof(irqname), "mic%dvirtio%d", mdev->id,
595 mvdev->virtio_id); 595 mvdev->virtio_id);
596 mvdev->virtio_db = mic_next_db(mdev); 596 mvdev->virtio_db = mic_next_db(mdev);
597 mvdev->virtio_cookie = mic_request_irq(mdev, mic_virtio_intr_handler, 597 mvdev->virtio_cookie = mic_request_threaded_irq(mdev,
598 irqname, mvdev, mvdev->virtio_db, MIC_INTR_DB); 598 mic_virtio_intr_handler,
599 NULL, irqname, mvdev,
600 mvdev->virtio_db, MIC_INTR_DB);
599 if (IS_ERR(mvdev->virtio_cookie)) { 601 if (IS_ERR(mvdev->virtio_cookie)) {
600 ret = PTR_ERR(mvdev->virtio_cookie); 602 ret = PTR_ERR(mvdev->virtio_cookie);
601 dev_dbg(mdev->sdev->parent, "request irq failed\n"); 603 dev_dbg(mdev->sdev->parent, "request irq failed\n");