Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Tegra ACONNECT Bus Driver
0003  *
0004  * Copyright (C) 2016, NVIDIA CORPORATION.  All rights reserved.
0005  *
0006  * This file is subject to the terms and conditions of the GNU General Public
0007  * License.  See the file "COPYING" in the main directory of this archive
0008  * for more details.
0009  */
0010 
0011 #include <linux/clk.h>
0012 #include <linux/module.h>
0013 #include <linux/of_platform.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/pm_runtime.h>
0016 
0017 struct tegra_aconnect {
0018     struct clk  *ape_clk;
0019     struct clk  *apb2ape_clk;
0020 };
0021 
0022 static int tegra_aconnect_probe(struct platform_device *pdev)
0023 {
0024     struct tegra_aconnect *aconnect;
0025 
0026     if (!pdev->dev.of_node)
0027         return -EINVAL;
0028 
0029     aconnect = devm_kzalloc(&pdev->dev, sizeof(struct tegra_aconnect),
0030                 GFP_KERNEL);
0031     if (!aconnect)
0032         return -ENOMEM;
0033 
0034     aconnect->ape_clk = devm_clk_get(&pdev->dev, "ape");
0035     if (IS_ERR(aconnect->ape_clk)) {
0036         dev_err(&pdev->dev, "Can't retrieve ape clock\n");
0037         return PTR_ERR(aconnect->ape_clk);
0038     }
0039 
0040     aconnect->apb2ape_clk = devm_clk_get(&pdev->dev, "apb2ape");
0041     if (IS_ERR(aconnect->apb2ape_clk)) {
0042         dev_err(&pdev->dev, "Can't retrieve apb2ape clock\n");
0043         return PTR_ERR(aconnect->apb2ape_clk);
0044     }
0045 
0046     dev_set_drvdata(&pdev->dev, aconnect);
0047     pm_runtime_enable(&pdev->dev);
0048 
0049     of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
0050 
0051     dev_info(&pdev->dev, "Tegra ACONNECT bus registered\n");
0052 
0053     return 0;
0054 }
0055 
0056 static int tegra_aconnect_remove(struct platform_device *pdev)
0057 {
0058     pm_runtime_disable(&pdev->dev);
0059 
0060     return 0;
0061 }
0062 
0063 static int tegra_aconnect_runtime_resume(struct device *dev)
0064 {
0065     struct tegra_aconnect *aconnect = dev_get_drvdata(dev);
0066     int ret;
0067 
0068     ret = clk_prepare_enable(aconnect->ape_clk);
0069     if (ret) {
0070         dev_err(dev, "ape clk_enable failed: %d\n", ret);
0071         return ret;
0072     }
0073 
0074     ret = clk_prepare_enable(aconnect->apb2ape_clk);
0075     if (ret) {
0076         clk_disable_unprepare(aconnect->ape_clk);
0077         dev_err(dev, "apb2ape clk_enable failed: %d\n", ret);
0078         return ret;
0079     }
0080 
0081     return 0;
0082 }
0083 
0084 static int tegra_aconnect_runtime_suspend(struct device *dev)
0085 {
0086     struct tegra_aconnect *aconnect = dev_get_drvdata(dev);
0087 
0088     clk_disable_unprepare(aconnect->ape_clk);
0089     clk_disable_unprepare(aconnect->apb2ape_clk);
0090 
0091     return 0;
0092 }
0093 
0094 static const struct dev_pm_ops tegra_aconnect_pm_ops = {
0095     SET_RUNTIME_PM_OPS(tegra_aconnect_runtime_suspend,
0096                tegra_aconnect_runtime_resume, NULL)
0097     SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
0098                       pm_runtime_force_resume)
0099 };
0100 
0101 static const struct of_device_id tegra_aconnect_of_match[] = {
0102     { .compatible = "nvidia,tegra210-aconnect", },
0103     { }
0104 };
0105 MODULE_DEVICE_TABLE(of, tegra_aconnect_of_match);
0106 
0107 static struct platform_driver tegra_aconnect_driver = {
0108     .probe = tegra_aconnect_probe,
0109     .remove = tegra_aconnect_remove,
0110     .driver = {
0111         .name = "tegra-aconnect",
0112         .of_match_table = tegra_aconnect_of_match,
0113         .pm = &tegra_aconnect_pm_ops,
0114     },
0115 };
0116 module_platform_driver(tegra_aconnect_driver);
0117 
0118 MODULE_DESCRIPTION("NVIDIA Tegra ACONNECT Bus Driver");
0119 MODULE_AUTHOR("Jon Hunter <jonathanh@nvidia.com>");
0120 MODULE_LICENSE("GPL v2");