summaryrefslogtreecommitdiff
path: root/drivers/pmdomain/imx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pmdomain/imx')
-rw-r--r--drivers/pmdomain/imx/gpc.c22
-rw-r--r--drivers/pmdomain/imx/gpcv2.c29
-rw-r--r--drivers/pmdomain/imx/imx8m-blk-ctrl.c12
-rw-r--r--drivers/pmdomain/imx/imx8mp-blk-ctrl.c24
-rw-r--r--drivers/pmdomain/imx/imx93-blk-ctrl.c6
-rw-r--r--drivers/pmdomain/imx/imx93-pd.c29
-rw-r--r--drivers/pmdomain/imx/scu-pd.c7
7 files changed, 67 insertions, 62 deletions
diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c
index 9517cce93d8a..f18c7e6e75dd 100644
--- a/drivers/pmdomain/imx/gpc.c
+++ b/drivers/pmdomain/imx/gpc.c
@@ -233,7 +233,7 @@ static struct platform_driver imx_pgc_power_domain_driver = {
.name = "imx-pgc-pd",
},
.probe = imx_pgc_power_domain_probe,
- .remove_new = imx_pgc_power_domain_remove,
+ .remove = imx_pgc_power_domain_remove,
.id_table = imx_pgc_power_domain_id,
};
builtin_platform_driver(imx_pgc_power_domain_driver)
@@ -411,7 +411,7 @@ static int imx_gpc_probe(struct platform_device *pdev)
pgc_node = of_get_child_by_name(pdev->dev.of_node, "pgc");
/* bail out if DT too old and doesn't provide the necessary info */
- if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells") &&
+ if (!of_property_present(pdev->dev.of_node, "#power-domain-cells") &&
!pgc_node)
return 0;
@@ -455,7 +455,6 @@ static int imx_gpc_probe(struct platform_device *pdev)
} else {
struct imx_pm_domain *domain;
struct platform_device *pd_pdev;
- struct device_node *np;
struct clk *ipg_clk;
unsigned int ipg_rate_mhz;
int domain_index;
@@ -465,28 +464,24 @@ static int imx_gpc_probe(struct platform_device *pdev)
return PTR_ERR(ipg_clk);
ipg_rate_mhz = clk_get_rate(ipg_clk) / 1000000;
- for_each_child_of_node(pgc_node, np) {
+ for_each_child_of_node_scoped(pgc_node, np) {
ret = of_property_read_u32(np, "reg", &domain_index);
- if (ret) {
- of_node_put(np);
+ if (ret)
return ret;
- }
+
if (domain_index >= of_id_data->num_domains)
continue;
pd_pdev = platform_device_alloc("imx-pgc-power-domain",
domain_index);
- if (!pd_pdev) {
- of_node_put(np);
+ if (!pd_pdev)
return -ENOMEM;
- }
ret = platform_device_add_data(pd_pdev,
&imx_gpc_domains[domain_index],
sizeof(imx_gpc_domains[domain_index]));
if (ret) {
platform_device_put(pd_pdev);
- of_node_put(np);
return ret;
}
domain = pd_pdev->dev.platform_data;
@@ -500,7 +495,6 @@ static int imx_gpc_probe(struct platform_device *pdev)
ret = platform_device_add(pd_pdev);
if (ret) {
platform_device_put(pd_pdev);
- of_node_put(np);
return ret;
}
}
@@ -517,7 +511,7 @@ static void imx_gpc_remove(struct platform_device *pdev)
pgc_node = of_get_child_by_name(pdev->dev.of_node, "pgc");
/* bail out if DT too old and doesn't provide the necessary info */
- if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells") &&
+ if (!of_property_present(pdev->dev.of_node, "#power-domain-cells") &&
!pgc_node)
return;
@@ -551,6 +545,6 @@ static struct platform_driver imx_gpc_driver = {
.of_match_table = imx_gpc_dt_ids,
},
.probe = imx_gpc_probe,
- .remove_new = imx_gpc_remove,
+ .remove = imx_gpc_remove,
};
builtin_platform_driver(imx_gpc_driver)
diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c
index 4b828d74a606..958d34d4821b 100644
--- a/drivers/pmdomain/imx/gpcv2.c
+++ b/drivers/pmdomain/imx/gpcv2.c
@@ -393,6 +393,17 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
* automatically there. Just add a delay and suppose the handshake finish
* after that.
*/
+
+ /*
+ * For some BLK-CTL module (eg. AudioMix on i.MX8MP) doesn't have BUS
+ * clk-en bit, it is better to add delay here, as the BLK-CTL module
+ * doesn't need to care about how it is powered up.
+ *
+ * regmap_read_bypassed() is to make sure the above write IO transaction
+ * already reaches target before udelay()
+ */
+ regmap_read_bypassed(domain->regmap, domain->regs->hsk, &reg_val);
+ udelay(10);
}
/* Disable reset clocks for all devices in the domain */
@@ -1345,7 +1356,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
ret = pm_genpd_init(&domain->genpd, NULL, true);
if (ret) {
- dev_err(domain->dev, "Failed to init power domain\n");
+ dev_err_probe(domain->dev, ret, "Failed to init power domain\n");
goto out_domain_unmap;
}
@@ -1356,7 +1367,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
ret = of_genpd_add_provider_simple(domain->dev->of_node,
&domain->genpd);
if (ret) {
- dev_err(domain->dev, "Failed to add genpd provider\n");
+ dev_err_probe(domain->dev, ret, "Failed to add genpd provider\n");
goto out_genpd_remove;
}
@@ -1426,9 +1437,10 @@ static struct platform_driver imx_pgc_domain_driver = {
.driver = {
.name = "imx-pgc",
.pm = &imx_pgc_domain_pm_ops,
+ .suppress_bind_attrs = true,
},
.probe = imx_pgc_domain_probe,
- .remove_new = imx_pgc_domain_remove,
+ .remove = imx_pgc_domain_remove,
.id_table = imx_pgc_domain_id,
};
builtin_platform_driver(imx_pgc_domain_driver)
@@ -1447,12 +1459,12 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
.max_register = SZ_4K,
};
struct device *dev = &pdev->dev;
- struct device_node *pgc_np, *np;
+ struct device_node *pgc_np __free(device_node) =
+ of_get_child_by_name(dev->of_node, "pgc");
struct regmap *regmap;
void __iomem *base;
int ret;
- pgc_np = of_get_child_by_name(dev->of_node, "pgc");
if (!pgc_np) {
dev_err(dev, "No power domains specified in DT\n");
return -EINVAL;
@@ -1469,7 +1481,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
return ret;
}
- for_each_child_of_node(pgc_np, np) {
+ for_each_child_of_node_scoped(pgc_np, np) {
struct platform_device *pd_pdev;
struct imx_pgc_domain *domain;
u32 domain_index;
@@ -1480,7 +1492,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
ret = of_property_read_u32(np, "reg", &domain_index);
if (ret) {
dev_err(dev, "Failed to read 'reg' property\n");
- of_node_put(np);
return ret;
}
@@ -1495,7 +1506,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
domain_index);
if (!pd_pdev) {
dev_err(dev, "Failed to allocate platform device\n");
- of_node_put(np);
return -ENOMEM;
}
@@ -1504,7 +1514,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
sizeof(domain_data->domains[domain_index]));
if (ret) {
platform_device_put(pd_pdev);
- of_node_put(np);
return ret;
}
@@ -1521,7 +1530,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
ret = platform_device_add(pd_pdev);
if (ret) {
platform_device_put(pd_pdev);
- of_node_put(np);
return ret;
}
}
@@ -1542,6 +1550,7 @@ static struct platform_driver imx_gpc_driver = {
.driver = {
.name = "imx-gpcv2",
.of_match_table = imx_gpcv2_dt_ids,
+ .suppress_bind_attrs = true,
},
.probe = imx_gpcv2_probe,
};
diff --git a/drivers/pmdomain/imx/imx8m-blk-ctrl.c b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
index 1341a707f61b..912802b5215b 100644
--- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c
+++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
@@ -258,11 +258,14 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
domain->power_dev =
dev_pm_domain_attach_by_name(dev, data->gpc_name);
- if (IS_ERR(domain->power_dev)) {
- dev_err_probe(dev, PTR_ERR(domain->power_dev),
+ if (IS_ERR_OR_NULL(domain->power_dev)) {
+ if (!domain->power_dev)
+ ret = -ENODEV;
+ else
+ ret = PTR_ERR(domain->power_dev);
+ dev_err_probe(dev, ret,
"failed to attach power domain \"%s\"\n",
data->gpc_name);
- ret = PTR_ERR(domain->power_dev);
goto cleanup_pds;
}
@@ -886,11 +889,12 @@ MODULE_DEVICE_TABLE(of, imx8m_blk_ctrl_of_match);
static struct platform_driver imx8m_blk_ctrl_driver = {
.probe = imx8m_blk_ctrl_probe,
- .remove_new = imx8m_blk_ctrl_remove,
+ .remove = imx8m_blk_ctrl_remove,
.driver = {
.name = "imx8m-blk-ctrl",
.pm = &imx8m_blk_ctrl_pm_ops,
.of_match_table = imx8m_blk_ctrl_of_match,
+ .suppress_bind_attrs = true,
},
};
module_platform_driver(imx8m_blk_ctrl_driver);
diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
index e3203eb6a022..34576be606e3 100644
--- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
+++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c
@@ -55,7 +55,7 @@ struct imx8mp_blk_ctrl_domain_data {
const char *gpc_name;
};
-#define DOMAIN_MAX_CLKS 2
+#define DOMAIN_MAX_CLKS 3
#define DOMAIN_MAX_PATHS 3
struct imx8mp_blk_ctrl_domain {
@@ -457,8 +457,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
},
[IMX8MP_HDMIBLK_PD_LCDIF] = {
.name = "hdmiblk-lcdif",
- .clk_names = (const char *[]){ "axi", "apb" },
- .num_clks = 2,
+ .clk_names = (const char *[]){ "axi", "apb", "fdcc" },
+ .num_clks = 3,
.gpc_name = "lcdif",
.path_names = (const char *[]){"lcdif-hdmi"},
.num_paths = 1,
@@ -483,8 +483,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
},
[IMX8MP_HDMIBLK_PD_HDMI_TX] = {
.name = "hdmiblk-hdmi-tx",
- .clk_names = (const char *[]){ "apb", "ref_266m" },
- .num_clks = 2,
+ .clk_names = (const char *[]){ "apb", "ref_266m", "fdcc" },
+ .num_clks = 3,
.gpc_name = "hdmi-tx",
},
[IMX8MP_HDMIBLK_PD_HDMI_TX_PHY] = {
@@ -687,11 +687,14 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
domain->power_dev =
dev_pm_domain_attach_by_name(dev, data->gpc_name);
- if (IS_ERR(domain->power_dev)) {
- dev_err_probe(dev, PTR_ERR(domain->power_dev),
+ if (IS_ERR_OR_NULL(domain->power_dev)) {
+ if (!domain->power_dev)
+ ret = -ENODEV;
+ else
+ ret = PTR_ERR(domain->power_dev);
+ dev_err_probe(dev, ret,
"failed to attach power domain %s\n",
data->gpc_name);
- ret = PTR_ERR(domain->power_dev);
goto cleanup_pds;
}
@@ -767,7 +770,7 @@ static void imx8mp_blk_ctrl_remove(struct platform_device *pdev)
of_genpd_del_provider(pdev->dev.of_node);
- for (i = 0; bc->onecell_data.num_domains; i++) {
+ for (i = 0; i < bc->onecell_data.num_domains; i++) {
struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i];
pm_genpd_remove(&domain->genpd);
@@ -854,11 +857,12 @@ MODULE_DEVICE_TABLE(of, imx8mp_blk_ctrl_of_match);
static struct platform_driver imx8mp_blk_ctrl_driver = {
.probe = imx8mp_blk_ctrl_probe,
- .remove_new = imx8mp_blk_ctrl_remove,
+ .remove = imx8mp_blk_ctrl_remove,
.driver = {
.name = "imx8mp-blk-ctrl",
.pm = &imx8mp_blk_ctrl_pm_ops,
.of_match_table = imx8mp_blk_ctrl_of_match,
+ .suppress_bind_attrs = true,
},
};
module_platform_driver(imx8mp_blk_ctrl_driver);
diff --git a/drivers/pmdomain/imx/imx93-blk-ctrl.c b/drivers/pmdomain/imx/imx93-blk-ctrl.c
index 904ffa55b8f4..0e2ba8ec55d7 100644
--- a/drivers/pmdomain/imx/imx93-blk-ctrl.c
+++ b/drivers/pmdomain/imx/imx93-blk-ctrl.c
@@ -313,7 +313,9 @@ static void imx93_blk_ctrl_remove(struct platform_device *pdev)
of_genpd_del_provider(pdev->dev.of_node);
- for (i = 0; bc->onecell_data.num_domains; i++) {
+ pm_runtime_disable(&pdev->dev);
+
+ for (i = 0; i < bc->onecell_data.num_domains; i++) {
struct imx93_blk_ctrl_domain *domain = &bc->domains[i];
pm_genpd_remove(&domain->genpd);
@@ -436,7 +438,7 @@ MODULE_DEVICE_TABLE(of, imx93_blk_ctrl_of_match);
static struct platform_driver imx93_blk_ctrl_driver = {
.probe = imx93_blk_ctrl_probe,
- .remove_new = imx93_blk_ctrl_remove,
+ .remove = imx93_blk_ctrl_remove,
.driver = {
.name = "imx93-blk-ctrl",
.of_match_table = imx93_blk_ctrl_of_match,
diff --git a/drivers/pmdomain/imx/imx93-pd.c b/drivers/pmdomain/imx/imx93-pd.c
index 1e94b499c19b..d68273330687 100644
--- a/drivers/pmdomain/imx/imx93-pd.c
+++ b/drivers/pmdomain/imx/imx93-pd.c
@@ -20,6 +20,7 @@
#define FUNC_STAT_PSW_STAT_MASK BIT(0)
#define FUNC_STAT_RST_STAT_MASK BIT(2)
#define FUNC_STAT_ISO_STAT_MASK BIT(4)
+#define FUNC_STAT_SSAR_STAT_MASK BIT(8)
struct imx93_power_domain {
struct generic_pm_domain genpd;
@@ -27,7 +28,6 @@ struct imx93_power_domain {
void __iomem *addr;
struct clk_bulk_data *clks;
int num_clks;
- bool init_off;
};
#define to_imx93_pd(_genpd) container_of(_genpd, struct imx93_power_domain, genpd)
@@ -50,7 +50,7 @@ static int imx93_pd_on(struct generic_pm_domain *genpd)
writel(val, addr + MIX_SLICE_SW_CTRL_OFF);
ret = readl_poll_timeout(addr + MIX_FUNC_STAT_OFF, val,
- !(val & FUNC_STAT_ISO_STAT_MASK), 1, 10000);
+ !(val & FUNC_STAT_SSAR_STAT_MASK), 1, 10000);
if (ret) {
dev_err(domain->dev, "pd_on timeout: name: %s, stat: %x\n", genpd->name, val);
return ret;
@@ -72,7 +72,7 @@ static int imx93_pd_off(struct generic_pm_domain *genpd)
writel(val, addr + MIX_SLICE_SW_CTRL_OFF);
ret = readl_poll_timeout(addr + MIX_FUNC_STAT_OFF, val,
- val & FUNC_STAT_PSW_STAT_MASK, 1, 1000);
+ val & FUNC_STAT_PSW_STAT_MASK, 1, 10000);
if (ret) {
dev_err(domain->dev, "pd_off timeout: name: %s, stat: %x\n", genpd->name, val);
return ret;
@@ -89,9 +89,6 @@ static void imx93_pd_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- if (!domain->init_off)
- clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
-
of_genpd_del_provider(np);
pm_genpd_remove(&domain->genpd);
}
@@ -101,6 +98,7 @@ static int imx93_pd_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct imx93_power_domain *domain;
+ bool init_off;
int ret;
domain = devm_kzalloc(dev, sizeof(*domain), GFP_KERNEL);
@@ -120,18 +118,17 @@ static int imx93_pd_probe(struct platform_device *pdev)
domain->genpd.power_on = imx93_pd_on;
domain->dev = dev;
- domain->init_off = readl(domain->addr + MIX_FUNC_STAT_OFF) & FUNC_STAT_ISO_STAT_MASK;
+ init_off = readl(domain->addr + MIX_FUNC_STAT_OFF) & FUNC_STAT_ISO_STAT_MASK;
/* Just to sync the status of hardware */
- if (!domain->init_off) {
+ if (!init_off) {
ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
- if (ret) {
- dev_err(domain->dev, "failed to enable clocks for domain: %s\n",
- domain->genpd.name);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(domain->dev, ret,
+ "failed to enable clocks for domain: %s\n",
+ domain->genpd.name);
}
- ret = pm_genpd_init(&domain->genpd, NULL, domain->init_off);
+ ret = pm_genpd_init(&domain->genpd, NULL, init_off);
if (ret)
goto err_clk_unprepare;
@@ -147,7 +144,7 @@ err_genpd_remove:
pm_genpd_remove(&domain->genpd);
err_clk_unprepare:
- if (!domain->init_off)
+ if (!init_off)
clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
return ret;
@@ -165,7 +162,7 @@ static struct platform_driver imx93_power_domain_driver = {
.of_match_table = imx93_pd_ids,
},
.probe = imx93_pd_probe,
- .remove_new = imx93_pd_remove,
+ .remove = imx93_pd_remove,
};
module_platform_driver(imx93_power_domain_driver);
diff --git a/drivers/pmdomain/imx/scu-pd.c b/drivers/pmdomain/imx/scu-pd.c
index 891c1d925a9d..01d465d88f60 100644
--- a/drivers/pmdomain/imx/scu-pd.c
+++ b/drivers/pmdomain/imx/scu-pd.c
@@ -223,11 +223,6 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
{ "lvds1-pwm", IMX_SC_R_LVDS_1_PWM_0, 1, false, 0 },
{ "lvds1-lpi2c", IMX_SC_R_LVDS_1_I2C_0, 2, true, 0 },
- { "mipi1", IMX_SC_R_MIPI_1, 1, 0 },
- { "mipi1-pwm0", IMX_SC_R_MIPI_1_PWM_0, 1, 0 },
- { "mipi1-i2c", IMX_SC_R_MIPI_1_I2C_0, 2, 1 },
- { "lvds1", IMX_SC_R_LVDS_1, 1, 0 },
-
/* DC SS */
{ "dc0", IMX_SC_R_DC_0, 1, false, 0 },
{ "dc0-pll", IMX_SC_R_DC_0_PLL_0, 2, true, 0 },
@@ -393,7 +388,7 @@ static int imx_sc_pd_power_off(struct generic_pm_domain *domain)
return imx_sc_pd_power(domain, false);
}
-static struct generic_pm_domain *imx_scu_pd_xlate(struct of_phandle_args *spec,
+static struct generic_pm_domain *imx_scu_pd_xlate(const struct of_phandle_args *spec,
void *data)
{
struct generic_pm_domain *domain = ERR_PTR(-ENOENT);