1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2020 Collabora Ltd.
6 #include <linux/clk-provider.h>
7 #include <linux/init.h>
9 #include <linux/iopoll.h>
10 #include <linux/mfd/syscon.h>
12 #include <linux/of_clk.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_domain.h>
15 #include <linux/regmap.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/soc/mediatek/infracfg.h>
19 #include "mt6735-pm-domains.h"
20 #include "mt6795-pm-domains.h"
21 #include "mt8167-pm-domains.h"
22 #include "mt8173-pm-domains.h"
23 #include "mt8183-pm-domains.h"
24 #include "mt8186-pm-domains.h"
25 #include "mt8188-pm-domains.h"
26 #include "mt8192-pm-domains.h"
27 #include "mt8195-pm-domains.h"
28 #include "mt8365-pm-domains.h"
30 #define MTK_POLL_DELAY_US 10
31 #define MTK_POLL_TIMEOUT USEC_PER_SEC
33 #define PWR_RST_B_BIT BIT(0)
34 #define PWR_ISO_BIT BIT(1)
35 #define PWR_ON_BIT BIT(2)
36 #define PWR_ON_2ND_BIT BIT(3)
37 #define PWR_CLK_DIS_BIT BIT(4)
38 #define PWR_SRAM_CLKISO_BIT BIT(5)
39 #define PWR_SRAM_ISOINT_B_BIT BIT(6)
41 struct scpsys_domain
{
42 struct generic_pm_domain genpd
;
43 const struct scpsys_domain_data
*data
;
44 struct scpsys
*scpsys
;
46 struct clk_bulk_data
*clks
;
48 struct clk_bulk_data
*subsys_clks
;
49 struct regmap
*infracfg_nao
;
50 struct regmap
*infracfg
;
52 struct regulator
*supply
;
58 const struct scpsys_soc_data
*soc_data
;
59 struct genpd_onecell_data pd_data
;
60 struct generic_pm_domain
*domains
[];
63 #define to_scpsys_domain(gpd) container_of(gpd, struct scpsys_domain, genpd)
65 static bool scpsys_domain_is_on(struct scpsys_domain
*pd
)
67 struct scpsys
*scpsys
= pd
->scpsys
;
70 regmap_read(scpsys
->base
, pd
->data
->pwr_sta_offs
, &status
);
71 status
&= pd
->data
->sta_mask
;
73 regmap_read(scpsys
->base
, pd
->data
->pwr_sta2nd_offs
, &status2
);
74 status2
&= pd
->data
->sta_mask
;
76 /* A domain is on when both status bits are set. */
77 return status
&& status2
;
80 static int scpsys_sram_enable(struct scpsys_domain
*pd
)
82 u32 pdn_ack
= pd
->data
->sram_pdn_ack_bits
;
83 struct scpsys
*scpsys
= pd
->scpsys
;
87 regmap_clear_bits(scpsys
->base
, pd
->data
->ctl_offs
, pd
->data
->sram_pdn_bits
);
89 /* Either wait until SRAM_PDN_ACK all 1 or 0 */
90 ret
= regmap_read_poll_timeout(scpsys
->base
, pd
->data
->ctl_offs
, tmp
,
91 (tmp
& pdn_ack
) == 0, MTK_POLL_DELAY_US
, MTK_POLL_TIMEOUT
);
95 if (MTK_SCPD_CAPS(pd
, MTK_SCPD_SRAM_ISO
)) {
96 regmap_set_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_SRAM_ISOINT_B_BIT
);
98 regmap_clear_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_SRAM_CLKISO_BIT
);
104 static int scpsys_sram_disable(struct scpsys_domain
*pd
)
106 u32 pdn_ack
= pd
->data
->sram_pdn_ack_bits
;
107 struct scpsys
*scpsys
= pd
->scpsys
;
110 if (MTK_SCPD_CAPS(pd
, MTK_SCPD_SRAM_ISO
)) {
111 regmap_set_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_SRAM_CLKISO_BIT
);
113 regmap_clear_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_SRAM_ISOINT_B_BIT
);
116 regmap_set_bits(scpsys
->base
, pd
->data
->ctl_offs
, pd
->data
->sram_pdn_bits
);
118 /* Either wait until SRAM_PDN_ACK all 1 or 0 */
119 return regmap_read_poll_timeout(scpsys
->base
, pd
->data
->ctl_offs
, tmp
,
120 (tmp
& pdn_ack
) == pdn_ack
, MTK_POLL_DELAY_US
,
124 static struct regmap
*scpsys_bus_protect_get_regmap(struct scpsys_domain
*pd
,
125 const struct scpsys_bus_prot_data
*bpd
)
127 if (bpd
->flags
& BUS_PROT_COMPONENT_SMI
)
133 static struct regmap
*scpsys_bus_protect_get_sta_regmap(struct scpsys_domain
*pd
,
134 const struct scpsys_bus_prot_data
*bpd
)
136 if (bpd
->flags
& BUS_PROT_STA_COMPONENT_INFRA_NAO
)
137 return pd
->infracfg_nao
;
139 return scpsys_bus_protect_get_regmap(pd
, bpd
);
142 static int scpsys_bus_protect_clear(struct scpsys_domain
*pd
,
143 const struct scpsys_bus_prot_data
*bpd
)
145 struct regmap
*sta_regmap
= scpsys_bus_protect_get_sta_regmap(pd
, bpd
);
146 struct regmap
*regmap
= scpsys_bus_protect_get_regmap(pd
, bpd
);
147 u32 sta_mask
= bpd
->bus_prot_sta_mask
;
151 expected_ack
= (bpd
->flags
& BUS_PROT_STA_COMPONENT_INFRA_NAO
? sta_mask
: 0);
153 if (bpd
->flags
& BUS_PROT_REG_UPDATE
)
154 regmap_clear_bits(regmap
, bpd
->bus_prot_clr
, bpd
->bus_prot_set_clr_mask
);
156 regmap_write(regmap
, bpd
->bus_prot_clr
, bpd
->bus_prot_set_clr_mask
);
158 if (bpd
->flags
& BUS_PROT_IGNORE_CLR_ACK
)
161 return regmap_read_poll_timeout(sta_regmap
, bpd
->bus_prot_sta
,
162 val
, (val
& sta_mask
) == expected_ack
,
163 MTK_POLL_DELAY_US
, MTK_POLL_TIMEOUT
);
166 static int scpsys_bus_protect_set(struct scpsys_domain
*pd
,
167 const struct scpsys_bus_prot_data
*bpd
)
169 struct regmap
*sta_regmap
= scpsys_bus_protect_get_sta_regmap(pd
, bpd
);
170 struct regmap
*regmap
= scpsys_bus_protect_get_regmap(pd
, bpd
);
171 u32 sta_mask
= bpd
->bus_prot_sta_mask
;
174 if (bpd
->flags
& BUS_PROT_REG_UPDATE
)
175 regmap_set_bits(regmap
, bpd
->bus_prot_set
, bpd
->bus_prot_set_clr_mask
);
177 regmap_write(regmap
, bpd
->bus_prot_set
, bpd
->bus_prot_set_clr_mask
);
179 return regmap_read_poll_timeout(sta_regmap
, bpd
->bus_prot_sta
,
180 val
, (val
& sta_mask
) == sta_mask
,
181 MTK_POLL_DELAY_US
, MTK_POLL_TIMEOUT
);
184 static int scpsys_bus_protect_enable(struct scpsys_domain
*pd
)
186 for (int i
= 0; i
< SPM_MAX_BUS_PROT_DATA
; i
++) {
187 const struct scpsys_bus_prot_data
*bpd
= &pd
->data
->bp_cfg
[i
];
190 if (!bpd
->bus_prot_set_clr_mask
)
193 if (bpd
->flags
& BUS_PROT_INVERTED
)
194 ret
= scpsys_bus_protect_clear(pd
, bpd
);
196 ret
= scpsys_bus_protect_set(pd
, bpd
);
204 static int scpsys_bus_protect_disable(struct scpsys_domain
*pd
)
206 for (int i
= SPM_MAX_BUS_PROT_DATA
- 1; i
>= 0; i
--) {
207 const struct scpsys_bus_prot_data
*bpd
= &pd
->data
->bp_cfg
[i
];
210 if (!bpd
->bus_prot_set_clr_mask
)
213 if (bpd
->flags
& BUS_PROT_INVERTED
)
214 ret
= scpsys_bus_protect_set(pd
, bpd
);
216 ret
= scpsys_bus_protect_clear(pd
, bpd
);
224 static int scpsys_regulator_enable(struct regulator
*supply
)
226 return supply
? regulator_enable(supply
) : 0;
229 static int scpsys_regulator_disable(struct regulator
*supply
)
231 return supply
? regulator_disable(supply
) : 0;
234 static int scpsys_power_on(struct generic_pm_domain
*genpd
)
236 struct scpsys_domain
*pd
= container_of(genpd
, struct scpsys_domain
, genpd
);
237 struct scpsys
*scpsys
= pd
->scpsys
;
241 ret
= scpsys_regulator_enable(pd
->supply
);
245 ret
= clk_bulk_prepare_enable(pd
->num_clks
, pd
->clks
);
249 if (pd
->data
->ext_buck_iso_offs
&& MTK_SCPD_CAPS(pd
, MTK_SCPD_EXT_BUCK_ISO
))
250 regmap_clear_bits(scpsys
->base
, pd
->data
->ext_buck_iso_offs
,
251 pd
->data
->ext_buck_iso_mask
);
253 /* subsys power on */
254 regmap_set_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_ON_BIT
);
255 regmap_set_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_ON_2ND_BIT
);
257 /* wait until PWR_ACK = 1 */
258 ret
= readx_poll_timeout(scpsys_domain_is_on
, pd
, tmp
, tmp
, MTK_POLL_DELAY_US
,
263 regmap_clear_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_CLK_DIS_BIT
);
264 regmap_clear_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_ISO_BIT
);
265 regmap_set_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_RST_B_BIT
);
268 * In few Mediatek platforms(e.g. MT6779), the bus protect policy is
269 * stricter, which leads to bus protect release must be prior to bus
272 if (!MTK_SCPD_CAPS(pd
, MTK_SCPD_STRICT_BUS_PROTECTION
)) {
273 ret
= clk_bulk_prepare_enable(pd
->num_subsys_clks
,
279 ret
= scpsys_sram_enable(pd
);
281 goto err_disable_subsys_clks
;
283 ret
= scpsys_bus_protect_disable(pd
);
285 goto err_disable_sram
;
287 if (MTK_SCPD_CAPS(pd
, MTK_SCPD_STRICT_BUS_PROTECTION
)) {
288 ret
= clk_bulk_prepare_enable(pd
->num_subsys_clks
,
291 goto err_enable_bus_protect
;
296 err_enable_bus_protect
:
297 scpsys_bus_protect_enable(pd
);
299 scpsys_sram_disable(pd
);
300 err_disable_subsys_clks
:
301 if (!MTK_SCPD_CAPS(pd
, MTK_SCPD_STRICT_BUS_PROTECTION
))
302 clk_bulk_disable_unprepare(pd
->num_subsys_clks
,
305 clk_bulk_disable_unprepare(pd
->num_clks
, pd
->clks
);
307 scpsys_regulator_disable(pd
->supply
);
311 static int scpsys_power_off(struct generic_pm_domain
*genpd
)
313 struct scpsys_domain
*pd
= container_of(genpd
, struct scpsys_domain
, genpd
);
314 struct scpsys
*scpsys
= pd
->scpsys
;
318 ret
= scpsys_bus_protect_enable(pd
);
322 ret
= scpsys_sram_disable(pd
);
326 if (pd
->data
->ext_buck_iso_offs
&& MTK_SCPD_CAPS(pd
, MTK_SCPD_EXT_BUCK_ISO
))
327 regmap_set_bits(scpsys
->base
, pd
->data
->ext_buck_iso_offs
,
328 pd
->data
->ext_buck_iso_mask
);
330 clk_bulk_disable_unprepare(pd
->num_subsys_clks
, pd
->subsys_clks
);
332 /* subsys power off */
333 regmap_set_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_ISO_BIT
);
334 regmap_set_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_CLK_DIS_BIT
);
335 regmap_clear_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_RST_B_BIT
);
336 regmap_clear_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_ON_2ND_BIT
);
337 regmap_clear_bits(scpsys
->base
, pd
->data
->ctl_offs
, PWR_ON_BIT
);
339 /* wait until PWR_ACK = 0 */
340 ret
= readx_poll_timeout(scpsys_domain_is_on
, pd
, tmp
, !tmp
, MTK_POLL_DELAY_US
,
345 clk_bulk_disable_unprepare(pd
->num_clks
, pd
->clks
);
347 scpsys_regulator_disable(pd
->supply
);
353 generic_pm_domain
*scpsys_add_one_domain(struct scpsys
*scpsys
, struct device_node
*node
)
355 const struct scpsys_domain_data
*domain_data
;
356 struct scpsys_domain
*pd
;
357 struct device_node
*smi_node
;
358 struct property
*prop
;
359 const char *clk_name
;
360 int i
, ret
, num_clks
;
365 ret
= of_property_read_u32(node
, "reg", &id
);
367 dev_err(scpsys
->dev
, "%pOF: failed to retrieve domain id from reg: %d\n",
369 return ERR_PTR(-EINVAL
);
372 if (id
>= scpsys
->soc_data
->num_domains
) {
373 dev_err(scpsys
->dev
, "%pOF: invalid domain id %d\n", node
, id
);
374 return ERR_PTR(-EINVAL
);
377 domain_data
= &scpsys
->soc_data
->domains_data
[id
];
378 if (domain_data
->sta_mask
== 0) {
379 dev_err(scpsys
->dev
, "%pOF: undefined domain id %d\n", node
, id
);
380 return ERR_PTR(-EINVAL
);
383 pd
= devm_kzalloc(scpsys
->dev
, sizeof(*pd
), GFP_KERNEL
);
385 return ERR_PTR(-ENOMEM
);
387 pd
->data
= domain_data
;
390 if (MTK_SCPD_CAPS(pd
, MTK_SCPD_DOMAIN_SUPPLY
)) {
391 pd
->supply
= devm_of_regulator_get_optional(scpsys
->dev
, node
, "domain");
392 if (IS_ERR(pd
->supply
))
393 return dev_err_cast_probe(scpsys
->dev
, pd
->supply
,
394 "%pOF: failed to get power supply.\n",
398 pd
->infracfg
= syscon_regmap_lookup_by_phandle_optional(node
, "mediatek,infracfg");
399 if (IS_ERR(pd
->infracfg
))
400 return ERR_CAST(pd
->infracfg
);
402 smi_node
= of_parse_phandle(node
, "mediatek,smi", 0);
404 pd
->smi
= device_node_to_regmap(smi_node
);
405 of_node_put(smi_node
);
407 return ERR_CAST(pd
->smi
);
410 if (MTK_SCPD_CAPS(pd
, MTK_SCPD_HAS_INFRA_NAO
)) {
411 pd
->infracfg_nao
= syscon_regmap_lookup_by_phandle(node
, "mediatek,infracfg-nao");
412 if (IS_ERR(pd
->infracfg_nao
))
413 return ERR_CAST(pd
->infracfg_nao
);
415 pd
->infracfg_nao
= NULL
;
418 num_clks
= of_clk_get_parent_count(node
);
420 /* Calculate number of subsys_clks */
421 of_property_for_each_string(node
, "clock-names", prop
, clk_name
) {
424 subsys
= strchr(clk_name
, '-');
426 pd
->num_subsys_clks
++;
431 pd
->clks
= devm_kcalloc(scpsys
->dev
, pd
->num_clks
, sizeof(*pd
->clks
), GFP_KERNEL
);
433 return ERR_PTR(-ENOMEM
);
435 pd
->subsys_clks
= devm_kcalloc(scpsys
->dev
, pd
->num_subsys_clks
,
436 sizeof(*pd
->subsys_clks
), GFP_KERNEL
);
437 if (!pd
->subsys_clks
)
438 return ERR_PTR(-ENOMEM
);
442 for (i
= 0; i
< pd
->num_clks
; i
++) {
443 clk
= of_clk_get(node
, i
);
446 dev_err_probe(scpsys
->dev
, ret
,
447 "%pOF: failed to get clk at index %d\n", node
, i
);
451 pd
->clks
[clk_ind
++].clk
= clk
;
454 for (i
= 0; i
< pd
->num_subsys_clks
; i
++) {
455 clk
= of_clk_get(node
, i
+ clk_ind
);
458 dev_err_probe(scpsys
->dev
, ret
,
459 "%pOF: failed to get clk at index %d\n", node
,
461 goto err_put_subsys_clocks
;
464 pd
->subsys_clks
[i
].clk
= clk
;
468 * Initially turn on all domains to make the domains usable
469 * with !CONFIG_PM and to get the hardware in sync with the
470 * software. The unused domains will be switched off during
473 if (MTK_SCPD_CAPS(pd
, MTK_SCPD_KEEP_DEFAULT_OFF
)) {
474 if (scpsys_domain_is_on(pd
))
475 dev_warn(scpsys
->dev
,
476 "%pOF: A default off power domain has been ON\n", node
);
478 ret
= scpsys_power_on(&pd
->genpd
);
480 dev_err(scpsys
->dev
, "%pOF: failed to power on domain: %d\n", node
, ret
);
481 goto err_put_subsys_clocks
;
484 if (MTK_SCPD_CAPS(pd
, MTK_SCPD_ALWAYS_ON
))
485 pd
->genpd
.flags
|= GENPD_FLAG_ALWAYS_ON
;
488 if (scpsys
->domains
[id
]) {
491 "power domain with id %d already exists, check your device-tree\n", id
);
492 goto err_put_subsys_clocks
;
496 pd
->genpd
.name
= node
->name
;
498 pd
->genpd
.name
= pd
->data
->name
;
500 pd
->genpd
.power_off
= scpsys_power_off
;
501 pd
->genpd
.power_on
= scpsys_power_on
;
503 if (MTK_SCPD_CAPS(pd
, MTK_SCPD_ACTIVE_WAKEUP
))
504 pd
->genpd
.flags
|= GENPD_FLAG_ACTIVE_WAKEUP
;
506 if (MTK_SCPD_CAPS(pd
, MTK_SCPD_KEEP_DEFAULT_OFF
))
507 pm_genpd_init(&pd
->genpd
, NULL
, true);
509 pm_genpd_init(&pd
->genpd
, NULL
, false);
511 scpsys
->domains
[id
] = &pd
->genpd
;
513 return scpsys
->pd_data
.domains
[id
];
515 err_put_subsys_clocks
:
516 clk_bulk_put(pd
->num_subsys_clks
, pd
->subsys_clks
);
518 clk_bulk_put(pd
->num_clks
, pd
->clks
);
522 static int scpsys_add_subdomain(struct scpsys
*scpsys
, struct device_node
*parent
)
524 struct generic_pm_domain
*child_pd
, *parent_pd
;
525 struct device_node
*child
;
528 for_each_child_of_node(parent
, child
) {
531 ret
= of_property_read_u32(parent
, "reg", &id
);
533 dev_err(scpsys
->dev
, "%pOF: failed to get parent domain id\n", child
);
537 if (!scpsys
->pd_data
.domains
[id
]) {
539 dev_err(scpsys
->dev
, "power domain with id %d does not exist\n", id
);
543 parent_pd
= scpsys
->pd_data
.domains
[id
];
545 child_pd
= scpsys_add_one_domain(scpsys
, child
);
546 if (IS_ERR(child_pd
)) {
547 ret
= PTR_ERR(child_pd
);
548 dev_err_probe(scpsys
->dev
, ret
, "%pOF: failed to get child domain id\n",
553 /* recursive call to add all subdomains */
554 ret
= scpsys_add_subdomain(scpsys
, child
);
558 ret
= pm_genpd_add_subdomain(parent_pd
, child_pd
);
560 dev_err(scpsys
->dev
, "failed to add %s subdomain to parent %s\n",
561 child_pd
->name
, parent_pd
->name
);
564 dev_dbg(scpsys
->dev
, "%s add subdomain: %s\n", parent_pd
->name
,
576 static void scpsys_remove_one_domain(struct scpsys_domain
*pd
)
581 * We're in the error cleanup already, so we only complain,
582 * but won't emit another error on top of the original one.
584 ret
= pm_genpd_remove(&pd
->genpd
);
586 dev_err(pd
->scpsys
->dev
,
587 "failed to remove domain '%s' : %d - state may be inconsistent\n",
588 pd
->genpd
.name
, ret
);
589 if (scpsys_domain_is_on(pd
))
590 scpsys_power_off(&pd
->genpd
);
592 clk_bulk_put(pd
->num_clks
, pd
->clks
);
593 clk_bulk_put(pd
->num_subsys_clks
, pd
->subsys_clks
);
596 static void scpsys_domain_cleanup(struct scpsys
*scpsys
)
598 struct generic_pm_domain
*genpd
;
599 struct scpsys_domain
*pd
;
602 for (i
= scpsys
->pd_data
.num_domains
- 1; i
>= 0; i
--) {
603 genpd
= scpsys
->pd_data
.domains
[i
];
605 pd
= to_scpsys_domain(genpd
);
606 scpsys_remove_one_domain(pd
);
611 static const struct of_device_id scpsys_of_match
[] = {
613 .compatible
= "mediatek,mt6735-power-controller",
614 .data
= &mt6735_scpsys_data
,
617 .compatible
= "mediatek,mt6795-power-controller",
618 .data
= &mt6795_scpsys_data
,
621 .compatible
= "mediatek,mt8167-power-controller",
622 .data
= &mt8167_scpsys_data
,
625 .compatible
= "mediatek,mt8173-power-controller",
626 .data
= &mt8173_scpsys_data
,
629 .compatible
= "mediatek,mt8183-power-controller",
630 .data
= &mt8183_scpsys_data
,
633 .compatible
= "mediatek,mt8186-power-controller",
634 .data
= &mt8186_scpsys_data
,
637 .compatible
= "mediatek,mt8188-power-controller",
638 .data
= &mt8188_scpsys_data
,
641 .compatible
= "mediatek,mt8192-power-controller",
642 .data
= &mt8192_scpsys_data
,
645 .compatible
= "mediatek,mt8195-power-controller",
646 .data
= &mt8195_scpsys_data
,
649 .compatible
= "mediatek,mt8365-power-controller",
650 .data
= &mt8365_scpsys_data
,
655 static int scpsys_probe(struct platform_device
*pdev
)
657 struct device
*dev
= &pdev
->dev
;
658 struct device_node
*np
= dev
->of_node
;
659 const struct scpsys_soc_data
*soc
;
660 struct device_node
*node
;
661 struct device
*parent
;
662 struct scpsys
*scpsys
;
665 soc
= of_device_get_match_data(&pdev
->dev
);
667 dev_err(&pdev
->dev
, "no power controller data\n");
671 scpsys
= devm_kzalloc(dev
, struct_size(scpsys
, domains
, soc
->num_domains
), GFP_KERNEL
);
676 scpsys
->soc_data
= soc
;
678 scpsys
->pd_data
.domains
= scpsys
->domains
;
679 scpsys
->pd_data
.num_domains
= soc
->num_domains
;
681 parent
= dev
->parent
;
683 dev_err(dev
, "no parent for syscon devices\n");
687 scpsys
->base
= syscon_node_to_regmap(parent
->of_node
);
688 if (IS_ERR(scpsys
->base
)) {
689 dev_err(dev
, "no regmap available\n");
690 return PTR_ERR(scpsys
->base
);
694 for_each_available_child_of_node(np
, node
) {
695 struct generic_pm_domain
*domain
;
697 domain
= scpsys_add_one_domain(scpsys
, node
);
698 if (IS_ERR(domain
)) {
699 ret
= PTR_ERR(domain
);
701 goto err_cleanup_domains
;
704 ret
= scpsys_add_subdomain(scpsys
, node
);
707 goto err_cleanup_domains
;
712 dev_dbg(dev
, "no power domains present\n");
716 ret
= of_genpd_add_provider_onecell(np
, &scpsys
->pd_data
);
718 dev_err(dev
, "failed to add provider: %d\n", ret
);
719 goto err_cleanup_domains
;
725 scpsys_domain_cleanup(scpsys
);
729 static struct platform_driver scpsys_pm_domain_driver
= {
730 .probe
= scpsys_probe
,
732 .name
= "mtk-power-controller",
733 .suppress_bind_attrs
= true,
734 .of_match_table
= scpsys_of_match
,
737 builtin_platform_driver(scpsys_pm_domain_driver
);