cregit-Linux how code gets into the kernel

Release 4.7 drivers/clk/qcom/clk-branch.c

Directory: drivers/clk/qcom
/*
 * Copyright (c) 2013, 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
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>

#include "clk-branch.h"


static bool clk_branch_in_hwcg_mode(const struct clk_branch *br) { u32 val; if (!br->hwcg_reg) return 0; regmap_read(br->clkr.regmap, br->hwcg_reg, &val); return !!(val & BIT(br->hwcg_bit)); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd55100.00%1100.00%
Total55100.00%1100.00%


static bool clk_branch_check_halt(const struct clk_branch *br, bool enabling) { bool invert = (br->halt_check == BRANCH_HALT_ENABLE); u32 val; regmap_read(br->clkr.regmap, br->halt_reg, &val); val &= BIT(br->halt_bit); if (invert) val = !val; return !!val == !enabling; }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd71100.00%1100.00%
Total71100.00%1100.00%

#define BRANCH_CLK_OFF BIT(31) #define BRANCH_NOC_FSM_STATUS_SHIFT 28 #define BRANCH_NOC_FSM_STATUS_MASK 0x7 #define BRANCH_NOC_FSM_STATUS_ON (0x2 << BRANCH_NOC_FSM_STATUS_SHIFT)
static bool clk_branch2_check_halt(const struct clk_branch *br, bool enabling) { u32 val; u32 mask; mask = BRANCH_NOC_FSM_STATUS_MASK << BRANCH_NOC_FSM_STATUS_SHIFT; mask |= BRANCH_CLK_OFF; regmap_read(br->clkr.regmap, br->halt_reg, &val); if (enabling) { val &= mask; return (val & BRANCH_CLK_OFF) == 0 || val == BRANCH_NOC_FSM_STATUS_ON; } else { return val & BRANCH_CLK_OFF; } }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd78100.00%1100.00%
Total78100.00%1100.00%


static int clk_branch_wait(const struct clk_branch *br, bool enabling, bool (check_halt)(const struct clk_branch *, bool)) { bool voted = br->halt_check & BRANCH_VOTED; const char *name = clk_hw_get_name(&br->clkr.hw); /* Skip checking halt bit if the clock is in hardware gated mode */ if (clk_branch_in_hwcg_mode(br)) return 0; if (br->halt_check == BRANCH_HALT_DELAY || (!enabling && voted)) { udelay(10); } else if (br->halt_check == BRANCH_HALT_ENABLE || br->halt_check == BRANCH_HALT || (enabling && voted)) { int count = 200; while (count-- > 0) { if (check_halt(br, enabling)) return 0; udelay(1); } WARN(1, "%s status stuck at 'o%s'", name, enabling ? "ff" : "n"); return -EBUSY; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd161100.00%2100.00%
Total161100.00%2100.00%


static int clk_branch_toggle(struct clk_hw *hw, bool en, bool (check_halt)(const struct clk_branch *, bool)) { struct clk_branch *br = to_clk_branch(hw); int ret; if (en) { ret = clk_enable_regmap(hw); if (ret) return ret; } else { clk_disable_regmap(hw); } return clk_branch_wait(br, en, check_halt); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd78100.00%1100.00%
Total78100.00%1100.00%


static int clk_branch_enable(struct clk_hw *hw) { return clk_branch_toggle(hw, true, clk_branch_check_halt); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd21100.00%1100.00%
Total21100.00%1100.00%


static void clk_branch_disable(struct clk_hw *hw) { clk_branch_toggle(hw, false, clk_branch_check_halt); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd20100.00%1100.00%
Total20100.00%1100.00%

const struct clk_ops clk_branch_ops = { .enable = clk_branch_enable, .disable = clk_branch_disable, .is_enabled = clk_is_enabled_regmap, }; EXPORT_SYMBOL_GPL(clk_branch_ops);
static int clk_branch2_enable(struct clk_hw *hw) { return clk_branch_toggle(hw, true, clk_branch2_check_halt); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd21100.00%1100.00%
Total21100.00%1100.00%


static void clk_branch2_disable(struct clk_hw *hw) { clk_branch_toggle(hw, false, clk_branch2_check_halt); }

Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd20100.00%1100.00%
Total20100.00%1100.00%

const struct clk_ops clk_branch2_ops = { .enable = clk_branch2_enable, .disable = clk_branch2_disable, .is_enabled = clk_is_enabled_regmap, }; EXPORT_SYMBOL_GPL(clk_branch2_ops); const struct clk_ops clk_branch_simple_ops = { .enable = clk_enable_regmap, .disable = clk_disable_regmap, .is_enabled = clk_is_enabled_regmap, }; EXPORT_SYMBOL_GPL(clk_branch_simple_ops);

Overall Contributors

PersonTokensPropCommitsCommitProp
stephen boydstephen boyd647100.00%2100.00%
Total647100.00%2100.00%
Directory: drivers/clk/qcom
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}