]> Git Repo - linux.git/blob - drivers/misc/mic/host/mic_intr.c
crush: add chooseleaf_vary_r tunable
[linux.git] / drivers / misc / mic / host / mic_intr.c
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 #include <linux/pci.h>
22 #include <linux/interrupt.h>
23
24 #include "../common/mic_dev.h"
25 #include "mic_device.h"
26
27 /*
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  */
36 static inline void mic_invoke_callback(struct mic_device *mdev, int idx)
37 {
38         struct mic_intr_cb *intr_cb;
39         struct pci_dev *pdev = container_of(mdev->sdev->parent,
40                 struct pci_dev, dev);
41
42         spin_lock(&mdev->irq_info.mic_intr_lock);
43         list_for_each_entry(intr_cb, &mdev->irq_info.cb_list[idx], list)
44                 if (intr_cb->func)
45                         intr_cb->func(pdev->irq, intr_cb->data);
46         spin_unlock(&mdev->irq_info.mic_intr_lock);
47 }
48
49 /**
50  * mic_interrupt - Generic interrupt handler for
51  * MSI and INTx based interrupts.
52  */
53 static irqreturn_t mic_interrupt(int irq, void *dev)
54 {
55         struct mic_device *mdev = dev;
56         struct mic_intr_info *info = mdev->intr_info;
57         u32 mask;
58         int i;
59
60         mask = mdev->ops->ack_interrupt(mdev);
61         if (!mask)
62                 return IRQ_NONE;
63
64         for (i = info->intr_start_idx[MIC_INTR_DB];
65                         i < info->intr_len[MIC_INTR_DB]; i++)
66                 if (mask & BIT(i))
67                         mic_invoke_callback(mdev, i);
68
69         return IRQ_HANDLED;
70 }
71
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)
75 {
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;
80
81         return mdev->intr_info->intr_start_idx[type] + intr_src;
82 }
83
84 /* Return next available msix_entry. */
85 static struct msix_entry *mic_get_available_vector(struct mic_device *mdev)
86 {
87         int i;
88         struct mic_irq_info *info = &mdev->irq_info;
89
90         for (i = 0; i < info->num_vectors; i++)
91                 if (!info->mic_msi_map[i])
92                         return &info->msix_entries[i];
93         return NULL;
94 }
95
96 /**
97  * mic_register_intr_callback - Register a callback handler for the
98  * given source id.
99  *
100  * @mdev: pointer to the mic_device instance
101  * @idx: The source id to be registered.
102  * @func: The function to be called when the source id receives
103  * the interrupt.
104  * @data: Private data of the requester.
105  * Return the callback structure that was registered or an
106  * appropriate error on failure.
107  */
108 static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
109                         u8 idx, irqreturn_t (*func) (int irq, void *dev),
110                         void *data)
111 {
112         struct mic_intr_cb *intr_cb;
113         unsigned long flags;
114         int rc;
115         intr_cb = kmalloc(sizeof(*intr_cb), GFP_KERNEL);
116
117         if (!intr_cb)
118                 return ERR_PTR(-ENOMEM);
119
120         intr_cb->func = func;
121         intr_cb->data = data;
122         intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida,
123                 0, 0, GFP_KERNEL);
124         if (intr_cb->cb_id < 0) {
125                 rc = intr_cb->cb_id;
126                 goto ida_fail;
127         }
128
129         spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
130         list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]);
131         spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
132
133         return intr_cb;
134 ida_fail:
135         kfree(intr_cb);
136         return ERR_PTR(rc);
137 }
138
139 /**
140  * mic_unregister_intr_callback - Unregister the callback handler
141  * identified by its callback id.
142  *
143  * @mdev: pointer to the mic_device instance
144  * @idx: The callback structure id to be unregistered.
145  * Return the source id that was unregistered or MIC_NUM_OFFSETS if no
146  * such callback handler was found.
147  */
148 static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
149 {
150         struct list_head *pos, *tmp;
151         struct mic_intr_cb *intr_cb;
152         unsigned long flags;
153         int i;
154
155         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]) {
158                         intr_cb = list_entry(pos, struct mic_intr_cb, list);
159                         if (intr_cb->cb_id == idx) {
160                                 list_del(pos);
161                                 ida_simple_remove(&mdev->irq_info.cb_ida,
162                                                   intr_cb->cb_id);
163                                 kfree(intr_cb);
164                                 spin_unlock_irqrestore(
165                                         &mdev->irq_info.mic_intr_lock, flags);
166                                 return i;
167                         }
168                 }
169                 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
170         }
171         return MIC_NUM_OFFSETS;
172 }
173
174 /**
175  * mic_setup_msix - Initializes MSIx interrupts.
176  *
177  * @mdev: pointer to mic_device instance
178  *
179  *
180  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
181  */
182 static int mic_setup_msix(struct mic_device *mdev, struct pci_dev *pdev)
183 {
184         int rc, i;
185         int entry_size = sizeof(*mdev->irq_info.msix_entries);
186
187         mdev->irq_info.msix_entries = kmalloc_array(MIC_MIN_MSIX,
188                                                     entry_size, GFP_KERNEL);
189         if (!mdev->irq_info.msix_entries) {
190                 rc = -ENOMEM;
191                 goto err_nomem1;
192         }
193
194         for (i = 0; i < MIC_MIN_MSIX; i++)
195                 mdev->irq_info.msix_entries[i].entry = i;
196
197         rc = pci_enable_msix(pdev, mdev->irq_info.msix_entries,
198                 MIC_MIN_MSIX);
199         if (rc) {
200                 dev_dbg(&pdev->dev, "Error enabling MSIx. rc = %d\n", rc);
201                 goto err_enable_msix;
202         }
203
204         mdev->irq_info.num_vectors = MIC_MIN_MSIX;
205         mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
206                 mdev->irq_info.num_vectors), GFP_KERNEL);
207
208         if (!mdev->irq_info.mic_msi_map) {
209                 rc = -ENOMEM;
210                 goto err_nomem2;
211         }
212
213         dev_dbg(mdev->sdev->parent,
214                 "%d MSIx irqs setup\n", mdev->irq_info.num_vectors);
215         return 0;
216 err_nomem2:
217         pci_disable_msix(pdev);
218 err_enable_msix:
219         kfree(mdev->irq_info.msix_entries);
220 err_nomem1:
221         mdev->irq_info.num_vectors = 0;
222         return rc;
223 }
224
225 /**
226  * mic_setup_callbacks - Initialize data structures needed
227  * to handle callbacks.
228  *
229  * @mdev: pointer to mic_device instance
230  */
231 static int mic_setup_callbacks(struct mic_device *mdev)
232 {
233         int i;
234
235         mdev->irq_info.cb_list = kmalloc_array(MIC_NUM_OFFSETS,
236                                                sizeof(*mdev->irq_info.cb_list),
237                                                GFP_KERNEL);
238         if (!mdev->irq_info.cb_list)
239                 return -ENOMEM;
240
241         for (i = 0; i < MIC_NUM_OFFSETS; i++)
242                 INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]);
243         ida_init(&mdev->irq_info.cb_ida);
244         spin_lock_init(&mdev->irq_info.mic_intr_lock);
245         return 0;
246 }
247
248 /**
249  * mic_release_callbacks - Uninitialize data structures needed
250  * to handle callbacks.
251  *
252  * @mdev: pointer to mic_device instance
253  */
254 static void mic_release_callbacks(struct mic_device *mdev)
255 {
256         unsigned long flags;
257         struct list_head *pos, *tmp;
258         struct mic_intr_cb *intr_cb;
259         int i;
260
261         for (i = 0; i < MIC_NUM_OFFSETS; i++) {
262                 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
263
264                 if (list_empty(&mdev->irq_info.cb_list[i])) {
265                         spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock,
266                                                flags);
267                         break;
268                 }
269
270                 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
271                         intr_cb = list_entry(pos, struct mic_intr_cb, list);
272                         list_del(pos);
273                         ida_simple_remove(&mdev->irq_info.cb_ida,
274                                           intr_cb->cb_id);
275                         kfree(intr_cb);
276                 }
277                 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
278         }
279         ida_destroy(&mdev->irq_info.cb_ida);
280         kfree(mdev->irq_info.cb_list);
281 }
282
283 /**
284  * mic_setup_msi - Initializes MSI interrupts.
285  *
286  * @mdev: pointer to mic_device instance
287  * @pdev: PCI device structure
288  *
289  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
290  */
291 static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev)
292 {
293         int rc;
294
295         rc = pci_enable_msi(pdev);
296         if (rc) {
297                 dev_dbg(&pdev->dev, "Error enabling MSI. rc = %d\n", rc);
298                 return rc;
299         }
300
301         mdev->irq_info.num_vectors = 1;
302         mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
303                 mdev->irq_info.num_vectors), GFP_KERNEL);
304
305         if (!mdev->irq_info.mic_msi_map) {
306                 rc = -ENOMEM;
307                 goto err_nomem1;
308         }
309
310         rc = mic_setup_callbacks(mdev);
311         if (rc) {
312                 dev_err(&pdev->dev, "Error setting up callbacks\n");
313                 goto err_nomem2;
314         }
315
316         rc = request_irq(pdev->irq, mic_interrupt, 0 , "mic-msi", mdev);
317         if (rc) {
318                 dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
319                 goto err_irq_req_fail;
320         }
321
322         dev_dbg(&pdev->dev, "%d MSI irqs setup\n", mdev->irq_info.num_vectors);
323         return 0;
324 err_irq_req_fail:
325         mic_release_callbacks(mdev);
326 err_nomem2:
327         kfree(mdev->irq_info.mic_msi_map);
328 err_nomem1:
329         pci_disable_msi(pdev);
330         mdev->irq_info.num_vectors = 0;
331         return rc;
332 }
333
334 /**
335  * mic_setup_intx - Initializes legacy interrupts.
336  *
337  * @mdev: pointer to mic_device instance
338  * @pdev: PCI device structure
339  *
340  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
341  */
342 static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev)
343 {
344         int rc;
345
346         pci_msi_off(pdev);
347
348         /* Enable intx */
349         pci_intx(pdev, 1);
350         rc = mic_setup_callbacks(mdev);
351         if (rc) {
352                 dev_err(&pdev->dev, "Error setting up callbacks\n");
353                 goto err_nomem;
354         }
355
356         rc = request_irq(pdev->irq, mic_interrupt,
357                 IRQF_SHARED, "mic-intx", mdev);
358         if (rc)
359                 goto err;
360
361         dev_dbg(&pdev->dev, "intx irq setup\n");
362         return 0;
363 err:
364         mic_release_callbacks(mdev);
365 err_nomem:
366         return rc;
367 }
368
369 /**
370  * mic_next_db - Retrieve the next doorbell interrupt source id.
371  * The id is picked sequentially from the available pool of
372  * doorlbell ids.
373  *
374  * @mdev: pointer to the mic_device instance.
375  *
376  * Returns the next doorbell interrupt source.
377  */
378 int mic_next_db(struct mic_device *mdev)
379 {
380         int next_db;
381
382         next_db = mdev->irq_info.next_avail_src %
383                 mdev->intr_info->intr_len[MIC_INTR_DB];
384         mdev->irq_info.next_avail_src++;
385         return next_db;
386 }
387
388 #define COOKIE_ID_SHIFT 16
389 #define GET_ENTRY(cookie) ((cookie) & 0xFFFF)
390 #define GET_OFFSET(cookie) ((cookie) >> COOKIE_ID_SHIFT)
391 #define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT)
392
393 /**
394  * mic_request_irq - request an irq. mic_mutex needs
395  * to be held before calling this function.
396  *
397  * @mdev: pointer to mic_device instance
398  * @func: The callback function that handles the interrupt.
399  * The function needs to call ack_interrupts
400  * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts.
401  * @name: The ASCII name of the callee requesting the irq.
402  * @data: private data that is returned back when calling the
403  * function handler.
404  * @intr_src: The source id of the requester. Its the doorbell id
405  * for Doorbell interrupts and DMA channel id for DMA interrupts.
406  * @type: The type of interrupt. Values defined in mic_intr_type
407  *
408  * returns: The cookie that is transparent to the caller. Passed
409  * back when calling mic_free_irq. An appropriate error code
410  * is returned on failure. Caller needs to use IS_ERR(return_val)
411  * to check for failure and PTR_ERR(return_val) to obtained the
412  * error code.
413  *
414  */
415 struct mic_irq *mic_request_irq(struct mic_device *mdev,
416         irqreturn_t (*func)(int irq, void *dev),
417         const char *name, void *data, int intr_src,
418         enum mic_intr_type type)
419 {
420         u16 offset;
421         int rc = 0;
422         struct msix_entry *msix = NULL;
423         unsigned long cookie = 0;
424         u16 entry;
425         struct mic_intr_cb *intr_cb;
426         struct pci_dev *pdev = container_of(mdev->sdev->parent,
427                 struct pci_dev, dev);
428
429         offset = mic_map_src_to_offset(mdev, intr_src, type);
430         if (offset >= MIC_NUM_OFFSETS) {
431                 dev_err(mdev->sdev->parent,
432                         "Error mapping index %d to a valid source id.\n",
433                         intr_src);
434                 rc = -EINVAL;
435                 goto err;
436         }
437
438         if (mdev->irq_info.num_vectors > 1) {
439                 msix = mic_get_available_vector(mdev);
440                 if (!msix) {
441                         dev_err(mdev->sdev->parent,
442                                 "No MSIx vectors available for use.\n");
443                         rc = -ENOSPC;
444                         goto err;
445                 }
446
447                 rc = request_irq(msix->vector, func, 0, name, data);
448                 if (rc) {
449                         dev_dbg(mdev->sdev->parent,
450                                 "request irq failed rc = %d\n", rc);
451                         goto err;
452                 }
453                 entry = msix->entry;
454                 mdev->irq_info.mic_msi_map[entry] |= BIT(offset);
455                 mdev->intr_ops->program_msi_to_src_map(mdev,
456                                 entry, offset, true);
457                 cookie = MK_COOKIE(entry, offset);
458                 dev_dbg(mdev->sdev->parent, "irq: %d assigned for src: %d\n",
459                         msix->vector, intr_src);
460         } else {
461                 intr_cb = mic_register_intr_callback(mdev,
462                                 offset, func, data);
463                 if (IS_ERR(intr_cb)) {
464                         dev_err(mdev->sdev->parent,
465                                 "No available callback entries for use\n");
466                         rc = PTR_ERR(intr_cb);
467                         goto err;
468                 }
469
470                 entry = 0;
471                 if (pci_dev_msi_enabled(pdev)) {
472                         mdev->irq_info.mic_msi_map[entry] |= (1 << offset);
473                         mdev->intr_ops->program_msi_to_src_map(mdev,
474                                 entry, offset, true);
475                 }
476                 cookie = MK_COOKIE(entry, intr_cb->cb_id);
477                 dev_dbg(mdev->sdev->parent, "callback %d registered for src: %d\n",
478                         intr_cb->cb_id, intr_src);
479         }
480         return (struct mic_irq *)cookie;
481 err:
482         return ERR_PTR(rc);
483 }
484
485 /**
486  * mic_free_irq - free irq. mic_mutex
487  *  needs to be held before calling this function.
488  *
489  * @mdev: pointer to mic_device instance
490  * @cookie: cookie obtained during a successful call to mic_request_irq
491  * @data: private data specified by the calling function during the
492  * mic_request_irq
493  *
494  * returns: none.
495  */
496 void mic_free_irq(struct mic_device *mdev,
497         struct mic_irq *cookie, void *data)
498 {
499         u32 offset;
500         u32 entry;
501         u8 src_id;
502         unsigned int irq;
503         struct pci_dev *pdev = container_of(mdev->sdev->parent,
504                 struct pci_dev, dev);
505
506         entry = GET_ENTRY((unsigned long)cookie);
507         offset = GET_OFFSET((unsigned long)cookie);
508         if (mdev->irq_info.num_vectors > 1) {
509                 if (entry >= mdev->irq_info.num_vectors) {
510                         dev_warn(mdev->sdev->parent,
511                                  "entry %d should be < num_irq %d\n",
512                                 entry, mdev->irq_info.num_vectors);
513                         return;
514                 }
515                 irq = mdev->irq_info.msix_entries[entry].vector;
516                 free_irq(irq, data);
517                 mdev->irq_info.mic_msi_map[entry] &= ~(BIT(offset));
518                 mdev->intr_ops->program_msi_to_src_map(mdev,
519                         entry, offset, false);
520
521                 dev_dbg(mdev->sdev->parent, "irq: %d freed\n", irq);
522         } else {
523                 irq = pdev->irq;
524                 src_id = mic_unregister_intr_callback(mdev, offset);
525                 if (src_id >= MIC_NUM_OFFSETS) {
526                         dev_warn(mdev->sdev->parent, "Error unregistering callback\n");
527                         return;
528                 }
529                 if (pci_dev_msi_enabled(pdev)) {
530                         mdev->irq_info.mic_msi_map[entry] &= ~(BIT(src_id));
531                         mdev->intr_ops->program_msi_to_src_map(mdev,
532                                 entry, src_id, false);
533                 }
534                 dev_dbg(mdev->sdev->parent, "callback %d unregistered for src: %d\n",
535                         offset, src_id);
536         }
537 }
538
539 /**
540  * mic_setup_interrupts - Initializes interrupts.
541  *
542  * @mdev: pointer to mic_device instance
543  * @pdev: PCI device structure
544  *
545  * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
546  */
547 int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
548 {
549         int rc;
550
551         rc = mic_setup_msix(mdev, pdev);
552         if (!rc)
553                 goto done;
554
555         rc = mic_setup_msi(mdev, pdev);
556         if (!rc)
557                 goto done;
558
559         rc = mic_setup_intx(mdev, pdev);
560         if (rc) {
561                 dev_err(mdev->sdev->parent, "no usable interrupts\n");
562                 return rc;
563         }
564 done:
565         mdev->intr_ops->enable_interrupts(mdev);
566         return 0;
567 }
568
569 /**
570  * mic_free_interrupts - Frees interrupts setup by mic_setup_interrupts
571  *
572  * @mdev: pointer to mic_device instance
573  * @pdev: PCI device structure
574  *
575  * returns none.
576  */
577 void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
578 {
579         int i;
580
581         mdev->intr_ops->disable_interrupts(mdev);
582         if (mdev->irq_info.num_vectors > 1) {
583                 for (i = 0; i < mdev->irq_info.num_vectors; i++) {
584                         if (mdev->irq_info.mic_msi_map[i])
585                                 dev_warn(&pdev->dev, "irq %d may still be in use.\n",
586                                          mdev->irq_info.msix_entries[i].vector);
587                 }
588                 kfree(mdev->irq_info.mic_msi_map);
589                 kfree(mdev->irq_info.msix_entries);
590                 pci_disable_msix(pdev);
591         } else {
592                 if (pci_dev_msi_enabled(pdev)) {
593                         free_irq(pdev->irq, mdev);
594                         kfree(mdev->irq_info.mic_msi_map);
595                         pci_disable_msi(pdev);
596                 } else {
597                         free_irq(pdev->irq, mdev);
598                 }
599                 mic_release_callbacks(mdev);
600         }
601 }
602
603 /**
604  * mic_intr_restore - Restore MIC interrupt registers.
605  *
606  * @mdev: pointer to mic_device instance.
607  *
608  * Restore the interrupt registers to values previously
609  * stored in the SW data structures. mic_mutex needs to
610  * be held before calling this function.
611  *
612  * returns None.
613  */
614 void mic_intr_restore(struct mic_device *mdev)
615 {
616         int entry, offset;
617         struct pci_dev *pdev = container_of(mdev->sdev->parent,
618                 struct pci_dev, dev);
619
620         if (!pci_dev_msi_enabled(pdev))
621                 return;
622
623         for (entry = 0; entry < mdev->irq_info.num_vectors; entry++) {
624                 for (offset = 0; offset < MIC_NUM_OFFSETS; offset++) {
625                         if (mdev->irq_info.mic_msi_map[entry] & BIT(offset))
626                                 mdev->intr_ops->program_msi_to_src_map(mdev,
627                                         entry, offset, true);
628                 }
629         }
630 }
This page took 0.070998 seconds and 4 git commands to generate.