aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/crypto/talitos.c207
-rw-r--r--drivers/crypto/talitos.h14
2 files changed, 149 insertions, 72 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 7f82e91e461c..92c0ca75400d 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -122,7 +122,7 @@ struct talitos_private {
122 struct device *dev; 122 struct device *dev;
123 struct platform_device *ofdev; 123 struct platform_device *ofdev;
124 void __iomem *reg; 124 void __iomem *reg;
125 int irq; 125 int irq[2];
126 126
127 /* SEC version geometry (from device tree node) */ 127 /* SEC version geometry (from device tree node) */
128 unsigned int num_channels; 128 unsigned int num_channels;
@@ -146,7 +146,7 @@ struct talitos_private {
146 atomic_t last_chan ____cacheline_aligned; 146 atomic_t last_chan ____cacheline_aligned;
147 147
148 /* request callback tasklet */ 148 /* request callback tasklet */
149 struct tasklet_struct done_task; 149 struct tasklet_struct done_task[2];
150 150
151 /* list of registered algorithms */ 151 /* list of registered algorithms */
152 struct list_head alg_list; 152 struct list_head alg_list;
@@ -226,13 +226,19 @@ static int reset_device(struct device *dev)
226{ 226{
227 struct talitos_private *priv = dev_get_drvdata(dev); 227 struct talitos_private *priv = dev_get_drvdata(dev);
228 unsigned int timeout = TALITOS_TIMEOUT; 228 unsigned int timeout = TALITOS_TIMEOUT;
229 u32 mcr = TALITOS_MCR_SWR;
229 230
230 setbits32(priv->reg + TALITOS_MCR, TALITOS_MCR_SWR); 231 setbits32(priv->reg + TALITOS_MCR, mcr);
231 232
232 while ((in_be32(priv->reg + TALITOS_MCR) & TALITOS_MCR_SWR) 233 while ((in_be32(priv->reg + TALITOS_MCR) & TALITOS_MCR_SWR)
233 && --timeout) 234 && --timeout)
234 cpu_relax(); 235 cpu_relax();
235 236
237 if (priv->irq[1] != NO_IRQ) {
238 mcr = TALITOS_MCR_RCA1 | TALITOS_MCR_RCA3;
239 setbits32(priv->reg + TALITOS_MCR, mcr);
240 }
241
236 if (timeout == 0) { 242 if (timeout == 0) {
237 dev_err(dev, "failed to reset device\n"); 243 dev_err(dev, "failed to reset device\n");
238 return -EIO; 244 return -EIO;
@@ -401,21 +407,32 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
401/* 407/*
402 * process completed requests for channels that have done status 408 * process completed requests for channels that have done status
403 */ 409 */
404static void talitos_done(unsigned long data) 410#define DEF_TALITOS_DONE(name, ch_done_mask) \
405{ 411static void talitos_done_##name(unsigned long data) \
406 struct device *dev = (struct device *)data; 412{ \
407 struct talitos_private *priv = dev_get_drvdata(dev); 413 struct device *dev = (struct device *)data; \
408 int ch; 414 struct talitos_private *priv = dev_get_drvdata(dev); \
409 415 \
410 for (ch = 0; ch < priv->num_channels; ch++) 416 if (ch_done_mask & 1) \
411 flush_channel(dev, ch, 0, 0); 417 flush_channel(dev, 0, 0, 0); \
412 418 if (priv->num_channels == 1) \
413 /* At this point, all completed channels have been processed. 419 goto out; \
414 * Unmask done interrupts for channels completed later on. 420 if (ch_done_mask & (1 << 2)) \
415 */ 421 flush_channel(dev, 1, 0, 0); \
416 setbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_INIT); 422 if (ch_done_mask & (1 << 4)) \
417 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); 423 flush_channel(dev, 2, 0, 0); \
418} 424 if (ch_done_mask & (1 << 6)) \
425 flush_channel(dev, 3, 0, 0); \
426 \
427out: \
428 /* At this point, all completed channels have been processed */ \
429 /* Unmask done interrupts for channels completed later on. */ \
430 setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
431 setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \
432}
433DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
434DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE)
435DEF_TALITOS_DONE(ch1_3, TALITOS_ISR_CH_1_3_DONE)
419 436
420/* 437/*
421 * locate current (offending) descriptor 438 * locate current (offending) descriptor
@@ -584,7 +601,7 @@ static void talitos_error(unsigned long data, u32 isr, u32 isr_lo)
584 } 601 }
585 } 602 }
586 } 603 }
587 if (reset_dev || isr & ~TALITOS_ISR_CHERR || isr_lo) { 604 if (reset_dev || isr & ~TALITOS_ISR_4CHERR || isr_lo) {
588 dev_err(dev, "done overflow, internal time out, or rngu error: " 605 dev_err(dev, "done overflow, internal time out, or rngu error: "
589 "ISR 0x%08x_%08x\n", isr, isr_lo); 606 "ISR 0x%08x_%08x\n", isr, isr_lo);
590 607
@@ -597,30 +614,35 @@ static void talitos_error(unsigned long data, u32 isr, u32 isr_lo)
597 } 614 }
598} 615}
599 616
600static irqreturn_t talitos_interrupt(int irq, void *data) 617#define DEF_TALITOS_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \
601{ 618static irqreturn_t talitos_interrupt_##name(int irq, void *data) \
602 struct device *dev = data; 619{ \
603 struct talitos_private *priv = dev_get_drvdata(dev); 620 struct device *dev = data; \
604 u32 isr, isr_lo; 621 struct talitos_private *priv = dev_get_drvdata(dev); \
605 622 u32 isr, isr_lo; \
606 isr = in_be32(priv->reg + TALITOS_ISR); 623 \
607 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); 624 isr = in_be32(priv->reg + TALITOS_ISR); \
608 /* Acknowledge interrupt */ 625 isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
609 out_be32(priv->reg + TALITOS_ICR, isr); 626 /* Acknowledge interrupt */ \
610 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); 627 out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
611 628 out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
612 if (unlikely((isr & ~TALITOS_ISR_CHDONE) || isr_lo)) 629 \
613 talitos_error((unsigned long)data, isr, isr_lo); 630 if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \
614 else 631 talitos_error((unsigned long)data, isr, isr_lo); \
615 if (likely(isr & TALITOS_ISR_CHDONE)) { 632 else \
616 /* mask further done interrupts. */ 633 if (likely(isr & ch_done_mask)) { \
617 clrbits32(priv->reg + TALITOS_IMR, TALITOS_IMR_DONE); 634 /* mask further done interrupts. */ \
618 /* done_task will unmask done interrupts at exit */ 635 clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
619 tasklet_schedule(&priv->done_task); 636 /* done_task will unmask done interrupts at exit */ \
620 } 637 tasklet_schedule(&priv->done_task[tlet]); \
621 638 } \
622 return (isr || isr_lo) ? IRQ_HANDLED : IRQ_NONE; 639 \
623} 640 return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
641 IRQ_NONE; \
642}
643DEF_TALITOS_INTERRUPT(4ch, TALITOS_ISR_4CHDONE, TALITOS_ISR_4CHERR, 0)
644DEF_TALITOS_INTERRUPT(ch0_2, TALITOS_ISR_CH_0_2_DONE, TALITOS_ISR_CH_0_2_ERR, 0)
645DEF_TALITOS_INTERRUPT(ch1_3, TALITOS_ISR_CH_1_3_DONE, TALITOS_ISR_CH_1_3_ERR, 1)
624 646
625/* 647/*
626 * hwrng 648 * hwrng
@@ -2558,12 +2580,15 @@ static int talitos_remove(struct platform_device *ofdev)
2558 2580
2559 kfree(priv->chan); 2581 kfree(priv->chan);
2560 2582
2561 if (priv->irq != NO_IRQ) { 2583 for (i = 0; i < 2; i++)
2562 free_irq(priv->irq, dev); 2584 if (priv->irq[i] != NO_IRQ) {
2563 irq_dispose_mapping(priv->irq); 2585 free_irq(priv->irq[i], dev);
2564 } 2586 irq_dispose_mapping(priv->irq[i]);
2587 }
2565 2588
2566 tasklet_kill(&priv->done_task); 2589 tasklet_kill(&priv->done_task[0]);
2590 if (priv->irq[1] != NO_IRQ)
2591 tasklet_kill(&priv->done_task[1]);
2567 2592
2568 iounmap(priv->reg); 2593 iounmap(priv->reg);
2569 2594
@@ -2628,6 +2653,54 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
2628 return t_alg; 2653 return t_alg;
2629} 2654}
2630 2655
2656static int talitos_probe_irq(struct platform_device *ofdev)
2657{
2658 struct device *dev = &ofdev->dev;
2659 struct device_node *np = ofdev->dev.of_node;
2660 struct talitos_private *priv = dev_get_drvdata(dev);
2661 int err;
2662
2663 priv->irq[0] = irq_of_parse_and_map(np, 0);
2664 if (priv->irq[0] == NO_IRQ) {
2665 dev_err(dev, "failed to map irq\n");
2666 return -EINVAL;
2667 }
2668
2669 priv->irq[1] = irq_of_parse_and_map(np, 1);
2670
2671 /* get the primary irq line */
2672 if (priv->irq[1] == NO_IRQ) {
2673 err = request_irq(priv->irq[0], talitos_interrupt_4ch, 0,
2674 dev_driver_string(dev), dev);
2675 goto primary_out;
2676 }
2677
2678 err = request_irq(priv->irq[0], talitos_interrupt_ch0_2, 0,
2679 dev_driver_string(dev), dev);
2680 if (err)
2681 goto primary_out;
2682
2683 /* get the secondary irq line */
2684 err = request_irq(priv->irq[1], talitos_interrupt_ch1_3, 0,
2685 dev_driver_string(dev), dev);
2686 if (err) {
2687 dev_err(dev, "failed to request secondary irq\n");
2688 irq_dispose_mapping(priv->irq[1]);
2689 priv->irq[1] = NO_IRQ;
2690 }
2691
2692 return err;
2693
2694primary_out:
2695 if (err) {
2696 dev_err(dev, "failed to request primary irq\n");
2697 irq_dispose_mapping(priv->irq[0]);
2698 priv->irq[0] = NO_IRQ;
2699 }
2700
2701 return err;
2702}
2703
2631static int talitos_probe(struct platform_device *ofdev) 2704static int talitos_probe(struct platform_device *ofdev)
2632{ 2705{
2633 struct device *dev = &ofdev->dev; 2706 struct device *dev = &ofdev->dev;
@@ -2644,28 +2717,22 @@ static int talitos_probe(struct platform_device *ofdev)
2644 2717
2645 priv->ofdev = ofdev; 2718 priv->ofdev = ofdev;
2646 2719
2647 tasklet_init(&priv->done_task, talitos_done, (unsigned long)dev); 2720 err = talitos_probe_irq(ofdev);
2648 2721 if (err)
2649 INIT_LIST_HEAD(&priv->alg_list);
2650
2651 priv->irq = irq_of_parse_and_map(np, 0);
2652
2653 if (priv->irq == NO_IRQ) {
2654 dev_err(dev, "failed to map irq\n");
2655 err = -EINVAL;
2656 goto err_out; 2722 goto err_out;
2657 }
2658 2723
2659 /* get the irq line */ 2724 if (priv->irq[1] == NO_IRQ) {
2660 err = request_irq(priv->irq, talitos_interrupt, 0, 2725 tasklet_init(&priv->done_task[0], talitos_done_4ch,
2661 dev_driver_string(dev), dev); 2726 (unsigned long)dev);
2662 if (err) { 2727 } else {
2663 dev_err(dev, "failed to request irq %d\n", priv->irq); 2728 tasklet_init(&priv->done_task[0], talitos_done_ch0_2,
2664 irq_dispose_mapping(priv->irq); 2729 (unsigned long)dev);
2665 priv->irq = NO_IRQ; 2730 tasklet_init(&priv->done_task[1], talitos_done_ch1_3,
2666 goto err_out; 2731 (unsigned long)dev);
2667 } 2732 }
2668 2733
2734 INIT_LIST_HEAD(&priv->alg_list);
2735
2669 priv->reg = of_iomap(np, 0); 2736 priv->reg = of_iomap(np, 0);
2670 if (!priv->reg) { 2737 if (!priv->reg) {
2671 dev_err(dev, "failed to of_iomap\n"); 2738 dev_err(dev, "failed to of_iomap\n");
@@ -2713,9 +2780,11 @@ static int talitos_probe(struct platform_device *ofdev)
2713 goto err_out; 2780 goto err_out;
2714 } 2781 }
2715 2782
2716 for (i = 0; i < priv->num_channels; i++) 2783 for (i = 0; i < priv->num_channels; i++) {
2717 priv->chan[i].reg = priv->reg + TALITOS_CH_BASE_OFFSET + 2784 priv->chan[i].reg = priv->reg + TALITOS_CH_STRIDE * (i + 1);
2718 TALITOS_CH_STRIDE * (i + 1); 2785 if ((priv->irq[1] == NO_IRQ) || !(i & 1))
2786 priv->chan[i].reg += TALITOS_CH_BASE_OFFSET;
2787 }
2719 2788
2720 for (i = 0; i < priv->num_channels; i++) { 2789 for (i = 0; i < priv->num_channels; i++) {
2721 spin_lock_init(&priv->chan[i].head_lock); 2790 spin_lock_init(&priv->chan[i].head_lock);
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index 3ed319da853c..3c173954ef29 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -34,16 +34,24 @@
34 34
35/* global register offset addresses */ 35/* global register offset addresses */
36#define TALITOS_MCR 0x1030 /* master control register */ 36#define TALITOS_MCR 0x1030 /* master control register */
37#define TALITOS_MCR_LO 0x1038 37#define TALITOS_MCR_RCA0 (1 << 15) /* remap channel 0 */
38#define TALITOS_MCR_RCA1 (1 << 14) /* remap channel 1 */
39#define TALITOS_MCR_RCA2 (1 << 13) /* remap channel 2 */
40#define TALITOS_MCR_RCA3 (1 << 12) /* remap channel 3 */
38#define TALITOS_MCR_SWR 0x1 /* s/w reset */ 41#define TALITOS_MCR_SWR 0x1 /* s/w reset */
42#define TALITOS_MCR_LO 0x1034
39#define TALITOS_IMR 0x1008 /* interrupt mask register */ 43#define TALITOS_IMR 0x1008 /* interrupt mask register */
40#define TALITOS_IMR_INIT 0x100ff /* enable channel IRQs */ 44#define TALITOS_IMR_INIT 0x100ff /* enable channel IRQs */
41#define TALITOS_IMR_DONE 0x00055 /* done IRQs */ 45#define TALITOS_IMR_DONE 0x00055 /* done IRQs */
42#define TALITOS_IMR_LO 0x100C 46#define TALITOS_IMR_LO 0x100C
43#define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */ 47#define TALITOS_IMR_LO_INIT 0x20000 /* allow RNGU error IRQs */
44#define TALITOS_ISR 0x1010 /* interrupt status register */ 48#define TALITOS_ISR 0x1010 /* interrupt status register */
45#define TALITOS_ISR_CHERR 0xaa /* channel errors mask */ 49#define TALITOS_ISR_4CHERR 0xaa /* 4 channel errors mask */
46#define TALITOS_ISR_CHDONE 0x55 /* channel done mask */ 50#define TALITOS_ISR_4CHDONE 0x55 /* 4 channel done mask */
51#define TALITOS_ISR_CH_0_2_ERR 0x22 /* channels 0, 2 errors mask */
52#define TALITOS_ISR_CH_0_2_DONE 0x11 /* channels 0, 2 done mask */
53#define TALITOS_ISR_CH_1_3_ERR 0x88 /* channels 1, 3 errors mask */
54#define TALITOS_ISR_CH_1_3_DONE 0x44 /* channels 1, 3 done mask */
47#define TALITOS_ISR_LO 0x1014 55#define TALITOS_ISR_LO 0x1014
48#define TALITOS_ICR 0x1018 /* interrupt clear register */ 56#define TALITOS_ICR 0x1018 /* interrupt clear register */
49#define TALITOS_ICR_LO 0x101C 57#define TALITOS_ICR_LO 0x101C