Skip to content

Commit 923ba46

Browse files
committed
Merge tag 'for-5.15-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into clk-nvidia
Pull a Tegra clk driver cleanup from Thierry Reding: The FUSE driver has been updated to take manual control of the FUSE clock over suspend/resume cycles, so the CLK_IS_CRITICAL flag can now be dropped. * tag 'for-5.15-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: clk: tegra: Remove CLK_IS_CRITICAL flag from fuse clock soc/tegra: fuse: Enable fuse clock on suspend for Tegra124 soc/tegra: fuse: Add runtime PM support soc/tegra: fuse: Clear fuse->clk on driver probe failure soc/tegra: pmc: Prevent racing with cpuilde driver soc/tegra: bpmp: Remove unused including <linux/version.h>
2 parents e73f0f0 + faa8605 commit 923ba46

File tree

11 files changed

+101
-25
lines changed

11 files changed

+101
-25
lines changed

arch/arm/mach-tegra/pm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ static const struct platform_suspend_ops tegra_suspend_ops = {
403403
.enter = tegra_suspend_enter,
404404
};
405405

406-
void __init tegra_init_suspend(void)
406+
void tegra_pm_init_suspend(void)
407407
{
408408
enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
409409

arch/arm/mach-tegra/pm.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,4 @@ void tegra30_sleep_core_init(void);
2525

2626
extern void (*tegra_tear_down_cpu)(void);
2727

28-
#ifdef CONFIG_PM_SLEEP
29-
void tegra_init_suspend(void);
30-
#else
31-
static inline void tegra_init_suspend(void) {}
32-
#endif
33-
3428
#endif /* _MACH_TEGRA_PM_H_ */

arch/arm/mach-tegra/tegra.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ static void __init tegra_dt_init(void)
8484

8585
static void __init tegra_dt_init_late(void)
8686
{
87-
tegra_init_suspend();
88-
8987
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
9088
of_machine_is_compatible("compal,paz00"))
9189
tegra_paz00_wifikill_init();

drivers/clk/tegra/clk-tegra-periph.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -777,11 +777,7 @@ static struct tegra_periph_init_data gate_clks[] = {
777777
GATE("ahbdma", "hclk", 33, 0, tegra_clk_ahbdma, 0),
778778
GATE("apbdma", "pclk", 34, 0, tegra_clk_apbdma, 0),
779779
GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0),
780-
/*
781-
* Critical for RAM re-repair operation, which must occur on resume
782-
* from LP1 system suspend and as part of CCPLEX cluster switching.
783-
*/
784-
GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, CLK_IS_CRITICAL),
780+
GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0),
785781
GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0),
786782
GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0),
787783
GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0),

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

Lines changed: 60 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)
@@ -246,14 +249,71 @@ static int tegra_fuse_probe(struct platform_device *pdev)
246249
return 0;
247250

248251
restore:
252+
fuse->clk = NULL;
249253
fuse->base = base;
254+
pm_runtime_disable(&pdev->dev);
250255
return err;
251256
}
252257

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 int __maybe_unused tegra_fuse_suspend(struct device *dev)
279+
{
280+
int ret;
281+
282+
/*
283+
* Critical for RAM re-repair operation, which must occur on resume
284+
* from LP1 system suspend and as part of CCPLEX cluster switching.
285+
*/
286+
if (fuse->soc->clk_suspend_on)
287+
ret = pm_runtime_resume_and_get(dev);
288+
else
289+
ret = pm_runtime_force_suspend(dev);
290+
291+
return ret;
292+
}
293+
294+
static int __maybe_unused tegra_fuse_resume(struct device *dev)
295+
{
296+
int ret = 0;
297+
298+
if (fuse->soc->clk_suspend_on)
299+
pm_runtime_put(dev);
300+
else
301+
ret = pm_runtime_force_resume(dev);
302+
303+
return ret;
304+
}
305+
306+
static const struct dev_pm_ops tegra_fuse_pm = {
307+
SET_RUNTIME_PM_OPS(tegra_fuse_runtime_suspend, tegra_fuse_runtime_resume,
308+
NULL)
309+
SET_SYSTEM_SLEEP_PM_OPS(tegra_fuse_suspend, tegra_fuse_resume)
310+
};
311+
253312
static struct platform_driver tegra_fuse_driver = {
254313
.driver = {
255314
.name = "tegra-fuse",
256315
.of_match_table = tegra_fuse_match,
316+
.pm = &tegra_fuse_pm,
257317
.suppress_bind_attrs = true,
258318
},
259319
.probe = tegra_fuse_probe,

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

Lines changed: 7 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

@@ -165,4 +167,5 @@ const struct tegra_fuse_soc tegra20_fuse_soc = {
165167
.probe = tegra20_fuse_probe,
166168
.info = &tegra20_fuse_info,
167169
.soc_attr_group = &tegra_soc_attr_group,
170+
.clk_suspend_on = false,
168171
};

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

Lines changed: 11 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
}
@@ -113,6 +112,7 @@ const struct tegra_fuse_soc tegra30_fuse_soc = {
113112
.speedo_init = tegra30_init_speedo_data,
114113
.info = &tegra30_fuse_info,
115114
.soc_attr_group = &tegra_soc_attr_group,
115+
.clk_suspend_on = false,
116116
};
117117
#endif
118118

