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

clk: sprd: Add common infrastructure

Added Spreadtrum's clock driver framework together with common
structures and interface functions.

Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>

authored by

Chunyan Zhang and committed by
Stephen Boyd
d41f59fd 1ded879e

+143
+1
drivers/clk/Kconfig
··· 236 236 source "drivers/clk/qcom/Kconfig" 237 237 source "drivers/clk/renesas/Kconfig" 238 238 source "drivers/clk/samsung/Kconfig" 239 + source "drivers/clk/sprd/Kconfig" 239 240 source "drivers/clk/sunxi-ng/Kconfig" 240 241 source "drivers/clk/tegra/Kconfig" 241 242 source "drivers/clk/ti/Kconfig"
+1
drivers/clk/Makefile
··· 85 85 obj-$(CONFIG_ARCH_SIRF) += sirf/ 86 86 obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ 87 87 obj-$(CONFIG_PLAT_SPEAR) += spear/ 88 + obj-$(CONFIG_ARCH_SPRD) += sprd/ 88 89 obj-$(CONFIG_ARCH_STI) += st/ 89 90 obj-$(CONFIG_ARCH_SUNXI) += sunxi/ 90 91 obj-$(CONFIG_ARCH_SUNXI) += sunxi-ng/
+4
drivers/clk/sprd/Kconfig
··· 1 + config SPRD_COMMON_CLK 2 + tristate "Clock support for Spreadtrum SoCs" 3 + depends on ARCH_SPRD || COMPILE_TEST 4 + default ARCH_SPRD
+3
drivers/clk/sprd/Makefile
··· 1 + obj-$(CONFIG_SPRD_COMMON_CLK) += clk-sprd.o 2 + 3 + clk-sprd-y += common.o
+96
drivers/clk/sprd/common.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Spreadtrum clock infrastructure 4 + // 5 + // Copyright (C) 2017 Spreadtrum, Inc. 6 + // Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> 7 + 8 + #include <linux/mfd/syscon.h> 9 + #include <linux/module.h> 10 + #include <linux/of_address.h> 11 + #include <linux/of_platform.h> 12 + #include <linux/regmap.h> 13 + 14 + #include "common.h" 15 + 16 + static const struct regmap_config sprdclk_regmap_config = { 17 + .reg_bits = 32, 18 + .reg_stride = 4, 19 + .val_bits = 32, 20 + .max_register = 0xffff, 21 + .fast_io = true, 22 + }; 23 + 24 + static void sprd_clk_set_regmap(const struct sprd_clk_desc *desc, 25 + struct regmap *regmap) 26 + { 27 + int i; 28 + struct sprd_clk_common *cclk; 29 + 30 + for (i = 0; i < desc->num_clk_clks; i++) { 31 + cclk = desc->clk_clks[i]; 32 + if (!cclk) 33 + continue; 34 + 35 + cclk->regmap = regmap; 36 + } 37 + } 38 + 39 + int sprd_clk_regmap_init(struct platform_device *pdev, 40 + const struct sprd_clk_desc *desc) 41 + { 42 + void __iomem *base; 43 + struct device_node *node = pdev->dev.of_node; 44 + struct regmap *regmap; 45 + 46 + if (of_find_property(node, "sprd,syscon", NULL)) { 47 + regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon"); 48 + if (IS_ERR_OR_NULL(regmap)) { 49 + pr_err("%s: failed to get syscon regmap\n", __func__); 50 + return PTR_ERR(regmap); 51 + } 52 + } else { 53 + base = of_iomap(node, 0); 54 + regmap = devm_regmap_init_mmio(&pdev->dev, base, 55 + &sprdclk_regmap_config); 56 + if (IS_ERR_OR_NULL(regmap)) { 57 + pr_err("failed to init regmap\n"); 58 + return PTR_ERR(regmap); 59 + } 60 + } 61 + 62 + sprd_clk_set_regmap(desc, regmap); 63 + 64 + return 0; 65 + } 66 + EXPORT_SYMBOL_GPL(sprd_clk_regmap_init); 67 + 68 + int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw) 69 + { 70 + int i, ret; 71 + struct clk_hw *hw; 72 + 73 + for (i = 0; i < clkhw->num; i++) { 74 + 75 + hw = clkhw->hws[i]; 76 + 77 + if (!hw) 78 + continue; 79 + 80 + ret = devm_clk_hw_register(dev, hw); 81 + if (ret) { 82 + dev_err(dev, "Couldn't register clock %d - %s\n", 83 + i, hw->init->name); 84 + return ret; 85 + } 86 + } 87 + 88 + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clkhw); 89 + if (ret) 90 + dev_err(dev, "Failed to add clock provider\n"); 91 + 92 + return ret; 93 + } 94 + EXPORT_SYMBOL_GPL(sprd_clk_probe); 95 + 96 + MODULE_LICENSE("GPL v2");
+38
drivers/clk/sprd/common.h
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Spreadtrum clock infrastructure 4 + // 5 + // Copyright (C) 2017 Spreadtrum, Inc. 6 + // Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com> 7 + 8 + #ifndef _SPRD_CLK_COMMON_H_ 9 + #define _SPRD_CLK_COMMON_H_ 10 + 11 + #include <linux/clk-provider.h> 12 + #include <linux/of_platform.h> 13 + #include <linux/regmap.h> 14 + 15 + struct device_node; 16 + 17 + struct sprd_clk_common { 18 + struct regmap *regmap; 19 + u32 reg; 20 + struct clk_hw hw; 21 + }; 22 + 23 + struct sprd_clk_desc { 24 + struct sprd_clk_common **clk_clks; 25 + unsigned long num_clk_clks; 26 + struct clk_hw_onecell_data *hw_clks; 27 + }; 28 + 29 + static inline struct sprd_clk_common * 30 + hw_to_sprd_clk_common(const struct clk_hw *hw) 31 + { 32 + return container_of(hw, struct sprd_clk_common, hw); 33 + } 34 + int sprd_clk_regmap_init(struct platform_device *pdev, 35 + const struct sprd_clk_desc *desc); 36 + int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw); 37 + 38 + #endif /* _SPRD_CLK_COMMON_H_ */