lkml.org 
[lkml]   [2012]   [May]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 36/75] crypto: talitos - properly lock access to global talitos registers
    3.3-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Horia Geanta <horia.geanta@freescale.com>

    commit 511d63cb19329235bc9298b64010ec494b5e1408 upstream.

    Access to global talitos registers must be protected for the case when
    affinities are configured such that primary and secondary talitos irqs
    run on different cpus.

    Signed-off-by: Horia Geanta <horia.geanta@freescale.com>
    Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/crypto/talitos.c | 20 +++++++++++++++++---
    1 file changed, 17 insertions(+), 3 deletions(-)

    --- a/drivers/crypto/talitos.c
    +++ b/drivers/crypto/talitos.c
    @@ -124,6 +124,9 @@ struct talitos_private {
    void __iomem *reg;
    int irq[2];

    + /* SEC global registers lock */
    + spinlock_t reg_lock ____cacheline_aligned;
    +
    /* SEC version geometry (from device tree node) */
    unsigned int num_channels;
    unsigned int chfifo_len;
    @@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned
    { \
    struct device *dev = (struct device *)data; \
    struct talitos_private *priv = dev_get_drvdata(dev); \
    + unsigned long flags; \
    \
    if (ch_done_mask & 1) \
    flush_channel(dev, 0, 0, 0); \
    @@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned
    out: \
    /* At this point, all completed channels have been processed */ \
    /* Unmask done interrupts for channels completed later on. */ \
    + spin_lock_irqsave(&priv->reg_lock, flags); \
    setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
    setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \
    + spin_unlock_irqrestore(&priv->reg_lock, flags); \
    }
    DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
    DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE)
    @@ -619,22 +625,28 @@ static irqreturn_t talitos_interrupt_##n
    struct device *dev = data; \
    struct talitos_private *priv = dev_get_drvdata(dev); \
    u32 isr, isr_lo; \
    + unsigned long flags; \
    \
    + spin_lock_irqsave(&priv->reg_lock, flags); \
    isr = in_be32(priv->reg + TALITOS_ISR); \
    isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
    /* Acknowledge interrupt */ \
    out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
    out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
    \
    - if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \
    - talitos_error(dev, isr, isr_lo); \
    - else \
    + if (unlikely(isr & ch_err_mask || isr_lo)) { \
    + spin_unlock_irqrestore(&priv->reg_lock, flags); \
    + talitos_error(dev, isr & ch_err_mask, isr_lo); \
    + } \
    + else { \
    if (likely(isr & ch_done_mask)) { \
    /* mask further done interrupts. */ \
    clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
    /* done_task will unmask done interrupts at exit */ \
    tasklet_schedule(&priv->done_task[tlet]); \
    } \
    + spin_unlock_irqrestore(&priv->reg_lock, flags); \
    + } \
    \
    return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
    IRQ_NONE; \
    @@ -2718,6 +2730,8 @@ static int talitos_probe(struct platform

    priv->ofdev = ofdev;

    + spin_lock_init(&priv->reg_lock);
    +
    err = talitos_probe_irq(ofdev);
    if (err)
    goto err_out;



    \
     
     \ /
      Last update: 2012-05-04 23:41    [W:0.028 / U:60.484 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site