@@ -152,40 +152,18 @@ int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable)
152
152
153
153
if (!enable ) {
154
154
regmap_update_bits (regmap , CSI_EN_REG , CSI_EN_CSI_EN , 0 );
155
+ pm_runtime_put (dev );
155
156
156
- clk_disable_unprepare (csi_dev -> clock_ram );
157
- clk_disable_unprepare (csi_dev -> clock_mod );
158
- reset_control_assert (csi_dev -> reset );
159
157
return 0 ;
160
158
}
161
159
162
- ret = clk_prepare_enable (csi_dev -> clock_mod );
163
- if (ret ) {
164
- dev_err (csi_dev -> dev , "Enable csi clk err %d\n" , ret );
160
+ ret = pm_runtime_resume_and_get (dev );
161
+ if (ret < 0 )
165
162
return ret ;
166
- }
167
-
168
- ret = clk_prepare_enable (csi_dev -> clock_ram );
169
- if (ret ) {
170
- dev_err (csi_dev -> dev , "Enable clk_dram_csi clk err %d\n" , ret );
171
- goto clk_mod_disable ;
172
- }
173
-
174
- ret = reset_control_deassert (csi_dev -> reset );
175
- if (ret ) {
176
- dev_err (csi_dev -> dev , "reset err %d\n" , ret );
177
- goto clk_ram_disable ;
178
- }
179
163
180
164
regmap_update_bits (regmap , CSI_EN_REG , CSI_EN_CSI_EN , CSI_EN_CSI_EN );
181
165
182
166
return 0 ;
183
-
184
- clk_ram_disable :
185
- clk_disable_unprepare (csi_dev -> clock_ram );
186
- clk_mod_disable :
187
- clk_disable_unprepare (csi_dev -> clock_mod );
188
- return ret ;
189
167
}
190
168
191
169
static enum csi_input_fmt get_csi_input_format (struct sun6i_csi_device * csi_dev ,
@@ -797,6 +775,56 @@ static irqreturn_t sun6i_csi_interrupt(int irq, void *private)
797
775
return IRQ_HANDLED ;
798
776
}
799
777
778
+ static int sun6i_csi_suspend (struct device * dev )
779
+ {
780
+ struct sun6i_csi_device * csi_dev = dev_get_drvdata (dev );
781
+
782
+ reset_control_assert (csi_dev -> reset );
783
+ clk_disable_unprepare (csi_dev -> clock_ram );
784
+ clk_disable_unprepare (csi_dev -> clock_mod );
785
+
786
+ return 0 ;
787
+ }
788
+
789
+ static int sun6i_csi_resume (struct device * dev )
790
+ {
791
+ struct sun6i_csi_device * csi_dev = dev_get_drvdata (dev );
792
+ int ret ;
793
+
794
+ ret = reset_control_deassert (csi_dev -> reset );
795
+ if (ret ) {
796
+ dev_err (dev , "failed to deassert reset\n" );
797
+ return ret ;
798
+ }
799
+
800
+ ret = clk_prepare_enable (csi_dev -> clock_mod );
801
+ if (ret ) {
802
+ dev_err (dev , "failed to enable module clock\n" );
803
+ goto error_reset ;
804
+ }
805
+
806
+ ret = clk_prepare_enable (csi_dev -> clock_ram );
807
+ if (ret ) {
808
+ dev_err (dev , "failed to enable ram clock\n" );
809
+ goto error_clock_mod ;
810
+ }
811
+
812
+ return 0 ;
813
+
814
+ error_clock_mod :
815
+ clk_disable_unprepare (csi_dev -> clock_mod );
816
+
817
+ error_reset :
818
+ reset_control_assert (csi_dev -> reset );
819
+
820
+ return ret ;
821
+ }
822
+
823
+ static const struct dev_pm_ops sun6i_csi_pm_ops = {
824
+ .runtime_suspend = sun6i_csi_suspend ,
825
+ .runtime_resume = sun6i_csi_resume ,
826
+ };
827
+
800
828
static const struct regmap_config sun6i_csi_regmap_config = {
801
829
.reg_bits = 32 ,
802
830
.reg_stride = 4 ,
@@ -876,6 +904,10 @@ static int sun6i_csi_resources_setup(struct sun6i_csi_device *csi_dev,
876
904
goto error_clock_rate_exclusive ;
877
905
}
878
906
907
+ /* Runtime PM */
908
+
909
+ pm_runtime_enable (dev );
910
+
879
911
return 0 ;
880
912
881
913
error_clock_rate_exclusive :
@@ -886,6 +918,7 @@ static int sun6i_csi_resources_setup(struct sun6i_csi_device *csi_dev,
886
918
887
919
static void sun6i_csi_resources_cleanup (struct sun6i_csi_device * csi_dev )
888
920
{
921
+ pm_runtime_disable (csi_dev -> dev );
889
922
clk_rate_exclusive_put (csi_dev -> clock_mod );
890
923
}
891
924
@@ -968,6 +1001,7 @@ static struct platform_driver sun6i_csi_platform_driver = {
968
1001
.driver = {
969
1002
.name = SUN6I_CSI_NAME ,
970
1003
.of_match_table = of_match_ptr (sun6i_csi_of_match ),
1004
+ .pm = & sun6i_csi_pm_ops ,
971
1005
},
972
1006
};
973
1007
0 commit comments