diff options
author | Benoit Cousson <b-cousson@ti.com> | 2011-07-10 07:56:54 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2011-07-10 07:56:54 -0400 |
commit | 113a74137f5c85f2c7914e78350f70247ef9447c (patch) | |
tree | f2eaea43a00c23424aa27a418f6a37a81caa8d83 /arch/arm/mach-omap2 | |
parent | a5122ff8ceb2b1f207965a3608d3da3af832e513 (diff) |
OMAP2+: clockdomain: Add 2 APIs to control clockdomain from hwmod framework
Duplicate the existing API for clockdomain enable from clock to enable
a clock domain from hwmod framework.
This will be needed when the hwmod framework will move from the current
clock centric approach to the module based approach.
These APIs are returning 0 for the moment for OMAP2 and OMAP3 until
their hwmods are updated with the clksm attribute.
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/clockdomain.c | 142 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clockdomain.h | 3 |
2 files changed, 109 insertions, 36 deletions
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 4fbbbfcc9ba2..5a57de563b30 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c | |||
@@ -796,7 +796,50 @@ void clkdm_deny_idle(struct clockdomain *clkdm) | |||
796 | } | 796 | } |
797 | 797 | ||
798 | 798 | ||
799 | /* Clockdomain-to-clock framework interface code */ | 799 | /* Clockdomain-to-clock/hwmod framework interface code */ |
800 | |||
801 | static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) | ||
802 | { | ||
803 | if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) | ||
804 | return -EINVAL; | ||
805 | |||
806 | /* | ||
807 | * For arch's with no autodeps, clkcm_clk_enable | ||
808 | * should be called for every clock instance or hwmod that is | ||
809 | * enabled, so the clkdm can be force woken up. | ||
810 | */ | ||
811 | if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) | ||
812 | return 0; | ||
813 | |||
814 | arch_clkdm->clkdm_clk_enable(clkdm); | ||
815 | pwrdm_wait_transition(clkdm->pwrdm.ptr); | ||
816 | pwrdm_clkdm_state_switch(clkdm); | ||
817 | |||
818 | pr_debug("clockdomain: clkdm %s: enabled\n", clkdm->name); | ||
819 | |||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm) | ||
824 | { | ||
825 | if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) | ||
826 | return -EINVAL; | ||
827 | |||
828 | if (atomic_read(&clkdm->usecount) == 0) { | ||
829 | WARN_ON(1); /* underflow */ | ||
830 | return -ERANGE; | ||
831 | } | ||
832 | |||
833 | if (atomic_dec_return(&clkdm->usecount) > 0) | ||
834 | return 0; | ||
835 | |||
836 | arch_clkdm->clkdm_clk_disable(clkdm); | ||
837 | pwrdm_clkdm_state_switch(clkdm); | ||
838 | |||
839 | pr_debug("clockdomain: clkdm %s: disabled\n", clkdm->name); | ||
840 | |||
841 | return 0; | ||
842 | } | ||
800 | 843 | ||
801 | /** | 844 | /** |
802 | * clkdm_clk_enable - add an enabled downstream clock to this clkdm | 845 | * clkdm_clk_enable - add an enabled downstream clock to this clkdm |
@@ -819,24 +862,10 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) | |||
819 | * downstream clocks for debugging purposes? | 862 | * downstream clocks for debugging purposes? |
820 | */ | 863 | */ |
821 | 864 | ||
822 | if (!clkdm || !clk) | 865 | if (!clk) |
823 | return -EINVAL; | 866 | return -EINVAL; |
824 | 867 | ||
825 | if (!arch_clkdm || !arch_clkdm->clkdm_clk_enable) | 868 | return _clkdm_clk_hwmod_enable(clkdm); |
826 | return -EINVAL; | ||
827 | |||
828 | if (atomic_inc_return(&clkdm->usecount) > 1) | ||
829 | return 0; | ||
830 | |||
831 | /* Clockdomain now has one enabled downstream clock */ | ||
832 | |||
833 | pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name, | ||
834 | clk->name); | ||
835 | |||
836 | arch_clkdm->clkdm_clk_enable(clkdm); | ||
837 | pwrdm_clkdm_state_switch(clkdm); | ||
838 | |||
839 | return 0; | ||
840 | } | 869 | } |
841 | 870 | ||
842 | /** | 871 | /** |
@@ -849,9 +878,8 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) | |||
849 | * clockdomain usecount goes to 0, put the clockdomain to sleep | 878 | * clockdomain usecount goes to 0, put the clockdomain to sleep |
850 | * (software-supervised mode) or remove the clkdm autodependencies | 879 | * (software-supervised mode) or remove the clkdm autodependencies |
851 | * (hardware-supervised mode). Returns -EINVAL if passed null | 880 | * (hardware-supervised mode). Returns -EINVAL if passed null |
852 | * pointers; -ERANGE if the @clkdm usecount underflows and debugging | 881 | * pointers; -ERANGE if the @clkdm usecount underflows; or returns 0 |
853 | * is enabled; or returns 0 upon success or if the clockdomain is in | 882 | * upon success or if the clockdomain is in hwsup idle mode. |
854 | * hwsup idle mode. | ||
855 | */ | 883 | */ |
856 | int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) | 884 | int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) |
857 | { | 885 | { |
@@ -860,30 +888,72 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) | |||
860 | * downstream clocks for debugging purposes? | 888 | * downstream clocks for debugging purposes? |
861 | */ | 889 | */ |
862 | 890 | ||
863 | if (!clkdm || !clk) | 891 | if (!clk) |
864 | return -EINVAL; | 892 | return -EINVAL; |
865 | 893 | ||
866 | if (!arch_clkdm || !arch_clkdm->clkdm_clk_disable) | 894 | return _clkdm_clk_hwmod_disable(clkdm); |
895 | } | ||
896 | |||
897 | /** | ||
898 | * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm | ||
899 | * @clkdm: struct clockdomain * | ||
900 | * @oh: struct omap_hwmod * of the enabled downstream hwmod | ||
901 | * | ||
902 | * Increment the usecount of the clockdomain @clkdm and ensure that it | ||
903 | * is awake before @oh is enabled. Intended to be called by | ||
904 | * module_enable() code. | ||
905 | * If the clockdomain is in software-supervised idle mode, force the | ||
906 | * clockdomain to wake. If the clockdomain is in hardware-supervised idle | ||
907 | * mode, add clkdm-pwrdm autodependencies, to ensure that devices in the | ||
908 | * clockdomain can be read from/written to by on-chip processors. | ||
909 | * Returns -EINVAL if passed null pointers; | ||
910 | * returns 0 upon success or if the clockdomain is in hwsup idle mode. | ||
911 | */ | ||
912 | int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh) | ||
913 | { | ||
914 | /* The clkdm attribute does not exist yet prior OMAP4 */ | ||
915 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | ||
916 | return 0; | ||
917 | |||
918 | /* | ||
919 | * XXX Rewrite this code to maintain a list of enabled | ||
920 | * downstream hwmods for debugging purposes? | ||
921 | */ | ||
922 | |||
923 | if (!oh) | ||
867 | return -EINVAL; | 924 | return -EINVAL; |
868 | 925 | ||
869 | #ifdef DEBUG | 926 | return _clkdm_clk_hwmod_enable(clkdm); |
870 | if (atomic_read(&clkdm->usecount) == 0) { | 927 | } |
871 | WARN_ON(1); /* underflow */ | ||
872 | return -ERANGE; | ||
873 | } | ||
874 | #endif | ||
875 | 928 | ||
876 | if (atomic_dec_return(&clkdm->usecount) > 0) | 929 | /** |
930 | * clkdm_hwmod_disable - remove an enabled downstream hwmod from this clkdm | ||
931 | * @clkdm: struct clockdomain * | ||
932 | * @oh: struct omap_hwmod * of the disabled downstream hwmod | ||
933 | * | ||
934 | * Decrement the usecount of this clockdomain @clkdm when @oh is | ||
935 | * disabled. Intended to be called by module_disable() code. | ||
936 | * If the clockdomain usecount goes to 0, put the clockdomain to sleep | ||
937 | * (software-supervised mode) or remove the clkdm autodependencies | ||
938 | * (hardware-supervised mode). | ||
939 | * Returns -EINVAL if passed null pointers; -ERANGE if the @clkdm usecount | ||
940 | * underflows; or returns 0 upon success or if the clockdomain is in hwsup | ||
941 | * idle mode. | ||
942 | */ | ||
943 | int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh) | ||
944 | { | ||
945 | /* The clkdm attribute does not exist yet prior OMAP4 */ | ||
946 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | ||
877 | return 0; | 947 | return 0; |
878 | 948 | ||
879 | /* All downstream clocks of this clockdomain are now disabled */ | 949 | /* |
880 | 950 | * XXX Rewrite this code to maintain a list of enabled | |
881 | pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name, | 951 | * downstream hwmods for debugging purposes? |
882 | clk->name); | 952 | */ |
883 | 953 | ||
884 | arch_clkdm->clkdm_clk_disable(clkdm); | 954 | if (!oh) |
885 | pwrdm_clkdm_state_switch(clkdm); | 955 | return -EINVAL; |
886 | 956 | ||
887 | return 0; | 957 | return _clkdm_clk_hwmod_disable(clkdm); |
888 | } | 958 | } |
889 | 959 | ||
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 5823584d9cd7..8e0da642355c 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include "powerdomain.h" | 21 | #include "powerdomain.h" |
22 | #include <plat/clock.h> | 22 | #include <plat/clock.h> |
23 | #include <plat/omap_hwmod.h> | ||
23 | #include <plat/cpu.h> | 24 | #include <plat/cpu.h> |
24 | 25 | ||
25 | /* | 26 | /* |
@@ -183,6 +184,8 @@ int clkdm_sleep(struct clockdomain *clkdm); | |||
183 | 184 | ||
184 | int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); | 185 | int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); |
185 | int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); | 186 | int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); |
187 | int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh); | ||
188 | int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh); | ||
186 | 189 | ||
187 | extern void __init omap2xxx_clockdomains_init(void); | 190 | extern void __init omap2xxx_clockdomains_init(void); |
188 | extern void __init omap3xxx_clockdomains_init(void); | 191 | extern void __init omap3xxx_clockdomains_init(void); |