mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
soc: rockchip: amp: support Power Domain protection.
For some rockchip SOCs, Power Domain protection is supported in AMP system. Signed-off-by: Steven Liu <steven.liu@rock-chips.com> Change-Id: I1e0cbde37df44dba466fc580b7f67d0053d09e3d
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/rockchip/rockchip_sip.h>
|
||||
|
||||
#define RK_CPU_STATUS_OFF 0
|
||||
@@ -31,6 +33,8 @@ struct rkamp_device {
|
||||
struct device *dev;
|
||||
struct clk_bulk_data *clks;
|
||||
int num_clks;
|
||||
struct device **pd_dev;
|
||||
int num_pds;
|
||||
};
|
||||
|
||||
static struct {
|
||||
@@ -233,6 +237,33 @@ static int rockchip_amp_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret, "failed to prepare enable clks: %d\n", ret);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
rkamp_dev->num_pds = of_count_phandle_with_args(pdev->dev.of_node, "power-domains",
|
||||
"#power-domain-cells");
|
||||
|
||||
if (rkamp_dev->num_pds > 0) {
|
||||
rkamp_dev->pd_dev = devm_kmalloc_array(&pdev->dev, rkamp_dev->num_pds,
|
||||
sizeof(*rkamp_dev->pd_dev), GFP_KERNEL);
|
||||
if (!rkamp_dev->pd_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
if (rkamp_dev->num_pds == 1) {
|
||||
ret = pm_runtime_resume_and_get(&pdev->dev);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"failed to get power-domain\n");
|
||||
} else {
|
||||
for (i = 0; i < rkamp_dev->num_pds; i++) {
|
||||
rkamp_dev->pd_dev[i] = dev_pm_domain_attach_by_id(&pdev->dev, i);
|
||||
ret = pm_runtime_resume_and_get(rkamp_dev->pd_dev[i]);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"failed to get pd_dev[%d]\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cpus_node = of_get_child_by_name(pdev->dev.of_node, "amp-cpus");
|
||||
|
||||
if (cpus_node) {
|
||||
@@ -259,11 +290,23 @@ static int rockchip_amp_probe(struct platform_device *pdev)
|
||||
|
||||
static int rockchip_amp_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
struct rkamp_device *rkamp_dev = platform_get_drvdata(pdev);
|
||||
|
||||
clk_bulk_disable_unprepare(rkamp_dev->num_clks, rkamp_dev->clks);
|
||||
|
||||
if (rkamp_dev->num_pds == 1) {
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
} else if (rkamp_dev->num_pds > 1) {
|
||||
for (i = 0; i < rkamp_dev->num_pds; i++) {
|
||||
pm_runtime_put_sync(rkamp_dev->pd_dev[i]);
|
||||
dev_pm_domain_detach(rkamp_dev->pd_dev[i], true);
|
||||
rkamp_dev->pd_dev[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rk_amp_attrs); i++)
|
||||
sysfs_remove_file(rk_amp_kobj, &rk_amp_attrs[i].attr);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user