Thread (42 messages) 42 messages, 3 authors, 2018-10-18

[PATCH V4 05/11] clk: imx: scu: add scu clock gate

From: sboyd@kernel.org (Stephen Boyd)
Date: 2018-10-16 21:18:34
Also in: linux-clk

Quoting A.s. Dong (2018-10-15 08:30:45)
quoted
-----Original Message-----
From: Sascha Hauer [mailto:s.hauer at pengutronix.de]
Sent: Monday, October 15, 2018 5:54 PM
To: A.s. Dong <aisheng.dong@nxp.com>
Cc: linux-clk at vger.kernel.org; sboyd at kernel.org; mturquette at baylibre.com;
dl-linux-imx [off-list ref]; kernel at pengutronix.de; Fabio Estevam
[off-list ref]; shawnguo at kernel.org;
linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH V4 05/11] clk: imx: scu: add scu clock gate

On Mon, Oct 15, 2018 at 09:17:14AM +0000, A.s. Dong wrote:
quoted
quoted
-----Original Message-----
From: Sascha Hauer [mailto:s.hauer at pengutronix.de]
Sent: Monday, October 15, 2018 3:32 PM
To: A.s. Dong <aisheng.dong@nxp.com>
Cc: linux-clk at vger.kernel.org; sboyd at kernel.org;
mturquette at baylibre.com; dl-linux-imx [off-list ref];
kernel at pengutronix.de; Fabio Estevam [off-list ref];
shawnguo at kernel.org; linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH V4 05/11] clk: imx: scu: add scu clock gate

On Sun, Oct 14, 2018 at 08:07:56AM +0000, A.s. Dong wrote:
quoted
+/* Write to the LPCG bits. */
+static int clk_gate_scu_enable(struct clk_hw *hw) {
+       struct clk_gate_scu *gate = to_clk_gate_scu(hw);
+       u32 reg;
+
+       if (gate->reg) {
+               reg = readl(gate->reg);
+               reg &= ~(CLK_GATE_SCU_LPCG_MASK << gate->bit_idx);
+               if (gate->hw_gate)
+                       reg |= (CLK_GATE_SCU_LPCG_HW_SEL |
+                               CLK_GATE_SCU_LPCG_SW_SEL) << gate->bit_idx;
+               else
+                       reg |= (CLK_GATE_SCU_LPCG_SW_SEL << gate->bit_idx);
+               writel(reg, gate->reg);
+       }
These register manipulations look like they need locking.
Unlike the legacy MX6&7 SoCs, each clock has a separate LPCG register.
Do we still need locking?
Let's take PWM_0_LPCG as an example:

+       clks[IMX8QXP_LSIO_PWM0_IPG_S_CLK]       =
imx_clk_gate_scu("pwm_0_ipg_s_clk", "pwm_0_div", IMX_SC_R_PWM_0,
IMX_SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0x10, 0);
+       clks[IMX8QXP_LSIO_PWM0_IPG_SLV_CLK]     =
imx_clk_gate_scu("pwm_0_ipg_slv_clk", "pwm_0_ipg_s_clk",
IMX_SC_R_PWM_0, IMX_SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG),
0x14, 0);
+       clks[IMX8QXP_LSIO_PWM0_IPG_MSTR_CLK]    =
imx_clk_gate2_scu("pwm_0_ipg_mstr_clk", "lsio_bus_clk_root", (void
__iomem *)(PWM_0_LPCG), 0x18, 0);
+       clks[IMX8QXP_LSIO_PWM0_HF_CLK]          =
imx_clk_gate_scu("pwm_0_hf_clk", "pwm_0_ipg_slv_clk", IMX_SC_R_PWM_0,
IMX_SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 4, 0);
+       clks[IMX8QXP_LSIO_PWM0_CLK]             =
imx_clk_gate_scu("pwm_0_clk", "pwm_0_ipg_slv_clk", IMX_SC_R_PWM_0,
IMX_SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0, 0);

This register is used in five different clocks.
Good catch.
BTW, it seems for the same clk group, we may still not need lock
as the clock framework already defined the global enable/disable lock
for the same group.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/driver-api/clk.rst
" Drivers don't need to manually protect resources shared between the operations
of one group, regardless of whether those resources are shared by multiple
clocks or not. However, access to resources that are shared between operations
of the two groups needs to be protected by the drivers."

Do you think it's okay to drop it?
No it's not OK. We prefer that clk drivers don't assume the global locks
in the clk framework are going to protect them from concurrent access to
the same resource between different clks. Drivers can assume that a clk
op won't be called in parallel for the same clk, but they shouldn't
assume that everything is protected otherwise. If they did, we would
have to go find all the drivers that make this assumption and then fix
them when we eventually split the lock into smaller pieces.

Long story short, if you have something shared (i.e. a register) and you
plan to write to it and read from it for multiple clks, add a lock
around it.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help