linux/drivers/clk/clk-moxart.c
<<
>>
Prefs
   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.h>
  14#include <linux/clk-provider.h>
  15#include <linux/io.h>
  16#include <linux/of_address.h>
  17#include <linux/clkdev.h>
  18
  19static void __init moxart_of_pll_clk_init(struct device_node *node)
  20{
  21        void __iomem *base;
  22        struct clk_hw *hw;
  23        struct clk *ref_clk;
  24        unsigned int mul;
  25        const char *name = node->name;
  26        const char *parent_name;
  27
  28        of_property_read_string(node, "clock-output-names", &name);
  29        parent_name = of_clk_get_parent_name(node, 0);
  30
  31        base = of_iomap(node, 0);
  32        if (!base) {
  33                pr_err("%pOF: of_iomap failed\n", node);
  34                return;
  35        }
  36
  37        mul = readl(base + 0x30) >> 3 & 0x3f;
  38        iounmap(base);
  39
  40        ref_clk = of_clk_get(node, 0);
  41        if (IS_ERR(ref_clk)) {
  42                pr_err("%pOF: of_clk_get failed\n", node);
  43                return;
  44        }
  45
  46        hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
  47        if (IS_ERR(hw)) {
  48                pr_err("%pOF: failed to register clock\n", node);
  49                return;
  50        }
  51
  52        clk_hw_register_clkdev(hw, NULL, name);
  53        of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
  54}
  55CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
  56               moxart_of_pll_clk_init);
  57
  58static void __init moxart_of_apb_clk_init(struct device_node *node)
  59{
  60        void __iomem *base;
  61        struct clk_hw *hw;
  62        struct clk *pll_clk;
  63        unsigned int div, val;
  64        unsigned int div_idx[] = { 2, 3, 4, 6, 8};
  65        const char *name = node->name;
  66        const char *parent_name;
  67
  68        of_property_read_string(node, "clock-output-names", &name);
  69        parent_name = of_clk_get_parent_name(node, 0);
  70
  71        base = of_iomap(node, 0);
  72        if (!base) {
  73                pr_err("%pOF: of_iomap failed\n", node);
  74                return;
  75        }
  76
  77        val = readl(base + 0xc) >> 4 & 0x7;
  78        iounmap(base);
  79
  80        if (val > 4)
  81                val = 0;
  82        div = div_idx[val] * 2;
  83
  84        pll_clk = of_clk_get(node, 0);
  85        if (IS_ERR(pll_clk)) {
  86                pr_err("%pOF: of_clk_get failed\n", node);
  87                return;
  88        }
  89
  90        hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
  91        if (IS_ERR(hw)) {
  92                pr_err("%pOF: failed to register clock\n", node);
  93                return;
  94        }
  95
  96        clk_hw_register_clkdev(hw, NULL, name);
  97        of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
  98}
  99CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock",
 100               moxart_of_apb_clk_init);
 101