linux/drivers/clk/ti/interface.c
<<
>>
Prefs
   1/*
   2 * OMAP interface clock support
   3 *
   4 * Copyright (C) 2013 Texas Instruments, Inc.
   5 *
   6 * Tero Kristo <t-kristo@ti.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 *
  12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  13 * kind, whether express or implied; without even the implied warranty
  14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 */
  17
  18#include <linux/clk-provider.h>
  19#include <linux/slab.h>
  20#include <linux/of.h>
  21#include <linux/of_address.h>
  22#include <linux/clk/ti.h>
  23
  24#undef pr_fmt
  25#define pr_fmt(fmt) "%s: " fmt, __func__
  26
  27static const struct clk_ops ti_interface_clk_ops = {
  28        .init           = &omap2_init_clk_clkdm,
  29        .enable         = &omap2_dflt_clk_enable,
  30        .disable        = &omap2_dflt_clk_disable,
  31        .is_enabled     = &omap2_dflt_clk_is_enabled,
  32};
  33
  34static void __init _of_ti_interface_clk_setup(struct device_node *node,
  35                                              const struct clk_hw_omap_ops *ops)
  36{
  37        struct clk *clk;
  38        struct clk_init_data init = { NULL };
  39        struct clk_hw_omap *clk_hw;
  40        const char *parent_name;
  41        u32 val;
  42
  43        clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
  44        if (!clk_hw)
  45                return;
  46
  47        clk_hw->hw.init = &init;
  48        clk_hw->ops = ops;
  49        clk_hw->flags = MEMMAP_ADDRESSING;
  50
  51        clk_hw->enable_reg = ti_clk_get_reg_addr(node, 0);
  52        if (!clk_hw->enable_reg)
  53                goto cleanup;
  54
  55        if (!of_property_read_u32(node, "ti,bit-shift", &val))
  56                clk_hw->enable_bit = val;
  57
  58        init.name = node->name;
  59        init.ops = &ti_interface_clk_ops;
  60        init.flags = 0;
  61
  62        parent_name = of_clk_get_parent_name(node, 0);
  63        if (!parent_name) {
  64                pr_err("%s must have a parent\n", node->name);
  65                goto cleanup;
  66        }
  67
  68        init.num_parents = 1;
  69        init.parent_names = &parent_name;
  70
  71        clk = clk_register(NULL, &clk_hw->hw);
  72
  73        if (!IS_ERR(clk)) {
  74                of_clk_add_provider(node, of_clk_src_simple_get, clk);
  75                omap2_init_clk_hw_omap_clocks(clk);
  76                return;
  77        }
  78
  79cleanup:
  80        kfree(clk_hw);
  81}
  82
  83static void __init of_ti_interface_clk_setup(struct device_node *node)
  84{
  85        _of_ti_interface_clk_setup(node, &clkhwops_iclk_wait);
  86}
  87CLK_OF_DECLARE(ti_interface_clk, "ti,omap3-interface-clock",
  88               of_ti_interface_clk_setup);
  89
  90static void __init of_ti_no_wait_interface_clk_setup(struct device_node *node)
  91{
  92        _of_ti_interface_clk_setup(node, &clkhwops_iclk);
  93}
  94CLK_OF_DECLARE(ti_no_wait_interface_clk, "ti,omap3-no-wait-interface-clock",
  95               of_ti_no_wait_interface_clk_setup);
  96
  97#ifdef CONFIG_ARCH_OMAP3
  98static void __init of_ti_hsotgusb_interface_clk_setup(struct device_node *node)
  99{
 100        _of_ti_interface_clk_setup(node,
 101                                   &clkhwops_omap3430es2_iclk_hsotgusb_wait);
 102}
 103CLK_OF_DECLARE(ti_hsotgusb_interface_clk, "ti,omap3-hsotgusb-interface-clock",
 104               of_ti_hsotgusb_interface_clk_setup);
 105
 106static void __init of_ti_dss_interface_clk_setup(struct device_node *node)
 107{
 108        _of_ti_interface_clk_setup(node,
 109                                   &clkhwops_omap3430es2_iclk_dss_usbhost_wait);
 110}
 111CLK_OF_DECLARE(ti_dss_interface_clk, "ti,omap3-dss-interface-clock",
 112               of_ti_dss_interface_clk_setup);
 113
 114static void __init of_ti_ssi_interface_clk_setup(struct device_node *node)
 115{
 116        _of_ti_interface_clk_setup(node, &clkhwops_omap3430es2_iclk_ssi_wait);
 117}
 118CLK_OF_DECLARE(ti_ssi_interface_clk, "ti,omap3-ssi-interface-clock",
 119               of_ti_ssi_interface_clk_setup);
 120
 121static void __init of_ti_am35xx_interface_clk_setup(struct device_node *node)
 122{
 123        _of_ti_interface_clk_setup(node, &clkhwops_am35xx_ipss_wait);
 124}
 125CLK_OF_DECLARE(ti_am35xx_interface_clk, "ti,am35xx-interface-clock",
 126               of_ti_am35xx_interface_clk_setup);
 127#endif
 128
 129#ifdef CONFIG_SOC_OMAP2430
 130static void __init of_ti_omap2430_interface_clk_setup(struct device_node *node)
 131{
 132        _of_ti_interface_clk_setup(node, &clkhwops_omap2430_i2chs_wait);
 133}
 134CLK_OF_DECLARE(ti_omap2430_interface_clk, "ti,omap2430-interface-clock",
 135               of_ti_omap2430_interface_clk_setup);
 136#endif
 137