[PATCH V3 09/15] ASoC: samsung: i2s: Protect more registers with a spinlock

Tushar Behera trblinux at gmail.com
Fri Jan 16 21:21:46 PST 2015


On Thu, Jan 15, 2015 at 3:42 AM, Sylwester Nawrocki
<s.nawrocki at samsung.com> wrote:
> Ensure the I2SMOD, I2SPSR registers, which are also exposed through
> clk API are only accessed with the i2s->spinlock spinlock held.
>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki at samsung.com>
> ---
>  sound/soc/samsung/i2s.c |   81 +++++++++++++++++++++++++++++------------------
>  1 file changed, 51 insertions(+), 30 deletions(-)
>
> diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
> index 20cc51f..05fc2f0 100644
> --- a/sound/soc/samsung/i2s.c
> +++ b/sound/soc/samsung/i2s.c
> @@ -472,17 +472,22 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
>  {
>         struct i2s_dai *i2s = to_info(dai);
>         struct i2s_dai *other = get_other_dai(i2s);
> -       u32 mod = readl(i2s->addr + I2SMOD);
>         const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs;
>         unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off;
>         unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off;
> +       u32 mod, mask, val = 0;
> +
> +       spin_lock(i2s->lock);
> +       mod = readl(i2s->addr + I2SMOD);
> +       spin_unlock(i2s->lock);
>

'mod' is now updated only at the bottom of this function. The above
readl can be omitted.

>         switch (clk_id) {
>         case SAMSUNG_I2S_OPCLK:
> -               mod &= ~MOD_OPCLK_MASK;
> -               mod |= dir;
> +               mask = MOD_OPCLK_MASK;
> +               val = dir;
>                 break;
>         case SAMSUNG_I2S_CDCLK:
> +               mask = 1 << i2s_regs->cdclkcon_off;

Use BIT() macro instead?

>                 /* Shouldn't matter in GATING(CLOCK_IN) mode */
>                 if (dir == SND_SOC_CLOCK_IN)
>                         rfs = 0;
> @@ -499,15 +504,15 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
>                 }
>
>                 if (dir == SND_SOC_CLOCK_IN)
> -                       mod |= 1 << i2s_regs->cdclkcon_off;
> -               else
> -                       mod &= ~(1 << i2s_regs->cdclkcon_off);
> +                       val = 1 << i2s_regs->cdclkcon_off;
>

Same as above.

>                 i2s->rfs = rfs;
>                 break;
>
>         case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */
>         case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
> +               mask = 1 << i2s_regs->rclksrc_off;
> +

Same as above.

>                 if ((i2s->quirks & QUIRK_NO_MUXPSR)
>                                 || (clk_id == SAMSUNG_I2S_RCLKSRC_0))
>                         clk_id = 0;
> @@ -557,18 +562,19 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
>                         return 0;
>                 }
>
> -               if (clk_id == 0)
> -                       mod &= ~(1 << i2s_regs->rclksrc_off);
> -               else
> -                       mod |= 1 << i2s_regs->rclksrc_off;
> -
> +               if (clk_id == 1)
> +                       val = 1 << i2s_regs->rclksrc_off;

Same as above.

-- 
Tushar Behera



More information about the linux-arm-kernel mailing list