Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Nicolas Ferre and committed by
Stephen Boyd
36844bdf 96ef36e9

+14 -6
+14 -6
drivers/clk/at91/clk-peripheral.c
··· 161 161 { 162 162 struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); 163 163 struct at91_pmc *pmc = periph->pmc; 164 + u32 tmp; 164 165 165 166 if (periph->id < PERIPHERAL_ID_MIN) 166 167 return 0; 167 168 168 - pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK) | 169 - AT91_PMC_PCR_CMD | 170 - AT91_PMC_PCR_DIV(periph->div) | 171 - AT91_PMC_PCR_EN); 169 + pmc_lock(pmc); 170 + pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); 171 + tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_DIV_MASK; 172 + pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_DIV(periph->div) 173 + | AT91_PMC_PCR_CMD 174 + | AT91_PMC_PCR_EN); 175 + pmc_unlock(pmc); 172 176 return 0; 173 177 } 174 178 ··· 180 176 { 181 177 struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); 182 178 struct at91_pmc *pmc = periph->pmc; 179 + u32 tmp; 183 180 184 181 if (periph->id < PERIPHERAL_ID_MIN) 185 182 return; 186 183 187 - pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK) | 188 - AT91_PMC_PCR_CMD); 184 + pmc_lock(pmc); 185 + pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); 186 + tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_EN; 187 + pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD); 188 + pmc_unlock(pmc); 189 189 } 190 190 191 191 static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)