143 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * OMAP interface clock support4 *5 * Copyright (C) 2013 Texas Instruments, Inc.6 *7 * Tero Kristo <t-kristo@ti.com>8 */9 10#include <linux/clk-provider.h>11#include <linux/slab.h>12#include <linux/of.h>13#include <linux/of_address.h>14#include <linux/clk/ti.h>15#include "clock.h"16 17#undef pr_fmt18#define pr_fmt(fmt) "%s: " fmt, __func__19 20static const struct clk_ops ti_interface_clk_ops = {21 .init = &omap2_init_clk_clkdm,22 .enable = &omap2_dflt_clk_enable,23 .disable = &omap2_dflt_clk_disable,24 .is_enabled = &omap2_dflt_clk_is_enabled,25};26 27static struct clk *_register_interface(struct device_node *node,28 const char *name,29 const char *parent_name,30 struct clk_omap_reg *reg, u8 bit_idx,31 const struct clk_hw_omap_ops *ops)32{33 struct clk_init_data init = { NULL };34 struct clk_hw_omap *clk_hw;35 struct clk *clk;36 37 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);38 if (!clk_hw)39 return ERR_PTR(-ENOMEM);40 41 clk_hw->hw.init = &init;42 clk_hw->ops = ops;43 memcpy(&clk_hw->enable_reg, reg, sizeof(*reg));44 clk_hw->enable_bit = bit_idx;45 46 init.name = name;47 init.ops = &ti_interface_clk_ops;48 init.flags = 0;49 50 init.num_parents = 1;51 init.parent_names = &parent_name;52 53 clk = of_ti_clk_register_omap_hw(node, &clk_hw->hw, name);54 55 if (IS_ERR(clk))56 kfree(clk_hw);57 58 return clk;59}60 61static void __init _of_ti_interface_clk_setup(struct device_node *node,62 const struct clk_hw_omap_ops *ops)63{64 struct clk *clk;65 const char *parent_name;66 struct clk_omap_reg reg;67 u8 enable_bit = 0;68 const char *name;69 70 if (ti_clk_get_reg_addr(node, 0, ®))71 return;72 73 enable_bit = reg.bit;74 75 parent_name = of_clk_get_parent_name(node, 0);76 if (!parent_name) {77 pr_err("%pOFn must have a parent\n", node);78 return;79 }80 81 name = ti_dt_clk_name(node);82 clk = _register_interface(node, name, parent_name, ®,83 enable_bit, ops);84 85 if (!IS_ERR(clk))86 of_clk_add_provider(node, of_clk_src_simple_get, clk);87}88 89static void __init of_ti_interface_clk_setup(struct device_node *node)90{91 _of_ti_interface_clk_setup(node, &clkhwops_iclk_wait);92}93CLK_OF_DECLARE(ti_interface_clk, "ti,omap3-interface-clock",94 of_ti_interface_clk_setup);95 96static void __init of_ti_no_wait_interface_clk_setup(struct device_node *node)97{98 _of_ti_interface_clk_setup(node, &clkhwops_iclk);99}100CLK_OF_DECLARE(ti_no_wait_interface_clk, "ti,omap3-no-wait-interface-clock",101 of_ti_no_wait_interface_clk_setup);102 103#ifdef CONFIG_ARCH_OMAP3104static void __init of_ti_hsotgusb_interface_clk_setup(struct device_node *node)105{106 _of_ti_interface_clk_setup(node,107 &clkhwops_omap3430es2_iclk_hsotgusb_wait);108}109CLK_OF_DECLARE(ti_hsotgusb_interface_clk, "ti,omap3-hsotgusb-interface-clock",110 of_ti_hsotgusb_interface_clk_setup);111 112static void __init of_ti_dss_interface_clk_setup(struct device_node *node)113{114 _of_ti_interface_clk_setup(node,115 &clkhwops_omap3430es2_iclk_dss_usbhost_wait);116}117CLK_OF_DECLARE(ti_dss_interface_clk, "ti,omap3-dss-interface-clock",118 of_ti_dss_interface_clk_setup);119 120static void __init of_ti_ssi_interface_clk_setup(struct device_node *node)121{122 _of_ti_interface_clk_setup(node, &clkhwops_omap3430es2_iclk_ssi_wait);123}124CLK_OF_DECLARE(ti_ssi_interface_clk, "ti,omap3-ssi-interface-clock",125 of_ti_ssi_interface_clk_setup);126 127static void __init of_ti_am35xx_interface_clk_setup(struct device_node *node)128{129 _of_ti_interface_clk_setup(node, &clkhwops_am35xx_ipss_wait);130}131CLK_OF_DECLARE(ti_am35xx_interface_clk, "ti,am35xx-interface-clock",132 of_ti_am35xx_interface_clk_setup);133#endif134 135#ifdef CONFIG_SOC_OMAP2430136static void __init of_ti_omap2430_interface_clk_setup(struct device_node *node)137{138 _of_ti_interface_clk_setup(node, &clkhwops_omap2430_i2chs_wait);139}140CLK_OF_DECLARE(ti_omap2430_interface_clk, "ti,omap2430-interface-clock",141 of_ti_omap2430_interface_clk_setup);142#endif143