Skip to content

Commit 24a1525

Browse files
digetxthierryreding
authored andcommitted
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 <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent a65a4ea commit 24a1525

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

drivers/soc/tegra/fuse/fuse-tegra.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/of.h>
1414
#include <linux/of_address.h>
1515
#include <linux/platform_device.h>
16+
#include <linux/pm_runtime.h>
1617
#include <linux/slab.h>
1718
#include <linux/sys_soc.h>
1819

@@ -210,6 +211,8 @@ static int tegra_fuse_probe(struct platform_device *pdev)
210211
platform_set_drvdata(pdev, fuse);
211212
fuse->dev = &pdev->dev;
212213

214+
pm_runtime_enable(&pdev->dev);
215+
213216
if (fuse->soc->probe) {
214217
err = fuse->soc->probe(fuse);
215218
if (err < 0)
@@ -248,13 +251,40 @@ static int tegra_fuse_probe(struct platform_device *pdev)
248251
restore:
249252
fuse->clk = NULL;
250253
fuse->base = base;
254+
pm_runtime_disable(&pdev->dev);
251255
return err;
252256
}
253257

258+
static int __maybe_unused tegra_fuse_runtime_resume(struct device *dev)
259+
{
260+
int err;
261+
262+
err = clk_prepare_enable(fuse->clk);
263+
if (err < 0) {
264+
dev_err(dev, "failed to enable FUSE clock: %d\n", err);
265+
return err;
266+
}
267+
268+
return 0;
269+
}
270+
271+
static int __maybe_unused tegra_fuse_runtime_suspend(struct device *dev)
272+
{
273+
clk_disable_unprepare(fuse->clk);
274+
275+
return 0;
276+
}
277+
278+
static const struct dev_pm_ops tegra_fuse_pm = {
279+
SET_RUNTIME_PM_OPS(tegra_fuse_runtime_suspend, tegra_fuse_runtime_resume,
280+
NULL)
281+
};
282+
254283
static struct platform_driver tegra_fuse_driver = {
255284
.driver = {
256285
.name = "tegra-fuse",
257286
.of_match_table = tegra_fuse_match,
287+
.pm = &tegra_fuse_pm,
258288
.suppress_bind_attrs = true,
259289
},
260290
.probe = tegra_fuse_probe,

drivers/soc/tegra/fuse/fuse-tegra20.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/kobject.h>
1717
#include <linux/of_device.h>
1818
#include <linux/platform_device.h>
19+
#include <linux/pm_runtime.h>
1920
#include <linux/random.h>
2021

2122
#include <soc/tegra/fuse.h>
@@ -46,6 +47,10 @@ static u32 tegra20_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
4647
u32 value = 0;
4748
int err;
4849

50+
err = pm_runtime_resume_and_get(fuse->dev);
51+
if (err)
52+
return err;
53+
4954
mutex_lock(&fuse->apbdma.lock);
5055

5156
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)
6671

6772
reinit_completion(&fuse->apbdma.wait);
6873

69-
clk_prepare_enable(fuse->clk);
70-
7174
dmaengine_submit(dma_desc);
7275
dma_async_issue_pending(fuse->apbdma.chan);
7376
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)
7881
else
7982
value = *fuse->apbdma.virt;
8083

81-
clk_disable_unprepare(fuse->clk);
82-
8384
out:
8485
mutex_unlock(&fuse->apbdma.lock);
86+
pm_runtime_put(fuse->dev);
8587
return value;
8688
}
8789

drivers/soc/tegra/fuse/fuse-tegra30.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/of_device.h>
1313
#include <linux/of_address.h>
1414
#include <linux/platform_device.h>
15+
#include <linux/pm_runtime.h>
1516
#include <linux/random.h>
1617

1718
#include <soc/tegra/fuse.h>
@@ -52,15 +53,13 @@ static u32 tegra30_fuse_read(struct tegra_fuse *fuse, unsigned int offset)
5253
u32 value;
5354
int err;
5455

55-
err = clk_prepare_enable(fuse->clk);
56-
if (err < 0) {
57-
dev_err(fuse->dev, "failed to enable FUSE clock: %d\n", err);
56+
err = pm_runtime_resume_and_get(fuse->dev);
57+
if (err)
5858
return 0;
59-
}
6059

6160
value = readl_relaxed(fuse->base + FUSE_BEGIN + offset);
6261

63-
clk_disable_unprepare(fuse->clk);
62+
pm_runtime_put(fuse->dev);
6463

6564
return value;
6665
}

0 commit comments

Comments
 (0)