Commit | Line | Data |
---|---|---|
46a88534 JH |
1 | /* |
2 | * Tegra ACONNECT Bus Driver | |
3 | * | |
4 | * Copyright (C) 2016, NVIDIA CORPORATION. All rights reserved. | |
5 | * | |
6 | * This file is subject to the terms and conditions of the GNU General Public | |
7 | * License. See the file "COPYING" in the main directory of this archive | |
8 | * for more details. | |
9 | */ | |
10 | ||
11 | #include <linux/clk.h> | |
12 | #include <linux/module.h> | |
13 | #include <linux/of_platform.h> | |
14 | #include <linux/platform_device.h> | |
46a88534 JH |
15 | #include <linux/pm_runtime.h> |
16 | ||
0d7dab92 SP |
17 | struct tegra_aconnect { |
18 | struct clk *ape_clk; | |
19 | struct clk *apb2ape_clk; | |
20 | }; | |
21 | ||
46a88534 JH |
22 | static int tegra_aconnect_probe(struct platform_device *pdev) |
23 | { | |
0d7dab92 | 24 | struct tegra_aconnect *aconnect; |
46a88534 JH |
25 | |
26 | if (!pdev->dev.of_node) | |
27 | return -EINVAL; | |
28 | ||
0d7dab92 SP |
29 | aconnect = devm_kzalloc(&pdev->dev, sizeof(struct tegra_aconnect), |
30 | GFP_KERNEL); | |
31 | if (!aconnect) | |
32 | return -ENOMEM; | |
46a88534 | 33 | |
0d7dab92 SP |
34 | aconnect->ape_clk = devm_clk_get(&pdev->dev, "ape"); |
35 | if (IS_ERR(aconnect->ape_clk)) { | |
36 | dev_err(&pdev->dev, "Can't retrieve ape clock\n"); | |
37 | return PTR_ERR(aconnect->ape_clk); | |
38 | } | |
46a88534 | 39 | |
0d7dab92 SP |
40 | aconnect->apb2ape_clk = devm_clk_get(&pdev->dev, "apb2ape"); |
41 | if (IS_ERR(aconnect->apb2ape_clk)) { | |
42 | dev_err(&pdev->dev, "Can't retrieve apb2ape clock\n"); | |
43 | return PTR_ERR(aconnect->apb2ape_clk); | |
44 | } | |
46a88534 | 45 | |
0d7dab92 | 46 | dev_set_drvdata(&pdev->dev, aconnect); |
46a88534 JH |
47 | pm_runtime_enable(&pdev->dev); |
48 | ||
49 | of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); | |
50 | ||
51 | dev_info(&pdev->dev, "Tegra ACONNECT bus registered\n"); | |
52 | ||
53 | return 0; | |
46a88534 JH |
54 | } |
55 | ||
f54ba5ef | 56 | static void tegra_aconnect_remove(struct platform_device *pdev) |
46a88534 JH |
57 | { |
58 | pm_runtime_disable(&pdev->dev); | |
46a88534 JH |
59 | } |
60 | ||
61 | static int tegra_aconnect_runtime_resume(struct device *dev) | |
62 | { | |
0d7dab92 SP |
63 | struct tegra_aconnect *aconnect = dev_get_drvdata(dev); |
64 | int ret; | |
65 | ||
66 | ret = clk_prepare_enable(aconnect->ape_clk); | |
67 | if (ret) { | |
68 | dev_err(dev, "ape clk_enable failed: %d\n", ret); | |
69 | return ret; | |
70 | } | |
71 | ||
72 | ret = clk_prepare_enable(aconnect->apb2ape_clk); | |
73 | if (ret) { | |
74 | clk_disable_unprepare(aconnect->ape_clk); | |
75 | dev_err(dev, "apb2ape clk_enable failed: %d\n", ret); | |
76 | return ret; | |
77 | } | |
78 | ||
79 | return 0; | |
46a88534 JH |
80 | } |
81 | ||
82 | static int tegra_aconnect_runtime_suspend(struct device *dev) | |
83 | { | |
0d7dab92 SP |
84 | struct tegra_aconnect *aconnect = dev_get_drvdata(dev); |
85 | ||
86 | clk_disable_unprepare(aconnect->ape_clk); | |
87 | clk_disable_unprepare(aconnect->apb2ape_clk); | |
88 | ||
89 | return 0; | |
46a88534 JH |
90 | } |
91 | ||
92 | static const struct dev_pm_ops tegra_aconnect_pm_ops = { | |
93 | SET_RUNTIME_PM_OPS(tegra_aconnect_runtime_suspend, | |
94 | tegra_aconnect_runtime_resume, NULL) | |
1427736e SP |
95 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
96 | pm_runtime_force_resume) | |
46a88534 JH |
97 | }; |
98 | ||
99 | static const struct of_device_id tegra_aconnect_of_match[] = { | |
100 | { .compatible = "nvidia,tegra210-aconnect", }, | |
101 | { } | |
102 | }; | |
103 | MODULE_DEVICE_TABLE(of, tegra_aconnect_of_match); | |
104 | ||
105 | static struct platform_driver tegra_aconnect_driver = { | |
106 | .probe = tegra_aconnect_probe, | |
f54ba5ef | 107 | .remove_new = tegra_aconnect_remove, |
46a88534 JH |
108 | .driver = { |
109 | .name = "tegra-aconnect", | |
110 | .of_match_table = tegra_aconnect_of_match, | |
111 | .pm = &tegra_aconnect_pm_ops, | |
112 | }, | |
113 | }; | |
114 | module_platform_driver(tegra_aconnect_driver); | |
115 | ||
116 | MODULE_DESCRIPTION("NVIDIA Tegra ACONNECT Bus Driver"); | |
117 | MODULE_AUTHOR("Jon Hunter <jonathanh@nvidia.com>"); | |
118 | MODULE_LICENSE("GPL v2"); |