summaryrefslogtreecommitdiffstats
path: root/drivers/clk/at91
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2015-06-17 14:40:39 +0200
committerStephen Boyd <sboyd@codeaurora.org>2015-10-01 12:39:43 -0700
commit36844bdf651a2ae2d35ae4b11337671905b67bff (patch)
tree8f0b69cce35a77befce1fec3c0c7d0c027e63978 /drivers/clk/at91
parent96ef36e9c424b7a66413bb9229ef5afcddf4fef4 (diff)
downloadop-kernel-dev-36844bdf651a2ae2d35ae4b11337671905b67bff.zip
op-kernel-dev-36844bdf651a2ae2d35ae4b11337671905b67bff.tar.gz
clk: at91: modify PMC peripheral clock to deal with newer register layout
As some more information is added to the PCR register, we'd better use a copy of its content and modify just the peripheral-related bits. Implement a read-modify-write for the enable() and disable() callbacks. Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk/at91')
-rw-r--r--drivers/clk/at91/clk-peripheral.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index 0a66b95..58f3b56 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -161,14 +161,18 @@ static int clk_sam9x5_peripheral_enable(struct clk_hw *hw)
{
struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
struct at91_pmc *pmc = periph->pmc;
+ u32 tmp;
if (periph->id < PERIPHERAL_ID_MIN)
return 0;
- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK) |
- AT91_PMC_PCR_CMD |
- AT91_PMC_PCR_DIV(periph->div) |
- AT91_PMC_PCR_EN);
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+ tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_DIV_MASK;
+ pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_DIV(periph->div)
+ | AT91_PMC_PCR_CMD
+ | AT91_PMC_PCR_EN);
+ pmc_unlock(pmc);
return 0;
}
@@ -176,12 +180,16 @@ static void clk_sam9x5_peripheral_disable(struct clk_hw *hw)
{
struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
struct at91_pmc *pmc = periph->pmc;
+ u32 tmp;
if (periph->id < PERIPHERAL_ID_MIN)
return;
- pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK) |
- AT91_PMC_PCR_CMD);
+ pmc_lock(pmc);
+ pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+ tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_EN;
+ pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD);
+ pmc_unlock(pmc);
}
static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
OpenPOWER on IntegriCloud