5555#define QDSP6SS_CORE_CBCR 0x20
5656#define QDSP6SS_SLEEP_CBCR 0x3c
5757
58- #define QCOM_Q6V5_RPROC_PROXY_PD_MAX 3
59-
6058#define LPASS_BOOT_CORE_START BIT(0)
6159#define LPASS_BOOT_CMD_START BIT(0)
6260#define LPASS_EFUSE_Q6SS_EVB_SEL 0x0
@@ -74,7 +72,8 @@ struct adsp_pil_data {
7472
7573 const char * * clk_ids ;
7674 int num_clks ;
77- const char * * proxy_pd_names ;
75+ const char * * pd_names ;
76+ unsigned int num_pds ;
7877 const char * load_state ;
7978};
8079
@@ -110,8 +109,7 @@ struct qcom_adsp {
110109 size_t mem_size ;
111110 bool has_iommu ;
112111
113- struct device * proxy_pds [QCOM_Q6V5_RPROC_PROXY_PD_MAX ];
114- size_t proxy_pd_count ;
112+ struct dev_pm_domain_list * pd_list ;
115113
116114 struct qcom_rproc_glink glink_subdev ;
117115 struct qcom_rproc_ssr ssr_subdev ;
@@ -120,98 +118,92 @@ struct qcom_adsp {
120118 int (* shutdown )(struct qcom_adsp * adsp );
121119};
122120
123- static int qcom_rproc_pds_attach (struct device * dev , struct qcom_adsp * adsp ,
124- const char * * pd_names )
121+ static int qcom_rproc_pds_attach (struct qcom_adsp * adsp , const char * * pd_names ,
122+ unsigned int num_pds )
125123{
126- struct device * * devs = adsp -> proxy_pds ;
127- size_t num_pds = 0 ;
124+ struct device * dev = adsp -> dev ;
125+ struct dev_pm_domain_attach_data pd_data = {
126+ .pd_names = pd_names ,
127+ .num_pd_names = num_pds ,
128+ };
128129 int ret ;
129- int i ;
130-
131- if (!pd_names )
132- return 0 ;
133130
134131 /* Handle single power domain */
135- if (dev -> pm_domain ) {
136- devs [0 ] = dev ;
137- pm_runtime_enable (dev );
138- return 1 ;
139- }
132+ if (dev -> pm_domain )
133+ goto out ;
140134
141- while ( pd_names [ num_pds ] )
142- num_pds ++ ;
135+ if (! pd_names )
136+ return 0 ;
143137
144- if (num_pds > ARRAY_SIZE (adsp -> proxy_pds ))
145- return - E2BIG ;
138+ ret = dev_pm_domain_attach_list (dev , & pd_data , & adsp -> pd_list );
139+ if (ret < 0 )
140+ return ret ;
146141
147- for (i = 0 ; i < num_pds ; i ++ ) {
148- devs [i ] = dev_pm_domain_attach_by_name (dev , pd_names [i ]);
149- if (IS_ERR_OR_NULL (devs [i ])) {
150- ret = PTR_ERR (devs [i ]) ? : - ENODATA ;
151- goto unroll_attach ;
152- }
153- }
142+ out :
143+ pm_runtime_enable (dev );
144+ return 0 ;
145+ }
154146
155- return num_pds ;
147+ static void qcom_rproc_pds_detach (struct qcom_adsp * adsp )
148+ {
149+ struct device * dev = adsp -> dev ;
150+ struct dev_pm_domain_list * pds = adsp -> pd_list ;
156151
157- unroll_attach :
158- for (i -- ; i >= 0 ; i -- )
159- dev_pm_domain_detach (devs [i ], false);
152+ dev_pm_domain_detach_list (pds );
160153
161- return ret ;
154+ if (dev -> pm_domain || pds )
155+ pm_runtime_disable (adsp -> dev );
162156}
163157
164- static void qcom_rproc_pds_detach (struct qcom_adsp * adsp , struct device * * pds ,
165- size_t pd_count )
158+ static int qcom_rproc_pds_enable (struct qcom_adsp * adsp )
166159{
167160 struct device * dev = adsp -> dev ;
168- int i ;
161+ struct dev_pm_domain_list * pds = adsp -> pd_list ;
162+ int ret , i = 0 ;
169163
170- /* Handle single power domain */
171- if (dev -> pm_domain && pd_count ) {
172- pm_runtime_disable (dev );
173- return ;
174- }
164+ if (!dev -> pm_domain && !pds )
165+ return 0 ;
175166
176- for (i = 0 ; i < pd_count ; i ++ )
177- dev_pm_domain_detach (pds [i ], false);
178- }
167+ if (dev -> pm_domain )
168+ dev_pm_genpd_set_performance_state (dev , INT_MAX );
179169
180- static int qcom_rproc_pds_enable (struct qcom_adsp * adsp , struct device * * pds ,
181- size_t pd_count )
182- {
183- int ret ;
184- int i ;
185-
186- for (i = 0 ; i < pd_count ; i ++ ) {
187- dev_pm_genpd_set_performance_state (pds [i ], INT_MAX );
188- ret = pm_runtime_resume_and_get (pds [i ]);
189- if (ret < 0 ) {
190- dev_pm_genpd_set_performance_state (pds [i ], 0 );
191- goto unroll_pd_votes ;
192- }
170+ while (pds && i < pds -> num_pds ) {
171+ dev_pm_genpd_set_performance_state (pds -> pd_devs [i ], INT_MAX );
172+ i ++ ;
193173 }
194174
195- return 0 ;
175+ ret = pm_runtime_resume_and_get (dev );
176+ if (ret < 0 ) {
177+ while (pds && i > 0 ) {
178+ i -- ;
179+ dev_pm_genpd_set_performance_state (pds -> pd_devs [i ], 0 );
180+ }
196181
197- unroll_pd_votes :
198- for (i -- ; i >= 0 ; i -- ) {
199- dev_pm_genpd_set_performance_state (pds [i ], 0 );
200- pm_runtime_put (pds [i ]);
182+ if (dev -> pm_domain )
183+ dev_pm_genpd_set_performance_state (dev , 0 );
201184 }
202185
203186 return ret ;
204187}
205188
206- static void qcom_rproc_pds_disable (struct qcom_adsp * adsp , struct device * * pds ,
207- size_t pd_count )
189+ static void qcom_rproc_pds_disable (struct qcom_adsp * adsp )
208190{
209- int i ;
191+ struct device * dev = adsp -> dev ;
192+ struct dev_pm_domain_list * pds = adsp -> pd_list ;
193+ int i = 0 ;
194+
195+ if (!dev -> pm_domain && !pds )
196+ return ;
197+
198+ if (dev -> pm_domain )
199+ dev_pm_genpd_set_performance_state (dev , 0 );
210200
211- for ( i = 0 ; i < pd_count ; i ++ ) {
212- dev_pm_genpd_set_performance_state (pds [i ], 0 );
213- pm_runtime_put ( pds [ i ]) ;
201+ while ( pds && i < pds -> num_pds ) {
202+ dev_pm_genpd_set_performance_state (pds -> pd_devs [i ], 0 );
203+ i ++ ;
214204 }
205+
206+ pm_runtime_put (dev );
215207}
216208
217209static int qcom_wpss_shutdown (struct qcom_adsp * adsp )
@@ -397,8 +389,7 @@ static int adsp_start(struct rproc *rproc)
397389 if (ret )
398390 goto adsp_smmu_unmap ;
399391
400- ret = qcom_rproc_pds_enable (adsp , adsp -> proxy_pds ,
401- adsp -> proxy_pd_count );
392+ ret = qcom_rproc_pds_enable (adsp );
402393 if (ret < 0 )
403394 goto disable_xo_clk ;
404395
@@ -448,7 +439,7 @@ static int adsp_start(struct rproc *rproc)
448439disable_adsp_clks :
449440 clk_bulk_disable_unprepare (adsp -> num_clks , adsp -> clks );
450441disable_power_domain :
451- qcom_rproc_pds_disable (adsp , adsp -> proxy_pds , adsp -> proxy_pd_count );
442+ qcom_rproc_pds_disable (adsp );
452443disable_xo_clk :
453444 clk_disable_unprepare (adsp -> xo );
454445adsp_smmu_unmap :
@@ -464,7 +455,7 @@ static void qcom_adsp_pil_handover(struct qcom_q6v5 *q6v5)
464455 struct qcom_adsp * adsp = container_of (q6v5 , struct qcom_adsp , q6v5 );
465456
466457 clk_disable_unprepare (adsp -> xo );
467- qcom_rproc_pds_disable (adsp , adsp -> proxy_pds , adsp -> proxy_pd_count );
458+ qcom_rproc_pds_disable (adsp );
468459}
469460
470461static int adsp_stop (struct rproc * rproc )
@@ -715,13 +706,11 @@ static int adsp_probe(struct platform_device *pdev)
715706 if (ret )
716707 goto free_rproc ;
717708
718- ret = qcom_rproc_pds_attach (adsp -> dev , adsp ,
719- desc -> proxy_pd_names );
709+ ret = qcom_rproc_pds_attach (adsp , desc -> pd_names , desc -> num_pds );
720710 if (ret < 0 ) {
721711 dev_err (& pdev -> dev , "Failed to attach proxy power domains\n" );
722712 goto free_rproc ;
723713 }
724- adsp -> proxy_pd_count = ret ;
725714
726715 ret = adsp_init_reset (adsp );
727716 if (ret )
@@ -753,7 +742,7 @@ static int adsp_probe(struct platform_device *pdev)
753742 return 0 ;
754743
755744disable_pm :
756- qcom_rproc_pds_detach (adsp , adsp -> proxy_pds , adsp -> proxy_pd_count );
745+ qcom_rproc_pds_detach (adsp );
757746
758747free_rproc :
759748 rproc_free (rproc );
@@ -771,7 +760,7 @@ static void adsp_remove(struct platform_device *pdev)
771760 qcom_remove_glink_subdev (adsp -> rproc , & adsp -> glink_subdev );
772761 qcom_remove_sysmon_subdev (adsp -> sysmon );
773762 qcom_remove_ssr_subdev (adsp -> rproc , & adsp -> ssr_subdev );
774- qcom_rproc_pds_detach (adsp , adsp -> proxy_pds , adsp -> proxy_pd_count );
763+ qcom_rproc_pds_detach (adsp );
775764 rproc_free (adsp -> rproc );
776765}
777766
@@ -788,9 +777,8 @@ static const struct adsp_pil_data adsp_resource_init = {
788777 "qdsp6ss_xo" , "qdsp6ss_sleep" , "qdsp6ss_core" , NULL
789778 },
790779 .num_clks = 7 ,
791- .proxy_pd_names = (const char * []) {
792- "cx" , NULL
793- },
780+ .pd_names = (const char * []) { "cx" },
781+ .num_pds = 1 ,
794782};
795783
796784static const struct adsp_pil_data adsp_sc7280_resource_init = {
@@ -821,9 +809,8 @@ static const struct adsp_pil_data cdsp_resource_init = {
821809 "q6_axim" , NULL
822810 },
823811 .num_clks = 7 ,
824- .proxy_pd_names = (const char * []) {
825- "cx" , NULL
826- },
812+ .pd_names = (const char * []) { "cx" },
813+ .num_pds = 1 ,
827814};
828815
829816static const struct adsp_pil_data wpss_resource_init = {
@@ -839,9 +826,8 @@ static const struct adsp_pil_data wpss_resource_init = {
839826 "ahb_bdg" , "ahb" , "rscp" , NULL
840827 },
841828 .num_clks = 3 ,
842- .proxy_pd_names = (const char * []) {
843- "cx" , "mx" , NULL
844- },
829+ .pd_names = (const char * []) { "cx" , "mx" },
830+ .num_pds = 2 ,
845831};
846832
847833static const struct of_device_id adsp_of_match [] = {
0 commit comments