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> 15 #include <linux/pm_clock.h> 16 #include <linux/pm_runtime.h> 17 18 static int tegra_aconnect_add_clock(struct device *dev, char *name) 19 { 20 struct clk *clk; 21 int ret; 22 23 clk = clk_get(dev, name); 24 if (IS_ERR(clk)) { 25 dev_err(dev, "%s clock not found\n", name); 26 return PTR_ERR(clk); 27 } 28 29 ret = pm_clk_add_clk(dev, clk); 30 if (ret) 31 clk_put(clk); 32 33 return ret; 34 } 35 36 static int tegra_aconnect_probe(struct platform_device *pdev) 37 { 38 int ret; 39 40 if (!pdev->dev.of_node) 41 return -EINVAL; 42 43 ret = pm_clk_create(&pdev->dev); 44 if (ret) 45 return ret; 46 47 ret = tegra_aconnect_add_clock(&pdev->dev, "ape"); 48 if (ret) 49 goto clk_destroy; 50 51 ret = tegra_aconnect_add_clock(&pdev->dev, "apb2ape"); 52 if (ret) 53 goto clk_destroy; 54 55 pm_runtime_enable(&pdev->dev); 56 57 of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); 58 59 dev_info(&pdev->dev, "Tegra ACONNECT bus registered\n"); 60 61 return 0; 62 63 clk_destroy: 64 pm_clk_destroy(&pdev->dev); 65 66 return ret; 67 } 68 69 static int tegra_aconnect_remove(struct platform_device *pdev) 70 { 71 pm_runtime_disable(&pdev->dev); 72 73 pm_clk_destroy(&pdev->dev); 74 75 return 0; 76 } 77 78 static int tegra_aconnect_runtime_resume(struct device *dev) 79 { 80 return pm_clk_resume(dev); 81 } 82 83 static int tegra_aconnect_runtime_suspend(struct device *dev) 84 { 85 return pm_clk_suspend(dev); 86 } 87 88 static const struct dev_pm_ops tegra_aconnect_pm_ops = { 89 SET_RUNTIME_PM_OPS(tegra_aconnect_runtime_suspend, 90 tegra_aconnect_runtime_resume, NULL) 91 }; 92 93 static const struct of_device_id tegra_aconnect_of_match[] = { 94 { .compatible = "nvidia,tegra210-aconnect", }, 95 { } 96 }; 97 MODULE_DEVICE_TABLE(of, tegra_aconnect_of_match); 98 99 static struct platform_driver tegra_aconnect_driver = { 100 .probe = tegra_aconnect_probe, 101 .remove = tegra_aconnect_remove, 102 .driver = { 103 .name = "tegra-aconnect", 104 .of_match_table = tegra_aconnect_of_match, 105 .pm = &tegra_aconnect_pm_ops, 106 }, 107 }; 108 module_platform_driver(tegra_aconnect_driver); 109 110 MODULE_DESCRIPTION("NVIDIA Tegra ACONNECT Bus Driver"); 111 MODULE_AUTHOR("Jon Hunter <jonathanh@nvidia.com>"); 112 MODULE_LICENSE("GPL v2"); 113