178
178
*/
179
179
#define OMAP4_RST_CTRL_ST_OFFSET 4
180
180
181
+ /*
182
+ * Maximum length for module clock handle names
183
+ */
184
+ #define MOD_CLK_MAX_NAME_LEN 32
185
+
181
186
/**
182
187
* struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
183
188
* @enable_module: function to enable a module (via MODULEMODE)
@@ -200,6 +205,7 @@ struct omap_hwmod_soc_ops {
200
205
int (* init_clkdm )(struct omap_hwmod * oh );
201
206
void (* update_context_lost )(struct omap_hwmod * oh );
202
207
int (* get_context_lost )(struct omap_hwmod * oh );
208
+ int (* disable_direct_prcm )(struct omap_hwmod * oh );
203
209
};
204
210
205
211
/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
@@ -776,17 +782,35 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
776
782
* @oh: struct omap_hwmod *
777
783
*
778
784
* Called from _init_clocks(). Populates the @oh _clk (main
779
- * functional clock pointer) if a main_clk is present. Returns 0 on
780
- * success or -EINVAL on error.
785
+ * functional clock pointer) if a clock matching the hwmod name is found,
786
+ * or a main_clk is present. Returns 0 on success or -EINVAL on error.
781
787
*/
782
788
static int _init_main_clk (struct omap_hwmod * oh )
783
789
{
784
790
int ret = 0 ;
791
+ char name [MOD_CLK_MAX_NAME_LEN ];
792
+ struct clk * clk ;
785
793
786
- if (!oh -> main_clk )
787
- return 0 ;
794
+ /* +7 magic comes from '_mod_ck' suffix */
795
+ if (strlen (oh -> name ) + 7 > MOD_CLK_MAX_NAME_LEN )
796
+ pr_warn ("%s: warning: cropping name for %s\n" , __func__ ,
797
+ oh -> name );
798
+
799
+ strncpy (name , oh -> name , MOD_CLK_MAX_NAME_LEN - 7 );
800
+ strcat (name , "_mod_ck" );
801
+
802
+ clk = clk_get (NULL , name );
803
+ if (!IS_ERR (clk )) {
804
+ oh -> _clk = clk ;
805
+ soc_ops .disable_direct_prcm (oh );
806
+ oh -> main_clk = kstrdup (name , GFP_KERNEL );
807
+ } else {
808
+ if (!oh -> main_clk )
809
+ return 0 ;
810
+
811
+ oh -> _clk = clk_get (NULL , oh -> main_clk );
812
+ }
788
813
789
- oh -> _clk = clk_get (NULL , oh -> main_clk );
790
814
if (IS_ERR (oh -> _clk )) {
791
815
pr_warn ("omap_hwmod: %s: cannot clk_get main_clk %s\n" ,
792
816
oh -> name , oh -> main_clk );
@@ -3090,6 +3114,25 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
3090
3114
oh -> prcm .omap4 .rstctrl_offs );
3091
3115
}
3092
3116
3117
+ /**
3118
+ * _omap4_disable_direct_prcm - disable direct PRCM control for hwmod
3119
+ * @oh: struct omap_hwmod * to disable control for
3120
+ *
3121
+ * Disables direct PRCM clkctrl done by hwmod core. Instead, the hwmod
3122
+ * will be using its main_clk to enable/disable the module. Returns
3123
+ * 0 if successful.
3124
+ */
3125
+ static int _omap4_disable_direct_prcm (struct omap_hwmod * oh )
3126
+ {
3127
+ if (!oh )
3128
+ return - EINVAL ;
3129
+
3130
+ oh -> prcm .omap4 .clkctrl_offs = 0 ;
3131
+ oh -> prcm .omap4 .modulemode = 0 ;
3132
+
3133
+ return 0 ;
3134
+ }
3135
+
3093
3136
/**
3094
3137
* _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
3095
3138
* @oh: struct omap_hwmod * to deassert hardreset
@@ -3913,6 +3956,7 @@ void __init omap_hwmod_init(void)
3913
3956
soc_ops .init_clkdm = _init_clkdm ;
3914
3957
soc_ops .update_context_lost = _omap4_update_context_lost ;
3915
3958
soc_ops .get_context_lost = _omap4_get_context_lost ;
3959
+ soc_ops .disable_direct_prcm = _omap4_disable_direct_prcm ;
3916
3960
} else if (cpu_is_ti814x () || cpu_is_ti816x () || soc_is_am33xx () ||
3917
3961
soc_is_am43xx ()) {
3918
3962
soc_ops .enable_module = _omap4_enable_module ;
@@ -3922,6 +3966,7 @@ void __init omap_hwmod_init(void)
3922
3966
soc_ops .deassert_hardreset = _am33xx_deassert_hardreset ;
3923
3967
soc_ops .is_hardreset_asserted = _omap4_is_hardreset_asserted ;
3924
3968
soc_ops .init_clkdm = _init_clkdm ;
3969
+ soc_ops .disable_direct_prcm = _omap4_disable_direct_prcm ;
3925
3970
} else {
3926
3971
WARN (1 , "omap_hwmod: unknown SoC type\n" );
3927
3972
}
0 commit comments