@@ -128,6 +128,7 @@ const struct tegra_fuse_soc tegra114_fuse_soc = {
128128
.speedo_init = tegra114_init_speedo_data,
129129
.info = &tegra114_fuse_info,
130130
.soc_attr_group = &tegra_soc_attr_group,
131+
.clk_suspend_on = false,
131132
};
132133
#endif
133134

@@ -209,6 +210,7 @@ const struct tegra_fuse_soc tegra124_fuse_soc = {
209210
.lookups = tegra124_fuse_lookups,
210211
.num_lookups = ARRAY_SIZE(tegra124_fuse_lookups),
211212
.soc_attr_group = &tegra_soc_attr_group,
213+
.clk_suspend_on = true,
212214
};
213215
#endif
214216

@@ -295,6 +297,7 @@ const struct tegra_fuse_soc tegra210_fuse_soc = {
295297
.lookups = tegra210_fuse_lookups,
296298
.num_lookups = ARRAY_SIZE(tegra210_fuse_lookups),
297299
.soc_attr_group = &tegra_soc_attr_group,
300+
.clk_suspend_on = false,
298301
};
299302
#endif
300303

@@ -325,6 +328,7 @@ const struct tegra_fuse_soc tegra186_fuse_soc = {
325328
.lookups = tegra186_fuse_lookups,
326329
.num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
327330
.soc_attr_group = &tegra_soc_attr_group,
331+
.clk_suspend_on = false,
328332
};
329333
#endif
330334

@@ -355,6 +359,7 @@ const struct tegra_fuse_soc tegra194_fuse_soc = {
355359
.lookups = tegra194_fuse_lookups,
356360
.num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
357361
.soc_attr_group = &tegra194_soc_attr_group,
362+
.clk_suspend_on = false,
358363
};
359364
#endif
360365

@@ -385,5 +390,6 @@ const struct tegra_fuse_soc tegra234_fuse_soc = {
385390
.lookups = tegra234_fuse_lookups,
386391
.num_lookups = ARRAY_SIZE(tegra234_fuse_lookups),
387392
.soc_attr_group = &tegra194_soc_attr_group,
393+
.clk_suspend_on = false,
388394
};
389395
#endif

drivers/soc/tegra/fuse/fuse.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ struct tegra_fuse_soc {
3434
unsigned int num_lookups;
3535

3636
const struct attribute_group *soc_attr_group;
37+
38+
bool clk_suspend_on;
3739
};
3840

3941
struct tegra_fuse {

drivers/soc/tegra/pmc.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ struct tegra_pmc {
436436

437437
static struct tegra_pmc *pmc = &(struct tegra_pmc) {
438438
.base = NULL,
439-
.suspend_mode = TEGRA_SUSPEND_NONE,
439+
.suspend_mode = TEGRA_SUSPEND_NOT_READY,
440440
};
441441

442442
static inline struct tegra_powergate *
@@ -1812,6 +1812,7 @@ static int tegra_pmc_parse_dt(struct tegra_pmc *pmc, struct device_node *np)
18121812
u32 value, values[2];
18131813

18141814
if (of_property_read_u32(np, "nvidia,suspend-mode", &value)) {
1815+
pmc->suspend_mode = TEGRA_SUSPEND_NONE;
18151816
} else {
18161817
switch (value) {
18171818
case 0:
@@ -2785,6 +2786,11 @@ static int tegra_pmc_regmap_init(struct tegra_pmc *pmc)
27852786
return 0;
27862787
}
27872788

2789+
static void tegra_pmc_reset_suspend_mode(void *data)
2790+
{
2791+
pmc->suspend_mode = TEGRA_SUSPEND_NOT_READY;
2792+
}
2793+
27882794
static int tegra_pmc_probe(struct platform_device *pdev)
27892795
{
27902796
void __iomem *base;
@@ -2803,6 +2809,11 @@ static int tegra_pmc_probe(struct platform_device *pdev)
28032809
if (err < 0)
28042810
return err;
28052811

2812+
err = devm_add_action_or_reset(&pdev->dev, tegra_pmc_reset_suspend_mode,
2813+
NULL);
2814+
if (err)
2815+
return err;
2816+
28062817
/* take over the memory region from the early initialization */
28072818
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
28082819
base = devm_ioremap_resource(&pdev->dev, res);
@@ -2909,6 +2920,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
29092920

29102921
tegra_pmc_clock_register(pmc, pdev->dev.of_node);
29112922
platform_set_drvdata(pdev, pmc);
2923+
tegra_pm_init_suspend();
29122924

29132925
return 0;
29142926

drivers/soc/tegra/powergate-bpmp.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <linux/platform_device.h>
88
#include <linux/pm_domain.h>
99
#include <linux/slab.h>
10-
#include <linux/version.h>
1110

1211
#include <soc/tegra/bpmp.h>
1312
#include <soc/tegra/bpmp-abi.h>

0 commit comments

Comments
 (0)