diff options
author | Mike Turquette <mturquette@ti.com> | 2012-11-07 16:14:47 -0500 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2012-11-12 21:18:51 -0500 |
commit | f9ae32a74f0242cbef76d9baa10993d707be1714 (patch) | |
tree | 4c9e616bd4a72879405b94b039ee26ca812bed14 /arch/arm/mach-omap2/clock.c | |
parent | f51e0f9862ccf8be71219763d51e7617b95faa10 (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.c | 784 |
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 | */ |
60 | static bool clkdm_control = true; | 56 | static bool clkdm_control = true; |
61 | 57 | ||
62 | static LIST_HEAD(clocks); | ||
63 | static DEFINE_MUTEX(clocks_mutex); | ||
64 | #ifndef CONFIG_COMMON_CLK | ||
65 | static DEFINE_SPINLOCK(clockfw_lock); | ||
66 | #endif | ||
67 | |||
68 | #ifdef CONFIG_COMMON_CLK | ||
69 | static LIST_HEAD(clk_hw_omap_clocks); | 58 | static 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 | ||
144 | static void _omap2_module_wait_ready(struct clk_hw_omap *clk) | 131 | static void _omap2_module_wait_ready(struct clk_hw_omap *clk) |
145 | #else | ||
146 | static 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 | ||
187 | void omap2_init_clk_clkdm(struct clk_hw *hw) | 166 | void 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 | ||
191 | void 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 | ||
252 | void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, | 222 | void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, |
253 | #else | ||
254 | void 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 | ||
285 | void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, | 251 | void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, |
286 | #else | ||
287 | void 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 | ||
609 | int 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 | |||
633 | void 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 | |||
655 | const 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 | |||
662 | const 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 | */ | ||
682 | void 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 | */ | ||
721 | int 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 | |||
764 | oce_err3: | ||
765 | if (clkdm_control && clk->clkdm) | ||
766 | clkdm_clk_disable(clk->clkdm, clk); | ||
767 | oce_err2: | ||
768 | if (clk->parent) | ||
769 | omap2_clk_disable(clk->parent); | ||
770 | oce_err1: | ||
771 | clk->usecount--; | ||
772 | |||
773 | return ret; | ||
774 | } | ||
775 | |||
776 | /* Given a clock and a rate apply a clock specific rounding function */ | ||
777 | long 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 */ | ||
786 | int 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 | |||
801 | int 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 | ||
817 | void 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 */ | ||
927 | int 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 | } | ||
941 | EXPORT_SYMBOL(clk_enable); | ||
942 | |||
943 | void 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 | |||
960 | out: | ||
961 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
962 | } | ||
963 | EXPORT_SYMBOL(clk_disable); | ||
964 | |||
965 | unsigned 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 | } | ||
979 | EXPORT_SYMBOL(clk_get_rate); | ||
980 | |||
981 | /* | ||
982 | * Optional clock functions defined in include/linux/clk.h | ||
983 | */ | ||
984 | |||
985 | long 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 | } | ||
999 | EXPORT_SYMBOL(clk_round_rate); | ||
1000 | |||
1001 | int 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 | } | ||
1017 | EXPORT_SYMBOL(clk_set_rate); | ||
1018 | |||
1019 | int 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 | } | ||
1039 | EXPORT_SYMBOL(clk_set_parent); | ||
1040 | |||
1041 | struct clk *clk_get_parent(struct clk *clk) | ||
1042 | { | ||
1043 | return clk->parent; | ||
1044 | } | ||
1045 | EXPORT_SYMBOL(clk_get_parent); | ||
1046 | |||
1047 | /* | ||
1048 | * OMAP specific clock functions shared between omap1 and omap2 | ||
1049 | */ | ||
1050 | |||
1051 | int __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 | */ | ||
1057 | static 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 */ | ||
1072 | unsigned 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 | */ | ||
1081 | unsigned 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 | |||
1088 | void 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 */ | ||
1100 | void 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 | |||
1111 | static 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 | */ | ||
1120 | void 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 | */ | ||
1138 | void clk_preinit(struct clk *clk) | ||
1139 | { | ||
1140 | INIT_LIST_HEAD(&clk->children); | ||
1141 | } | ||
1142 | |||
1143 | int 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 | } | ||
1167 | EXPORT_SYMBOL(clk_register); | ||
1168 | |||
1169 | void 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 | } | ||
1179 | EXPORT_SYMBOL(clk_unregister); | ||
1180 | |||
1181 | void 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 | */ | ||
1198 | struct 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 | |||
1217 | int 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 | |||
1233 | int 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 | */ | ||
1252 | static int clkll_enable_null(struct clk *clk) | ||
1253 | { | ||
1254 | return 0; | ||
1255 | } | ||
1256 | |||
1257 | static void clkll_disable_null(struct clk *clk) | ||
1258 | { | ||
1259 | } | ||
1260 | |||
1261 | const 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 | */ | ||
1271 | struct 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 | */ | ||
1284 | static 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 | } | ||
1305 | late_initcall(clk_disable_unused); | ||
1306 | late_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 | |||
1317 | static struct dentry *clk_debugfs_root; | ||
1318 | |||
1319 | static 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 | |||
1339 | static 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 | |||
1344 | static 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 | |||
1351 | static 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 | |||
1379 | err_out: | ||
1380 | debugfs_remove_recursive(c->dent); | ||
1381 | return err; | ||
1382 | } | ||
1383 | |||
1384 | static 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 | |||
1403 | static 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; | ||
1426 | err_out: | ||
1427 | debugfs_remove_recursive(clk_debugfs_root); | ||
1428 | return err; | ||
1429 | } | ||
1430 | late_initcall(clk_debugfs_init); | ||
1431 | |||
1432 | #endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */ | ||
1433 | #endif /* CONFIG_COMMON_CLK */ | ||