aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/hifn_795x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/crypto/hifn_795x.c')
-rw-r--r--drivers/crypto/hifn_795x.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 391c20a3dff8..7b7c85439c33 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -26,6 +26,7 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/highmem.h> 28#include <linux/highmem.h>
29#include <linux/interrupt.h>
29#include <linux/crypto.h> 30#include <linux/crypto.h>
30 31
31#include <crypto/algapi.h> 32#include <crypto/algapi.h>
@@ -426,6 +427,8 @@ struct hifn_device
426 427
427 u8 snum; 428 u8 snum;
428 429
430 struct tasklet_struct tasklet;
431
429 struct crypto_queue queue; 432 struct crypto_queue queue;
430 struct list_head alg_list; 433 struct list_head alg_list;
431}; 434};
@@ -1879,7 +1882,7 @@ static irqreturn_t hifn_interrupt(int irq, void *data)
1879 hifn_write_1(dev, HIFN_1_DMA_IER, dev->dmareg); 1882 hifn_write_1(dev, HIFN_1_DMA_IER, dev->dmareg);
1880 } 1883 }
1881 1884
1882 hifn_check_for_completion(dev, 0); 1885 tasklet_schedule(&dev->tasklet);
1883 hifn_clear_rings(dev); 1886 hifn_clear_rings(dev);
1884 1887
1885 return IRQ_HANDLED; 1888 return IRQ_HANDLED;
@@ -2408,6 +2411,19 @@ err_out_exit:
2408 return err; 2411 return err;
2409} 2412}
2410 2413
2414static void hifn_tasklet_callback(unsigned long data)
2415{
2416 struct hifn_device *dev = (struct hifn_device *)data;
2417
2418 /*
2419 * This is ok to call this without lock being held,
2420 * althogh it modifies some parameters used in parallel,
2421 * (like dev->success), but they are used in process
2422 * context or update is atomic (like setting dev->sa[i] to NULL).
2423 */
2424 hifn_check_for_completion(dev, 0);
2425}
2426
2411static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id) 2427static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2412{ 2428{
2413 int err, i; 2429 int err, i;
@@ -2489,6 +2505,8 @@ static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2489 2505
2490 pci_set_drvdata(pdev, dev); 2506 pci_set_drvdata(pdev, dev);
2491 2507
2508 tasklet_init(&dev->tasklet, hifn_tasklet_callback, (unsigned long)dev);
2509
2492 crypto_init_queue(&dev->queue, 1); 2510 crypto_init_queue(&dev->queue, 1);
2493 2511
2494 err = request_irq(dev->irq, hifn_interrupt, IRQF_SHARED, dev->name, dev); 2512 err = request_irq(dev->irq, hifn_interrupt, IRQF_SHARED, dev->name, dev);
@@ -2524,6 +2542,7 @@ err_out_stop_device:
2524 hifn_stop_device(dev); 2542 hifn_stop_device(dev);
2525err_out_free_irq: 2543err_out_free_irq:
2526 free_irq(dev->irq, dev->name); 2544 free_irq(dev->irq, dev->name);
2545 tasklet_kill(&dev->tasklet);
2527err_out_free_desc: 2546err_out_free_desc:
2528 pci_free_consistent(pdev, sizeof(struct hifn_dma), 2547 pci_free_consistent(pdev, sizeof(struct hifn_dma),
2529 dev->desc_virt, dev->desc_dma); 2548 dev->desc_virt, dev->desc_dma);
@@ -2563,6 +2582,7 @@ static void hifn_remove(struct pci_dev *pdev)
2563 hifn_stop_device(dev); 2582 hifn_stop_device(dev);
2564 2583
2565 free_irq(dev->irq, dev->name); 2584 free_irq(dev->irq, dev->name);
2585 tasklet_kill(&dev->tasklet);
2566 2586
2567 hifn_flush(dev); 2587 hifn_flush(dev);
2568 2588