aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorBenoit Cousson <b-cousson@ti.com>2011-07-10 07:56:54 -0400
committerPaul Walmsley <paul@pwsan.com>2011-07-10 07:56:54 -0400
commit113a74137f5c85f2c7914e78350f70247ef9447c (patch)
treef2eaea43a00c23424aa27a418f6a37a81caa8d83 /arch/arm/mach-omap2
parenta5122ff8ceb2b1f207965a3608d3da3af832e513 (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.c142
-rw-r--r--arch/arm/mach-omap2/clockdomain.h3
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
801static 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
823static 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 */
856int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) 884int 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 */
912int 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 */
943int 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
184int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); 185int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
185int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); 186int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
187int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
188int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
186 189
187extern void __init omap2xxx_clockdomains_init(void); 190extern void __init omap2xxx_clockdomains_init(void);
188extern void __init omap3xxx_clockdomains_init(void); 191extern void __init omap3xxx_clockdomains_init(void);