Loading drivers/clk/qcom/clk-branch.c +40 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and Loading Loading @@ -83,6 +83,9 @@ static int clk_branch_wait(const struct clk_branch *br, bool enabling, if (br->halt_check == BRANCH_HALT_DELAY || (!enabling && voted)) { udelay(10); } else if ((br->halt_check == BRANCH_HALT_NO_CHECK_ON_DISABLE) && !enabling) { return 0; } else if (br->halt_check == BRANCH_HALT_ENABLE || br->halt_check == BRANCH_HALT || (enabling && voted)) { Loading Loading @@ -151,6 +154,42 @@ const struct clk_ops clk_branch2_ops = { }; EXPORT_SYMBOL_GPL(clk_branch2_ops); static int clk_gate_toggle(struct clk_hw *hw, bool en) { struct clk_gate2 *gt = to_clk_gate2(hw); int ret = 0; if (en) { ret = clk_enable_regmap(hw); if (ret) return ret; } else { clk_disable_regmap(hw); } if (gt->udelay) udelay(gt->udelay); return ret; } static int clk_gate2_enable(struct clk_hw *hw) { return clk_gate_toggle(hw, true); } static void clk_gate2_disable(struct clk_hw *hw) { clk_gate_toggle(hw, false); } const struct clk_ops clk_gate2_ops = { .enable = clk_gate2_enable, .disable = clk_gate2_disable, .is_enabled = clk_is_enabled_regmap, }; EXPORT_SYMBOL_GPL(clk_gate2_ops); const struct clk_ops clk_branch_simple_ops = { .enable = clk_enable_regmap, .disable = clk_disable_regmap, Loading drivers/clk/qcom/clk-branch.h +21 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and Loading Loading @@ -42,15 +42,35 @@ struct clk_branch { #define BRANCH_HALT_ENABLE 1 /* pol: 0 = halt */ #define BRANCH_HALT_ENABLE_VOTED (BRANCH_HALT_ENABLE | BRANCH_VOTED) #define BRANCH_HALT_DELAY 2 /* No bit to check; just delay */ /* No halt check during clk disable for the clocks controlled by other masters * via voting registers like SMMU clocks. */ #define BRANCH_HALT_NO_CHECK_ON_DISABLE 4 struct clk_regmap clkr; }; /** * struct clk_gate2 - gating clock with status bit and dynamic hardware gating * @udelay: halt delay in microseconds on clock branch Enable/Disable * @clkr: handle between common and hardware-specific interfaces * * Clock which can gate its output. */ struct clk_gate2 { u32 udelay; struct clk_regmap clkr; }; extern const struct clk_ops clk_branch_ops; extern const struct clk_ops clk_branch2_ops; extern const struct clk_ops clk_gate2_ops; extern const struct clk_ops clk_branch_simple_ops; #define to_clk_branch(_hw) \ container_of(to_clk_regmap(_hw), struct clk_branch, clkr) #define to_clk_gate2(_hw) \ container_of(to_clk_regmap(_hw), struct clk_gate2, clkr) #endif Loading
drivers/clk/qcom/clk-branch.c +40 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and Loading Loading @@ -83,6 +83,9 @@ static int clk_branch_wait(const struct clk_branch *br, bool enabling, if (br->halt_check == BRANCH_HALT_DELAY || (!enabling && voted)) { udelay(10); } else if ((br->halt_check == BRANCH_HALT_NO_CHECK_ON_DISABLE) && !enabling) { return 0; } else if (br->halt_check == BRANCH_HALT_ENABLE || br->halt_check == BRANCH_HALT || (enabling && voted)) { Loading Loading @@ -151,6 +154,42 @@ const struct clk_ops clk_branch2_ops = { }; EXPORT_SYMBOL_GPL(clk_branch2_ops); static int clk_gate_toggle(struct clk_hw *hw, bool en) { struct clk_gate2 *gt = to_clk_gate2(hw); int ret = 0; if (en) { ret = clk_enable_regmap(hw); if (ret) return ret; } else { clk_disable_regmap(hw); } if (gt->udelay) udelay(gt->udelay); return ret; } static int clk_gate2_enable(struct clk_hw *hw) { return clk_gate_toggle(hw, true); } static void clk_gate2_disable(struct clk_hw *hw) { clk_gate_toggle(hw, false); } const struct clk_ops clk_gate2_ops = { .enable = clk_gate2_enable, .disable = clk_gate2_disable, .is_enabled = clk_is_enabled_regmap, }; EXPORT_SYMBOL_GPL(clk_gate2_ops); const struct clk_ops clk_branch_simple_ops = { .enable = clk_enable_regmap, .disable = clk_disable_regmap, Loading
drivers/clk/qcom/clk-branch.h +21 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and Loading Loading @@ -42,15 +42,35 @@ struct clk_branch { #define BRANCH_HALT_ENABLE 1 /* pol: 0 = halt */ #define BRANCH_HALT_ENABLE_VOTED (BRANCH_HALT_ENABLE | BRANCH_VOTED) #define BRANCH_HALT_DELAY 2 /* No bit to check; just delay */ /* No halt check during clk disable for the clocks controlled by other masters * via voting registers like SMMU clocks. */ #define BRANCH_HALT_NO_CHECK_ON_DISABLE 4 struct clk_regmap clkr; }; /** * struct clk_gate2 - gating clock with status bit and dynamic hardware gating * @udelay: halt delay in microseconds on clock branch Enable/Disable * @clkr: handle between common and hardware-specific interfaces * * Clock which can gate its output. */ struct clk_gate2 { u32 udelay; struct clk_regmap clkr; }; extern const struct clk_ops clk_branch_ops; extern const struct clk_ops clk_branch2_ops; extern const struct clk_ops clk_gate2_ops; extern const struct clk_ops clk_branch_simple_ops; #define to_clk_branch(_hw) \ container_of(to_clk_regmap(_hw), struct clk_branch, clkr) #define to_clk_gate2(_hw) \ container_of(to_clk_regmap(_hw), struct clk_gate2, clkr) #endif