diff options
Diffstat (limited to 'arch/arm/mach-pnx4008/clock.c')
-rw-r--r-- | arch/arm/mach-pnx4008/clock.c | 129 |
1 files changed, 51 insertions, 78 deletions
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index 285b22f631e9..f582ed2ec43c 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c | |||
@@ -767,6 +767,54 @@ static struct clk *onchip_clks[] = { | |||
767 | &uart6_ck, | 767 | &uart6_ck, |
768 | }; | 768 | }; |
769 | 769 | ||
770 | static int local_clk_enable(struct clk *clk) | ||
771 | { | ||
772 | int ret = 0; | ||
773 | |||
774 | if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate | ||
775 | && clk->user_rate) | ||
776 | ret = clk->set_rate(clk, clk->user_rate); | ||
777 | return ret; | ||
778 | } | ||
779 | |||
780 | static void local_clk_disable(struct clk *clk) | ||
781 | { | ||
782 | if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) | ||
783 | clk->set_rate(clk, 0); | ||
784 | } | ||
785 | |||
786 | static void local_clk_unuse(struct clk *clk) | ||
787 | { | ||
788 | if (clk->usecount > 0 && !(--clk->usecount)) { | ||
789 | local_clk_disable(clk); | ||
790 | if (clk->parent) | ||
791 | local_clk_unuse(clk->parent); | ||
792 | } | ||
793 | } | ||
794 | |||
795 | static int local_clk_use(struct clk *clk) | ||
796 | { | ||
797 | int ret = 0; | ||
798 | if (clk->usecount++ == 0) { | ||
799 | if (clk->parent) | ||
800 | ret = local_clk_use(clk->parent); | ||
801 | |||
802 | if (ret != 0) { | ||
803 | clk->usecount--; | ||
804 | goto out; | ||
805 | } | ||
806 | |||
807 | ret = local_clk_enable(clk); | ||
808 | |||
809 | if (ret != 0 && clk->parent) { | ||
810 | local_clk_unuse(clk->parent); | ||
811 | clk->usecount--; | ||
812 | } | ||
813 | } | ||
814 | out: | ||
815 | return ret; | ||
816 | } | ||
817 | |||
770 | static int local_set_rate(struct clk *clk, u32 rate) | 818 | static int local_set_rate(struct clk *clk, u32 rate) |
771 | { | 819 | { |
772 | int ret = -EINVAL; | 820 | int ret = -EINVAL; |
@@ -847,28 +895,12 @@ unsigned long clk_get_rate(struct clk *clk) | |||
847 | } | 895 | } |
848 | EXPORT_SYMBOL(clk_get_rate); | 896 | EXPORT_SYMBOL(clk_get_rate); |
849 | 897 | ||
850 | static int local_clk_enable(struct clk *clk) | ||
851 | { | ||
852 | int ret = 0; | ||
853 | |||
854 | if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate | ||
855 | && clk->user_rate) | ||
856 | ret = clk->set_rate(clk, clk->user_rate); | ||
857 | return ret; | ||
858 | } | ||
859 | |||
860 | static void local_clk_disable(struct clk *clk) | ||
861 | { | ||
862 | if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate) | ||
863 | clk->set_rate(clk, 0); | ||
864 | } | ||
865 | |||
866 | int clk_enable(struct clk *clk) | 898 | int clk_enable(struct clk *clk) |
867 | { | 899 | { |
868 | int ret = 0; | 900 | int ret = 0; |
869 | 901 | ||
870 | clock_lock(); | 902 | clock_lock(); |
871 | ret = local_clk_enable(clk); | 903 | ret = local_clk_use(clk); |
872 | clock_unlock(); | 904 | clock_unlock(); |
873 | return ret; | 905 | return ret; |
874 | } | 906 | } |
@@ -878,70 +910,11 @@ EXPORT_SYMBOL(clk_enable); | |||
878 | void clk_disable(struct clk *clk) | 910 | void clk_disable(struct clk *clk) |
879 | { | 911 | { |
880 | clock_lock(); | 912 | clock_lock(); |
881 | local_clk_disable(clk); | ||
882 | clock_unlock(); | ||
883 | } | ||
884 | |||
885 | EXPORT_SYMBOL(clk_disable); | ||
886 | |||
887 | static void local_clk_unuse(struct clk *clk) | ||
888 | { | ||
889 | if (clk->usecount > 0 && !(--clk->usecount)) { | ||
890 | local_clk_disable(clk); | ||
891 | if (clk->parent) | ||
892 | local_clk_unuse(clk->parent); | ||
893 | } | ||
894 | } | ||
895 | |||
896 | static int local_clk_use(struct clk *clk) | ||
897 | { | ||
898 | int ret = 0; | ||
899 | if (clk->usecount++ == 0) { | ||
900 | if (clk->parent) | ||
901 | ret = local_clk_use(clk->parent); | ||
902 | |||
903 | if (ret != 0) { | ||
904 | clk->usecount--; | ||
905 | goto out; | ||
906 | } | ||
907 | |||
908 | ret = local_clk_enable(clk); | ||
909 | |||
910 | if (ret != 0 && clk->parent) { | ||
911 | local_clk_unuse(clk->parent); | ||
912 | clk->usecount--; | ||
913 | } | ||
914 | } | ||
915 | out: | ||
916 | return ret; | ||
917 | } | ||
918 | |||
919 | /* The main purpose of clk_use ans clk_unuse functions | ||
920 | * is to control switching 13MHz oscillator and PLL1 (13'MHz), | ||
921 | * so that they are disabled whenever none of PLL2-5 is using them. | ||
922 | * Although in theory these functions should work with any clock, | ||
923 | * please use them only on PLL2 - PLL5 to avoid confusion. | ||
924 | */ | ||
925 | int clk_use(struct clk *clk) | ||
926 | { | ||
927 | int ret = 0; | ||
928 | |||
929 | clock_lock(); | ||
930 | ret = local_clk_use(clk); | ||
931 | clock_unlock(); | ||
932 | return ret; | ||
933 | } | ||
934 | EXPORT_SYMBOL(clk_use); | ||
935 | |||
936 | void clk_unuse(struct clk *clk) | ||
937 | { | ||
938 | |||
939 | clock_lock(); | ||
940 | local_clk_unuse(clk); | 913 | local_clk_unuse(clk); |
941 | clock_unlock(); | 914 | clock_unlock(); |
942 | } | 915 | } |
943 | 916 | ||
944 | EXPORT_SYMBOL(clk_unuse); | 917 | EXPORT_SYMBOL(clk_disable); |
945 | 918 | ||
946 | long clk_round_rate(struct clk *clk, unsigned long rate) | 919 | long clk_round_rate(struct clk *clk, unsigned long rate) |
947 | { | 920 | { |
@@ -995,7 +968,7 @@ static int __init clk_init(void) | |||
995 | __FUNCTION__, (*clkp)->name, (*clkp)->rate); | 968 | __FUNCTION__, (*clkp)->name, (*clkp)->rate); |
996 | } | 969 | } |
997 | 970 | ||
998 | clk_use(&ck_pll4); | 971 | local_clk_use(&ck_pll4); |
999 | 972 | ||
1000 | /* if ck_13MHz is not used, disable it. */ | 973 | /* if ck_13MHz is not used, disable it. */ |
1001 | if (ck_13MHz.usecount == 0) | 974 | if (ck_13MHz.usecount == 0) |