mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 05:44:11 +00:00
soc/tegra: fuse: Add runtime PM support
The Tegra FUSE belongs to the core power domain and we're going to enable GENPD support for the core domain. Now FUSE device must be resumed using runtime PM API in order to initialize the FUSE power state. Add runtime PM support to the FUSE driver. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
a65a4ea156
commit
24a15252ff
3 changed files with 40 additions and 9 deletions
|
@ -13,6 +13,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sys_soc.h>
|
||||
|
||||
|
@ -210,6 +211,8 @@ static int tegra_fuse_probe(struct platform_device *pdev)
|
|||
platform_set_drvdata(pdev, fuse);
|
||||
fuse->dev = &pdev->dev;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
if (fuse->soc->probe) {
|
||||
err = fuse->soc->probe(fuse);
|
||||
if (err < 0)
|
||||
|
@ -248,13 +251,40 @@ static int tegra_fuse_probe(struct platform_device *pdev)
|
|||
restore:
|
||||
fuse->clk = NULL;
|
||||
fuse->base = base;
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __maybe_unused tegra_fuse_runtime_resume(struct device *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = clk_prepare_enable(fuse->clk);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "failed to enable FUSE clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused tegra_fuse_runtime_suspend(struct device *dev)
|
||||
{
|
||||
clk_disable_unprepare(fuse->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops tegra_fuse_pm = {
|
||||
SET_RUNTIME_PM_OPS(tegra_fuse_runtime_suspend, tegra_fuse_runtime_resume,
|
||||
NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver tegra_fuse_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-fuse",
|
||||
.of_match_table = tegra_fuse_match,
|
||||
.pm = &tegra_fuse_pm,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = tegra_fuse_probe,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/kobject.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
@ -46,6 +47,10 @@ static u32 tegra20_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
|
|||
u32 value = 0;
|
||||
int err;
|
||||
|
||||
err = pm_runtime_resume_and_get(fuse->dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mutex_lock(&fuse->apbdma.lock);
|
||||
|
||||
fuse->apbdma.config.src_addr = fuse->phys + FUSE_BEGIN + offset;
|
||||
|
@ -66,8 +71,6 @@ static u32 tegra20_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
|
|||
|
||||
reinit_completion(&fuse->apbdma.wait);
|
||||
|
||||
clk_prepare_enable(fuse->clk);
|
||||
|
||||
dmaengine_submit(dma_desc);
|
||||
dma_async_issue_pending(fuse->apbdma.chan);
|
||||
time_left = wait_for_completion_timeout(&fuse->apbdma.wait,
|
||||
|
@ -78,10 +81,9 @@ static u32 tegra20_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
|
|||
else
|
||||
value = *fuse->apbdma.virt;
|
||||
|
||||
clk_disable_unprepare(fuse->clk);
|
||||
|
||||
out:
|
||||
mutex_unlock(&fuse->apbdma.lock);
|
||||
pm_runtime_put(fuse->dev);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
@ -52,15 +53,13 @@ static u32 tegra30_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
|
|||
u32 value;
|
||||
int err;
|
||||
|
||||
err = clk_prepare_enable(fuse->clk);
|
||||
if (err < 0) {
|
||||
dev_err(fuse->dev, "failed to enable FUSE clock: %d\n", err);
|
||||
err = pm_runtime_resume_and_get(fuse->dev);
|
||||
if (err)
|
||||
return 0;
|
||||
}
|
||||
|
||||
value = readl_relaxed(fuse->base + FUSE_BEGIN + offset);
|
||||
|
||||
clk_disable_unprepare(fuse->clk);
|
||||
pm_runtime_put(fuse->dev);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue