aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock.c
diff options
context:
space:
mode:
authorMike Turquette <mturquette@ti.com>2012-11-07 16:14:47 -0500
committerPaul Walmsley <paul@pwsan.com>2012-11-12 21:18:51 -0500
commitf9ae32a74f0242cbef76d9baa10993d707be1714 (patch)
tree4c9e616bd4a72879405b94b039ee26ca812bed14 /arch/arm/mach-omap2/clock.c
parentf51e0f9862ccf8be71219763d51e7617b95faa10 (diff)
ARM: OMAP2+: clock: Cleanup !CONFIG_COMMON_CLK parts
Clean all #ifdef's added to common clock code. This code is no longer needed due to migration to the common clock framework. Signed-off-by: Mike Turquette <mturquette@ti.com> [paul@pwsan.com: clean up new ifdefs added in clockdomain.c] Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r--arch/arm/mach-omap2/clock.c784
1 files changed, 0 insertions, 784 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 744e6eb17b26..e4ec3a69ee2e 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -20,11 +20,7 @@
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#ifdef CONFIG_COMMON_CLK
24#include <linux/clk-provider.h> 23#include <linux/clk-provider.h>
25#else
26#include <linux/clk.h>
27#endif
28#include <linux/io.h> 24#include <linux/io.h>
29#include <linux/bitops.h> 25#include <linux/bitops.h>
30 26
@@ -59,13 +55,6 @@ u16 cpu_mask;
59 */ 55 */
60static bool clkdm_control = true; 56static bool clkdm_control = true;
61 57
62static LIST_HEAD(clocks);
63static DEFINE_MUTEX(clocks_mutex);
64#ifndef CONFIG_COMMON_CLK
65static DEFINE_SPINLOCK(clockfw_lock);
66#endif
67
68#ifdef CONFIG_COMMON_CLK
69static LIST_HEAD(clk_hw_omap_clocks); 58static LIST_HEAD(clk_hw_omap_clocks);
70 59
71/* 60/*
@@ -88,7 +77,6 @@ unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw,
88 77
89 return parent_rate / oclk->fixed_div; 78 return parent_rate / oclk->fixed_div;
90} 79}
91#endif
92 80
93/* 81/*
94 * OMAP2+ specific clock functions 82 * OMAP2+ specific clock functions
@@ -140,11 +128,7 @@ static int _wait_idlest_generic(void __iomem *reg, u32 mask, u8 idlest,
140 * belong in the clock code and will be moved in the medium term to 128 * belong in the clock code and will be moved in the medium term to
141 * module-dependent code. No return value. 129 * module-dependent code. No return value.
142 */ 130 */
143#ifdef CONFIG_COMMON_CLK
144static void _omap2_module_wait_ready(struct clk_hw_omap *clk) 131static void _omap2_module_wait_ready(struct clk_hw_omap *clk)
145#else
146static void _omap2_module_wait_ready(struct clk *clk)
147#endif
148{ 132{
149 void __iomem *companion_reg, *idlest_reg; 133 void __iomem *companion_reg, *idlest_reg;
150 u8 other_bit, idlest_bit, idlest_val, idlest_reg_id; 134 u8 other_bit, idlest_bit, idlest_val, idlest_reg_id;
@@ -163,11 +147,7 @@ static void _omap2_module_wait_ready(struct clk *clk)
163 if (r) { 147 if (r) {
164 /* IDLEST register not in the CM module */ 148 /* IDLEST register not in the CM module */
165 _wait_idlest_generic(idlest_reg, (1 << idlest_bit), idlest_val, 149 _wait_idlest_generic(idlest_reg, (1 << idlest_bit), idlest_val,
166#ifdef CONFIG_COMMON_CLK
167 __clk_get_name(clk->hw.clk)); 150 __clk_get_name(clk->hw.clk));
168#else
169 clk->name);
170#endif
171 } else { 151 } else {
172 cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit); 152 cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit);
173 }; 153 };
@@ -183,25 +163,16 @@ static void _omap2_module_wait_ready(struct clk *clk)
183 * clockdomain pointer, and save it into the struct clk. Intended to be 163 * clockdomain pointer, and save it into the struct clk. Intended to be
184 * called during clk_register(). No return value. 164 * called during clk_register(). No return value.
185 */ 165 */
186#ifdef CONFIG_COMMON_CLK
187void omap2_init_clk_clkdm(struct clk_hw *hw) 166void omap2_init_clk_clkdm(struct clk_hw *hw)
188{ 167{
189 struct clk_hw_omap *clk = to_clk_hw_omap(hw); 168 struct clk_hw_omap *clk = to_clk_hw_omap(hw);
190#else
191void omap2_init_clk_clkdm(struct clk *clk)
192{
193#endif
194 struct clockdomain *clkdm; 169 struct clockdomain *clkdm;
195 const char *clk_name; 170 const char *clk_name;
196 171
197 if (!clk->clkdm_name) 172 if (!clk->clkdm_name)
198 return; 173 return;
199 174
200#ifdef CONFIG_COMMON_CLK
201 clk_name = __clk_get_name(hw->clk); 175 clk_name = __clk_get_name(hw->clk);
202#else
203 clk_name = __clk_get_name(clk);
204#endif
205 176
206 clkdm = clkdm_lookup(clk->clkdm_name); 177 clkdm = clkdm_lookup(clk->clkdm_name);
207 if (clkdm) { 178 if (clkdm) {
@@ -248,11 +219,7 @@ void __init omap2_clk_disable_clkdm_control(void)
248 * associate this type of code with per-module data structures to 219 * associate this type of code with per-module data structures to
249 * avoid this issue, and remove the casts. No return value. 220 * avoid this issue, and remove the casts. No return value.
250 */ 221 */
251#ifdef CONFIG_COMMON_CLK
252void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, 222void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
253#else
254void omap2_clk_dflt_find_companion(struct clk *clk,
255#endif
256 void __iomem **other_reg, u8 *other_bit) 223 void __iomem **other_reg, u8 *other_bit)
257{ 224{
258 u32 r; 225 u32 r;
@@ -281,11 +248,7 @@ void omap2_clk_dflt_find_companion(struct clk *clk,
281 * register address ID (e.g., that CM_FCLKEN2 corresponds to 248 * register address ID (e.g., that CM_FCLKEN2 corresponds to
282 * CM_IDLEST2). This is not true for all modules. No return value. 249 * CM_IDLEST2). This is not true for all modules. No return value.
283 */ 250 */
284#ifdef CONFIG_COMMON_CLK
285void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, 251void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
286#else
287void omap2_clk_dflt_find_idlest(struct clk *clk,
288#endif
289 void __iomem **idlest_reg, u8 *idlest_bit, u8 *idlest_val) 252 void __iomem **idlest_reg, u8 *idlest_bit, u8 *idlest_val)
290{ 253{
291 u32 r; 254 u32 r;
@@ -308,7 +271,6 @@ void omap2_clk_dflt_find_idlest(struct clk *clk,
308 271
309} 272}
310 273
311#ifdef CONFIG_COMMON_CLK
312/** 274/**
313 * omap2_dflt_clk_enable - enable a clock in the hardware 275 * omap2_dflt_clk_enable - enable a clock in the hardware
314 * @hw: struct clk_hw * of the clock to enable 276 * @hw: struct clk_hw * of the clock to enable
@@ -605,238 +567,6 @@ const struct clk_hw_omap_ops clkhwops_wait = {
605 .find_idlest = omap2_clk_dflt_find_idlest, 567 .find_idlest = omap2_clk_dflt_find_idlest,
606 .find_companion = omap2_clk_dflt_find_companion, 568 .find_companion = omap2_clk_dflt_find_companion,
607}; 569};
608#else
609int omap2_dflt_clk_enable(struct clk *clk)
610{
611 u32 v;
612
613 if (unlikely(clk->enable_reg == NULL)) {
614 pr_err("clock.c: Enable for %s without enable code\n",
615 clk->name);
616 return 0; /* REVISIT: -EINVAL */
617 }
618
619 v = __raw_readl(clk->enable_reg);
620 if (clk->flags & INVERT_ENABLE)
621 v &= ~(1 << clk->enable_bit);
622 else
623 v |= (1 << clk->enable_bit);
624 __raw_writel(v, clk->enable_reg);
625 v = __raw_readl(clk->enable_reg); /* OCP barrier */
626
627 if (clk->ops->find_idlest)
628 _omap2_module_wait_ready(clk);
629
630 return 0;
631}
632
633void omap2_dflt_clk_disable(struct clk *clk)
634{
635 u32 v;
636
637 if (!clk->enable_reg) {
638 /*
639 * 'Independent' here refers to a clock which is not
640 * controlled by its parent.
641 */
642 pr_err("clock: clk_disable called on independent clock %s which has no enable_reg\n", clk->name);
643 return;
644 }
645
646 v = __raw_readl(clk->enable_reg);
647 if (clk->flags & INVERT_ENABLE)
648 v |= (1 << clk->enable_bit);
649 else
650 v &= ~(1 << clk->enable_bit);
651 __raw_writel(v, clk->enable_reg);
652 /* No OCP barrier needed here since it is a disable operation */
653}
654
655const struct clkops clkops_omap2_dflt_wait = {
656 .enable = omap2_dflt_clk_enable,
657 .disable = omap2_dflt_clk_disable,
658 .find_companion = omap2_clk_dflt_find_companion,
659 .find_idlest = omap2_clk_dflt_find_idlest,
660};
661
662const struct clkops clkops_omap2_dflt = {
663 .enable = omap2_dflt_clk_enable,
664 .disable = omap2_dflt_clk_disable,
665};
666
667/**
668 * omap2_clk_disable - disable a clock, if the system is not using it
669 * @clk: struct clk * to disable
670 *
671 * Decrements the usecount on struct clk @clk. If there are no users
672 * left, call the clkops-specific clock disable function to disable it
673 * in hardware. If the clock is part of a clockdomain (which they all
674 * should be), request that the clockdomain be disabled. (It too has
675 * a usecount, and so will not be disabled in the hardware until it no
676 * longer has any users.) If the clock has a parent clock (most of
677 * them do), then call ourselves, recursing on the parent clock. This
678 * can cause an entire branch of the clock tree to be powered off by
679 * simply disabling one clock. Intended to be called with the clockfw_lock
680 * spinlock held. No return value.
681 */
682void omap2_clk_disable(struct clk *clk)
683{
684 if (clk->usecount == 0) {
685 WARN(1, "clock: %s: omap2_clk_disable() called, but usecount already 0?", clk->name);
686 return;
687 }
688
689 pr_debug("clock: %s: decrementing usecount\n", clk->name);
690
691 clk->usecount--;
692
693 if (clk->usecount > 0)
694 return;
695
696 pr_debug("clock: %s: disabling in hardware\n", clk->name);
697
698 if (clk->ops && clk->ops->disable) {
699 trace_clock_disable(clk->name, 0, smp_processor_id());
700 clk->ops->disable(clk);
701 }
702
703 if (clkdm_control && clk->clkdm)
704 clkdm_clk_disable(clk->clkdm, clk);
705
706 if (clk->parent)
707 omap2_clk_disable(clk->parent);
708}
709
710/**
711 * omap2_clk_enable - request that the system enable a clock
712 * @clk: struct clk * to enable
713 *
714 * Increments the usecount on struct clk @clk. If there were no users
715 * previously, then recurse up the clock tree, enabling all of the
716 * clock's parents and all of the parent clockdomains, and finally,
717 * enabling @clk's clockdomain, and @clk itself. Intended to be
718 * called with the clockfw_lock spinlock held. Returns 0 upon success
719 * or a negative error code upon failure.
720 */
721int omap2_clk_enable(struct clk *clk)
722{
723 int ret;
724
725 pr_debug("clock: %s: incrementing usecount\n", clk->name);
726
727 clk->usecount++;
728
729 if (clk->usecount > 1)
730 return 0;
731
732 pr_debug("clock: %s: enabling in hardware\n", clk->name);
733
734 if (clk->parent) {
735 ret = omap2_clk_enable(clk->parent);
736 if (ret) {
737 WARN(1, "clock: %s: could not enable parent %s: %d\n",
738 clk->name, clk->parent->name, ret);
739 goto oce_err1;
740 }
741 }
742
743 if (clkdm_control && clk->clkdm) {
744 ret = clkdm_clk_enable(clk->clkdm, clk);
745 if (ret) {
746 WARN(1, "clock: %s: could not enable clockdomain %s: %d\n",
747 clk->name, clk->clkdm->name, ret);
748 goto oce_err2;
749 }
750 }
751
752 if (clk->ops && clk->ops->enable) {
753 trace_clock_enable(clk->name, 1, smp_processor_id());
754 ret = clk->ops->enable(clk);
755 if (ret) {
756 WARN(1, "clock: %s: could not enable: %d\n",
757 clk->name, ret);
758 goto oce_err3;
759 }
760 }
761
762 return 0;
763
764oce_err3:
765 if (clkdm_control && clk->clkdm)
766 clkdm_clk_disable(clk->clkdm, clk);
767oce_err2:
768 if (clk->parent)
769 omap2_clk_disable(clk->parent);
770oce_err1:
771 clk->usecount--;
772
773 return ret;
774}
775
776/* Given a clock and a rate apply a clock specific rounding function */
777long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
778{
779 if (clk->round_rate)
780 return clk->round_rate(clk, rate);
781
782 return clk->rate;
783}
784
785/* Set the clock rate for a clock source */
786int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
787{
788 int ret = -EINVAL;
789
790 pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate);
791
792 /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
793 if (clk->set_rate) {
794 trace_clock_set_rate(clk->name, rate, smp_processor_id());
795 ret = clk->set_rate(clk, rate);
796 }
797
798 return ret;
799}
800
801int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
802{
803 if (!clk->clksel)
804 return -EINVAL;
805
806 if (clk->parent == new_parent)
807 return 0;
808
809 return omap2_clksel_set_parent(clk, new_parent);
810}
811
812/*
813 * OMAP2+ clock reset and init functions
814 */
815
816#ifdef CONFIG_OMAP_RESET_CLOCKS
817void omap2_clk_disable_unused(struct clk *clk)
818{
819 u32 regval32, v;
820
821 v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0;
822
823 regval32 = __raw_readl(clk->enable_reg);
824 if ((regval32 & (1 << clk->enable_bit)) == v)
825 return;
826
827 pr_debug("Disabling unused clock \"%s\"\n", clk->name);
828 if (cpu_is_omap34xx()) {
829 omap2_clk_enable(clk);
830 omap2_clk_disable(clk);
831 } else {
832 clk->ops->disable(clk);
833 }
834 if (clk->clkdm != NULL)
835 pwrdm_state_switch(clk->clkdm->pwrdm.ptr);
836}
837#endif
838
839#endif /* CONFIG_COMMON_CLK */
840 570
841/** 571/**
842 * omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument 572 * omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument
@@ -874,10 +604,6 @@ int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name)
874 } 604 }
875 605
876 calibrate_delay(); 606 calibrate_delay();
877#ifndef CONFIG_COMMON_CLK
878 recalculate_root_clocks();
879#endif
880
881 clk_put(mpurate_ck); 607 clk_put(mpurate_ck);
882 608
883 return 0; 609 return 0;
@@ -921,513 +647,3 @@ void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name,
921 (clk_get_rate(core_ck) / 1000000), 647 (clk_get_rate(core_ck) / 1000000),
922 (clk_get_rate(mpu_ck) / 1000000)); 648 (clk_get_rate(mpu_ck) / 1000000));
923} 649}
924
925#ifndef CONFIG_COMMON_CLK
926/* Common data */
927int clk_enable(struct clk *clk)
928{
929 unsigned long flags;
930 int ret;
931
932 if (clk == NULL || IS_ERR(clk))
933 return -EINVAL;
934
935 spin_lock_irqsave(&clockfw_lock, flags);
936 ret = omap2_clk_enable(clk);
937 spin_unlock_irqrestore(&clockfw_lock, flags);
938
939 return ret;
940}
941EXPORT_SYMBOL(clk_enable);
942
943void clk_disable(struct clk *clk)
944{
945 unsigned long flags;
946
947 if (clk == NULL || IS_ERR(clk))
948 return;
949
950 spin_lock_irqsave(&clockfw_lock, flags);
951 if (clk->usecount == 0) {
952 pr_err("Trying disable clock %s with 0 usecount\n",
953 clk->name);
954 WARN_ON(1);
955 goto out;
956 }
957
958 omap2_clk_disable(clk);
959
960out:
961 spin_unlock_irqrestore(&clockfw_lock, flags);
962}
963EXPORT_SYMBOL(clk_disable);
964
965unsigned long clk_get_rate(struct clk *clk)
966{
967 unsigned long flags;
968 unsigned long ret;
969
970 if (clk == NULL || IS_ERR(clk))
971 return 0;
972
973 spin_lock_irqsave(&clockfw_lock, flags);
974 ret = clk->rate;
975 spin_unlock_irqrestore(&clockfw_lock, flags);
976
977 return ret;
978}
979EXPORT_SYMBOL(clk_get_rate);
980
981/*
982 * Optional clock functions defined in include/linux/clk.h
983 */
984
985long clk_round_rate(struct clk *clk, unsigned long rate)
986{
987 unsigned long flags;
988 long ret;
989
990 if (clk == NULL || IS_ERR(clk))
991 return 0;
992
993 spin_lock_irqsave(&clockfw_lock, flags);
994 ret = omap2_clk_round_rate(clk, rate);
995 spin_unlock_irqrestore(&clockfw_lock, flags);
996
997 return ret;
998}
999EXPORT_SYMBOL(clk_round_rate);
1000
1001int clk_set_rate(struct clk *clk, unsigned long rate)
1002{
1003 unsigned long flags;
1004 int ret = -EINVAL;
1005
1006 if (clk == NULL || IS_ERR(clk))
1007 return ret;
1008
1009 spin_lock_irqsave(&clockfw_lock, flags);
1010 ret = omap2_clk_set_rate(clk, rate);
1011 if (ret == 0)
1012 propagate_rate(clk);
1013 spin_unlock_irqrestore(&clockfw_lock, flags);
1014
1015 return ret;
1016}
1017EXPORT_SYMBOL(clk_set_rate);
1018
1019int clk_set_parent(struct clk *clk, struct clk *parent)
1020{
1021 unsigned long flags;
1022 int ret = -EINVAL;
1023
1024 if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
1025 return ret;
1026
1027 spin_lock_irqsave(&clockfw_lock, flags);
1028 if (clk->usecount == 0) {
1029 ret = omap2_clk_set_parent(clk, parent);
1030 if (ret == 0)
1031 propagate_rate(clk);
1032 } else {
1033 ret = -EBUSY;
1034 }
1035 spin_unlock_irqrestore(&clockfw_lock, flags);
1036
1037 return ret;
1038}
1039EXPORT_SYMBOL(clk_set_parent);
1040
1041struct clk *clk_get_parent(struct clk *clk)
1042{
1043 return clk->parent;
1044}
1045EXPORT_SYMBOL(clk_get_parent);
1046
1047/*
1048 * OMAP specific clock functions shared between omap1 and omap2
1049 */
1050
1051int __initdata mpurate;
1052
1053/*
1054 * By default we use the rate set by the bootloader.
1055 * You can override this with mpurate= cmdline option.
1056 */
1057static int __init omap_clk_setup(char *str)
1058{
1059 get_option(&str, &mpurate);
1060
1061 if (!mpurate)
1062 return 1;
1063
1064 if (mpurate < 1000)
1065 mpurate *= 1000000;
1066
1067 return 1;
1068}
1069__setup("mpurate=", omap_clk_setup);
1070
1071/* Used for clocks that always have same value as the parent clock */
1072unsigned long followparent_recalc(struct clk *clk)
1073{
1074 return clk->parent->rate;
1075}
1076
1077/*
1078 * Used for clocks that have the same value as the parent clock,
1079 * divided by some factor
1080 */
1081unsigned long omap_fixed_divisor_recalc(struct clk *clk)
1082{
1083 WARN_ON(!clk->fixed_div);
1084
1085 return clk->parent->rate / clk->fixed_div;
1086}
1087
1088void clk_reparent(struct clk *child, struct clk *parent)
1089{
1090 list_del_init(&child->sibling);
1091 if (parent)
1092 list_add(&child->sibling, &parent->children);
1093 child->parent = parent;
1094
1095 /* now do the debugfs renaming to reattach the child
1096 to the proper parent */
1097}
1098
1099/* Propagate rate to children */
1100void propagate_rate(struct clk *tclk)
1101{
1102 struct clk *clkp;
1103
1104 list_for_each_entry(clkp, &tclk->children, sibling) {
1105 if (clkp->recalc)
1106 clkp->rate = clkp->recalc(clkp);
1107 propagate_rate(clkp);
1108 }
1109}
1110
1111static LIST_HEAD(root_clks);
1112
1113/**
1114 * recalculate_root_clocks - recalculate and propagate all root clocks
1115 *
1116 * Recalculates all root clocks (clocks with no parent), which if the
1117 * clock's .recalc is set correctly, should also propagate their rates.
1118 * Called at init.
1119 */
1120void recalculate_root_clocks(void)
1121{
1122 struct clk *clkp;
1123
1124 list_for_each_entry(clkp, &root_clks, sibling) {
1125 if (clkp->recalc)
1126 clkp->rate = clkp->recalc(clkp);
1127 propagate_rate(clkp);
1128 }
1129}
1130
1131/**
1132 * clk_preinit - initialize any fields in the struct clk before clk init
1133 * @clk: struct clk * to initialize
1134 *
1135 * Initialize any struct clk fields needed before normal clk initialization
1136 * can run. No return value.
1137 */
1138void clk_preinit(struct clk *clk)
1139{
1140 INIT_LIST_HEAD(&clk->children);
1141}
1142
1143int clk_register(struct clk *clk)
1144{
1145 if (clk == NULL || IS_ERR(clk))
1146 return -EINVAL;
1147
1148 /*
1149 * trap out already registered clocks
1150 */
1151 if (clk->node.next || clk->node.prev)
1152 return 0;
1153
1154 mutex_lock(&clocks_mutex);
1155 if (clk->parent)
1156 list_add(&clk->sibling, &clk->parent->children);
1157 else
1158 list_add(&clk->sibling, &root_clks);
1159
1160 list_add(&clk->node, &clocks);
1161 if (clk->init)
1162 clk->init(clk);
1163 mutex_unlock(&clocks_mutex);
1164
1165 return 0;
1166}
1167EXPORT_SYMBOL(clk_register);
1168
1169void clk_unregister(struct clk *clk)
1170{
1171 if (clk == NULL || IS_ERR(clk))
1172 return;
1173
1174 mutex_lock(&clocks_mutex);
1175 list_del(&clk->sibling);
1176 list_del(&clk->node);
1177 mutex_unlock(&clocks_mutex);
1178}
1179EXPORT_SYMBOL(clk_unregister);
1180
1181void clk_enable_init_clocks(void)
1182{
1183 struct clk *clkp;
1184
1185 list_for_each_entry(clkp, &clocks, node)
1186 if (clkp->flags & ENABLE_ON_INIT)
1187 clk_enable(clkp);
1188}
1189
1190/**
1191 * omap_clk_get_by_name - locate OMAP struct clk by its name
1192 * @name: name of the struct clk to locate
1193 *
1194 * Locate an OMAP struct clk by its name. Assumes that struct clk
1195 * names are unique. Returns NULL if not found or a pointer to the
1196 * struct clk if found.
1197 */
1198struct clk *omap_clk_get_by_name(const char *name)
1199{
1200 struct clk *c;
1201 struct clk *ret = NULL;
1202
1203 mutex_lock(&clocks_mutex);
1204
1205 list_for_each_entry(c, &clocks, node) {
1206 if (!strcmp(c->name, name)) {
1207 ret = c;
1208 break;
1209 }
1210 }
1211
1212 mutex_unlock(&clocks_mutex);
1213
1214 return ret;
1215}
1216
1217int omap_clk_enable_autoidle_all(void)
1218{
1219 struct clk *c;
1220 unsigned long flags;
1221
1222 spin_lock_irqsave(&clockfw_lock, flags);
1223
1224 list_for_each_entry(c, &clocks, node)
1225 if (c->ops->allow_idle)
1226 c->ops->allow_idle(c);
1227
1228 spin_unlock_irqrestore(&clockfw_lock, flags);
1229
1230 return 0;
1231}
1232
1233int omap_clk_disable_autoidle_all(void)
1234{
1235 struct clk *c;
1236 unsigned long flags;
1237
1238 spin_lock_irqsave(&clockfw_lock, flags);
1239
1240 list_for_each_entry(c, &clocks, node)
1241 if (c->ops->deny_idle)
1242 c->ops->deny_idle(c);
1243
1244 spin_unlock_irqrestore(&clockfw_lock, flags);
1245
1246 return 0;
1247}
1248
1249/*
1250 * Low level helpers
1251 */
1252static int clkll_enable_null(struct clk *clk)
1253{
1254 return 0;
1255}
1256
1257static void clkll_disable_null(struct clk *clk)
1258{
1259}
1260
1261const struct clkops clkops_null = {
1262 .enable = clkll_enable_null,
1263 .disable = clkll_disable_null,
1264};
1265
1266/*
1267 * Dummy clock
1268 *
1269 * Used for clock aliases that are needed on some OMAPs, but not others
1270 */
1271struct clk dummy_ck = {
1272 .name = "dummy",
1273 .ops = &clkops_null,
1274};
1275
1276/*
1277 *
1278 */
1279
1280#ifdef CONFIG_OMAP_RESET_CLOCKS
1281/*
1282 * Disable any unused clocks left on by the bootloader
1283 */
1284static int __init clk_disable_unused(void)
1285{
1286 struct clk *ck;
1287 unsigned long flags;
1288
1289 pr_info("clock: disabling unused clocks to save power\n");
1290
1291 spin_lock_irqsave(&clockfw_lock, flags);
1292 list_for_each_entry(ck, &clocks, node) {
1293 if (ck->ops == &clkops_null)
1294 continue;
1295
1296 if (ck->usecount > 0 || !ck->enable_reg)
1297 continue;
1298
1299 omap2_clk_disable_unused(ck);
1300 }
1301 spin_unlock_irqrestore(&clockfw_lock, flags);
1302
1303 return 0;
1304}
1305late_initcall(clk_disable_unused);
1306late_initcall(omap_clk_enable_autoidle_all);
1307#endif
1308
1309#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
1310/*
1311 * debugfs support to trace clock tree hierarchy and attributes
1312 */
1313
1314#include <linux/debugfs.h>
1315#include <linux/seq_file.h>
1316
1317static struct dentry *clk_debugfs_root;
1318
1319static int clk_dbg_show_summary(struct seq_file *s, void *unused)
1320{
1321 struct clk *c;
1322 struct clk *pa;
1323
1324 mutex_lock(&clocks_mutex);
1325 seq_printf(s, "%-30s %-30s %-10s %s\n",
1326 "clock-name", "parent-name", "rate", "use-count");
1327
1328 list_for_each_entry(c, &clocks, node) {
1329 pa = c->parent;
1330 seq_printf(s, "%-30s %-30s %-10lu %d\n",
1331 c->name, pa ? pa->name : "none", c->rate,
1332 c->usecount);
1333 }
1334 mutex_unlock(&clocks_mutex);
1335
1336 return 0;
1337}
1338
1339static int clk_dbg_open(struct inode *inode, struct file *file)
1340{
1341 return single_open(file, clk_dbg_show_summary, inode->i_private);
1342}
1343
1344static const struct file_operations debug_clock_fops = {
1345 .open = clk_dbg_open,
1346 .read = seq_read,
1347 .llseek = seq_lseek,
1348 .release = single_release,
1349};
1350
1351static int clk_debugfs_register_one(struct clk *c)
1352{
1353 int err;
1354 struct dentry *d;
1355 struct clk *pa = c->parent;
1356
1357 d = debugfs_create_dir(c->name, pa ? pa->dent : clk_debugfs_root);
1358 if (!d)
1359 return -ENOMEM;
1360 c->dent = d;
1361
1362 d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount);
1363 if (!d) {
1364 err = -ENOMEM;
1365 goto err_out;
1366 }
1367 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
1368 if (!d) {
1369 err = -ENOMEM;
1370 goto err_out;
1371 }
1372 d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
1373 if (!d) {
1374 err = -ENOMEM;
1375 goto err_out;
1376 }
1377 return 0;
1378
1379err_out:
1380 debugfs_remove_recursive(c->dent);
1381 return err;
1382}
1383
1384static int clk_debugfs_register(struct clk *c)
1385{
1386 int err;
1387 struct clk *pa = c->parent;
1388
1389 if (pa && !pa->dent) {
1390 err = clk_debugfs_register(pa);
1391 if (err)
1392 return err;
1393 }
1394
1395 if (!c->dent) {
1396 err = clk_debugfs_register_one(c);
1397 if (err)
1398 return err;
1399 }
1400 return 0;
1401}
1402
1403static int __init clk_debugfs_init(void)
1404{
1405 struct clk *c;
1406 struct dentry *d;
1407 int err;
1408
1409 d = debugfs_create_dir("clock", NULL);
1410 if (!d)
1411 return -ENOMEM;
1412 clk_debugfs_root = d;
1413
1414 list_for_each_entry(c, &clocks, node) {
1415 err = clk_debugfs_register(c);
1416 if (err)
1417 goto err_out;
1418 }
1419
1420 d = debugfs_create_file("summary", S_IRUGO,
1421 d, NULL, &debug_clock_fops);
1422 if (!d)
1423 return -ENOMEM;
1424
1425 return 0;
1426err_out:
1427 debugfs_remove_recursive(clk_debugfs_root);
1428 return err;
1429}
1430late_initcall(clk_debugfs_init);
1431
1432#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */
1433#endif /* CONFIG_COMMON_CLK */