diff options
author | Martin Sperl <kernel@martin.sperl.org> | 2016-02-29 12:39:18 +0100 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2016-03-17 18:42:17 +0100 |
commit | ec36a5c6682fdd5328abf15c3c67281bed0241d7 (patch) | |
tree | 661c3386d950521ff390a5415eb86636b1d7ec31 | |
parent | clk: bcm2835: pll_off should only update CM_PLL_ANARST (diff) | |
download | linux-ec36a5c6682fdd5328abf15c3c67281bed0241d7.tar.xz linux-ec36a5c6682fdd5328abf15c3c67281bed0241d7.zip |
clk: bcm2835: add locking to pll*_on/off methods
Add missing locking to:
* bcm2835_pll_divider_on
* bcm2835_pll_divider_off
to protect the read modify write cycle for the
register access protecting both cm_reg and a2w_reg
registers.
Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the
audio domain clocks")
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r-- | drivers/clk/bcm/clk-bcm2835.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index adbaa55e939c..a39f8a7b6410 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1085,10 +1085,12 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw) struct bcm2835_cprman *cprman = divider->cprman; const struct bcm2835_pll_divider_data *data = divider->data; + spin_lock(&cprman->regs_lock); cprman_write(cprman, data->cm_reg, (cprman_read(cprman, data->cm_reg) & ~data->load_mask) | data->hold_mask); cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE); + spin_unlock(&cprman->regs_lock); } static int bcm2835_pll_divider_on(struct clk_hw *hw) @@ -1097,12 +1099,14 @@ static int bcm2835_pll_divider_on(struct clk_hw *hw) struct bcm2835_cprman *cprman = divider->cprman; const struct bcm2835_pll_divider_data *data = divider->data; + spin_lock(&cprman->regs_lock); cprman_write(cprman, data->a2w_reg, cprman_read(cprman, data->a2w_reg) & ~A2W_PLL_CHANNEL_DISABLE); cprman_write(cprman, data->cm_reg, cprman_read(cprman, data->cm_reg) & ~data->hold_mask); + spin_unlock(&cprman->regs_lock); return 0; } |