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

clk: add MOXA ART SoCs clock driver

MOXA ART SoCs allow to determine PLL output and APB frequencies
by reading registers holding multiplier and divisor information.

Add a clock driver for this SoC.

Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>

authored by

Jonas Jensen and committed by
Mike Turquette
c7bb4fc1 5ba8dac0

+146
+48
Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt
··· 1 + Device Tree Clock bindings for arch-moxart 2 + 3 + This binding uses the common clock binding[1]. 4 + 5 + [1] Documentation/devicetree/bindings/clock/clock-bindings.txt 6 + 7 + MOXA ART SoCs allow to determine PLL output and APB frequencies 8 + by reading registers holding multiplier and divisor information. 9 + 10 + 11 + PLL: 12 + 13 + Required properties: 14 + - compatible : Must be "moxa,moxart-pll-clock" 15 + - #clock-cells : Should be 0 16 + - reg : Should contain registers location and length 17 + - clocks : Should contain phandle + clock-specifier for the parent clock 18 + 19 + Optional properties: 20 + - clock-output-names : Should contain clock name 21 + 22 + 23 + APB: 24 + 25 + Required properties: 26 + - compatible : Must be "moxa,moxart-apb-clock" 27 + - #clock-cells : Should be 0 28 + - reg : Should contain registers location and length 29 + - clocks : Should contain phandle + clock-specifier for the parent clock 30 + 31 + Optional properties: 32 + - clock-output-names : Should contain clock name 33 + 34 + 35 + For example: 36 + 37 + clk_pll: clk_pll@98100000 { 38 + compatible = "moxa,moxart-pll-clock"; 39 + #clock-cells = <0>; 40 + reg = <0x98100000 0x34>; 41 + }; 42 + 43 + clk_apb: clk_apb@98100000 { 44 + compatible = "moxa,moxart-apb-clock"; 45 + #clock-cells = <0>; 46 + reg = <0x98100000 0x34>; 47 + clocks = <&clk_pll>; 48 + };
+1
drivers/clk/Makefile
··· 17 17 obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 18 18 obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o 19 19 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 20 + obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o 20 21 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 21 22 obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o 22 23 obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
+97
drivers/clk/clk-moxart.c
··· 1 + /* 2 + * MOXA ART SoCs clock driver. 3 + * 4 + * Copyright (C) 2013 Jonas Jensen 5 + * 6 + * Jonas Jensen <jonas.jensen@gmail.com> 7 + * 8 + * This file is licensed under the terms of the GNU General Public 9 + * License version 2. This program is licensed "as is" without any 10 + * warranty of any kind, whether express or implied. 11 + */ 12 + 13 + #include <linux/clk-provider.h> 14 + #include <linux/io.h> 15 + #include <linux/of_address.h> 16 + #include <linux/clkdev.h> 17 + 18 + void __init moxart_of_pll_clk_init(struct device_node *node) 19 + { 20 + static void __iomem *base; 21 + struct clk *clk, *ref_clk; 22 + unsigned int mul; 23 + const char *name = node->name; 24 + const char *parent_name; 25 + 26 + of_property_read_string(node, "clock-output-names", &name); 27 + parent_name = of_clk_get_parent_name(node, 0); 28 + 29 + base = of_iomap(node, 0); 30 + if (!base) { 31 + pr_err("%s: of_iomap failed\n", node->full_name); 32 + return; 33 + } 34 + 35 + mul = readl(base + 0x30) >> 3 & 0x3f; 36 + iounmap(base); 37 + 38 + ref_clk = of_clk_get(node, 0); 39 + if (IS_ERR(ref_clk)) { 40 + pr_err("%s: of_clk_get failed\n", node->full_name); 41 + return; 42 + } 43 + 44 + clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); 45 + if (IS_ERR(clk)) { 46 + pr_err("%s: failed to register clock\n", node->full_name); 47 + return; 48 + } 49 + 50 + clk_register_clkdev(clk, NULL, name); 51 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 52 + } 53 + CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", 54 + moxart_of_pll_clk_init); 55 + 56 + void __init moxart_of_apb_clk_init(struct device_node *node) 57 + { 58 + static void __iomem *base; 59 + struct clk *clk, *pll_clk; 60 + unsigned int div, val; 61 + unsigned int div_idx[] = { 2, 3, 4, 6, 8}; 62 + const char *name = node->name; 63 + const char *parent_name; 64 + 65 + of_property_read_string(node, "clock-output-names", &name); 66 + parent_name = of_clk_get_parent_name(node, 0); 67 + 68 + base = of_iomap(node, 0); 69 + if (!base) { 70 + pr_err("%s: of_iomap failed\n", node->full_name); 71 + return; 72 + } 73 + 74 + val = readl(base + 0xc) >> 4 & 0x7; 75 + iounmap(base); 76 + 77 + if (val > 4) 78 + val = 0; 79 + div = div_idx[val] * 2; 80 + 81 + pll_clk = of_clk_get(node, 0); 82 + if (IS_ERR(pll_clk)) { 83 + pr_err("%s: of_clk_get failed\n", node->full_name); 84 + return; 85 + } 86 + 87 + clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div); 88 + if (IS_ERR(clk)) { 89 + pr_err("%s: failed to register clock\n", node->full_name); 90 + return; 91 + } 92 + 93 + clk_register_clkdev(clk, NULL, name); 94 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 95 + } 96 + CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock", 97 + moxart_of_apb_clk_init);