aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2019-04-29 02:33:19 -0400
committerOlof Johansson <olof@lixom.net>2019-04-29 02:33:19 -0400
commitfea188820b3850268571b66cb5b4837009b3fe97 (patch)
tree361d8af084bfbd08183e810bbb9ea17a9d0c3a9d
parentaaf75f2b53b7dfbc99b85b9707ffd4115cfce7ac (diff)
parent1427736e64c3a8b513cd984332f596055a7ca196 (diff)
Merge tag 'tegra-for-5.2-bus' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into arm/drivers
bus/tegra: Changes for v5.2-rc1 This pair of patches adds support for system sleep to the ACONNECT bus found on Tegra SoCs. * tag 'tegra-for-5.2-bus' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: bus: tegra-aconnect: add system sleep callbacks bus: tegra-aconnect: use devm_clk_*() helpers Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r--drivers/bus/tegra-aconnect.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/drivers/bus/tegra-aconnect.c b/drivers/bus/tegra-aconnect.c
index 084ae286fa23..ac58142301f4 100644
--- a/drivers/bus/tegra-aconnect.c
+++ b/drivers/bus/tegra-aconnect.c
@@ -12,28 +12,38 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/of_platform.h> 13#include <linux/of_platform.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/pm_clock.h>
16#include <linux/pm_runtime.h> 15#include <linux/pm_runtime.h>
17 16
17struct tegra_aconnect {
18 struct clk *ape_clk;
19 struct clk *apb2ape_clk;
20};
21
18static int tegra_aconnect_probe(struct platform_device *pdev) 22static int tegra_aconnect_probe(struct platform_device *pdev)
19{ 23{
20 int ret; 24 struct tegra_aconnect *aconnect;
21 25
22 if (!pdev->dev.of_node) 26 if (!pdev->dev.of_node)
23 return -EINVAL; 27 return -EINVAL;
24 28
25 ret = pm_clk_create(&pdev->dev); 29 aconnect = devm_kzalloc(&pdev->dev, sizeof(struct tegra_aconnect),
26 if (ret) 30 GFP_KERNEL);
27 return ret; 31 if (!aconnect)
32 return -ENOMEM;
28 33
29 ret = of_pm_clk_add_clk(&pdev->dev, "ape"); 34 aconnect->ape_clk = devm_clk_get(&pdev->dev, "ape");
30 if (ret) 35 if (IS_ERR(aconnect->ape_clk)) {
31 goto clk_destroy; 36 dev_err(&pdev->dev, "Can't retrieve ape clock\n");
37 return PTR_ERR(aconnect->ape_clk);
38 }
32 39
33 ret = of_pm_clk_add_clk(&pdev->dev, "apb2ape"); 40 aconnect->apb2ape_clk = devm_clk_get(&pdev->dev, "apb2ape");
34 if (ret) 41 if (IS_ERR(aconnect->apb2ape_clk)) {
35 goto clk_destroy; 42 dev_err(&pdev->dev, "Can't retrieve apb2ape clock\n");
43 return PTR_ERR(aconnect->apb2ape_clk);
44 }
36 45
46 dev_set_drvdata(&pdev->dev, aconnect);
37 pm_runtime_enable(&pdev->dev); 47 pm_runtime_enable(&pdev->dev);
38 48
39 of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); 49 of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
@@ -41,35 +51,51 @@ static int tegra_aconnect_probe(struct platform_device *pdev)
41 dev_info(&pdev->dev, "Tegra ACONNECT bus registered\n"); 51 dev_info(&pdev->dev, "Tegra ACONNECT bus registered\n");
42 52
43 return 0; 53 return 0;
44
45clk_destroy:
46 pm_clk_destroy(&pdev->dev);
47
48 return ret;
49} 54}
50 55
51static int tegra_aconnect_remove(struct platform_device *pdev) 56static int tegra_aconnect_remove(struct platform_device *pdev)
52{ 57{
53 pm_runtime_disable(&pdev->dev); 58 pm_runtime_disable(&pdev->dev);
54 59
55 pm_clk_destroy(&pdev->dev);
56
57 return 0; 60 return 0;
58} 61}
59 62
60static int tegra_aconnect_runtime_resume(struct device *dev) 63static int tegra_aconnect_runtime_resume(struct device *dev)
61{ 64{
62 return pm_clk_resume(dev); 65 struct tegra_aconnect *aconnect = dev_get_drvdata(dev);
66 int ret;
67
68 ret = clk_prepare_enable(aconnect->ape_clk);
69 if (ret) {
70 dev_err(dev, "ape clk_enable failed: %d\n", ret);
71 return ret;
72 }
73
74 ret = clk_prepare_enable(aconnect->apb2ape_clk);
75 if (ret) {
76 clk_disable_unprepare(aconnect->ape_clk);
77 dev_err(dev, "apb2ape clk_enable failed: %d\n", ret);
78 return ret;
79 }
80
81 return 0;
63} 82}
64 83
65static int tegra_aconnect_runtime_suspend(struct device *dev) 84static int tegra_aconnect_runtime_suspend(struct device *dev)
66{ 85{
67 return pm_clk_suspend(dev); 86 struct tegra_aconnect *aconnect = dev_get_drvdata(dev);
87
88 clk_disable_unprepare(aconnect->ape_clk);
89 clk_disable_unprepare(aconnect->apb2ape_clk);
90
91 return 0;
68} 92}
69 93
70static const struct dev_pm_ops tegra_aconnect_pm_ops = { 94static const struct dev_pm_ops tegra_aconnect_pm_ops = {
71 SET_RUNTIME_PM_OPS(tegra_aconnect_runtime_suspend, 95 SET_RUNTIME_PM_OPS(tegra_aconnect_runtime_suspend,
72 tegra_aconnect_runtime_resume, NULL) 96 tegra_aconnect_runtime_resume, NULL)
97 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
98 pm_runtime_force_resume)
73}; 99};
74 100
75static const struct of_device_id tegra_aconnect_of_match[] = { 101static const struct of_device_id tegra_aconnect_of_match[] = {