Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Synopsys G210 Test Chip driver
0004  *
0005  * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
0006  *
0007  * Authors: Joao Pinto <jpinto@synopsys.com>
0008  */
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/of.h>
0014 #include <linux/delay.h>
0015 #include <linux/pm_runtime.h>
0016 
0017 #include "ufshcd-pltfrm.h"
0018 #include "ufshcd-dwc.h"
0019 #include "tc-dwc-g210.h"
0020 
0021 /*
0022  * UFS DWC specific variant operations
0023  */
0024 static struct ufs_hba_variant_ops tc_dwc_g210_20bit_pltfm_hba_vops = {
0025     .name                   = "tc-dwc-g210-pltfm",
0026     .link_startup_notify    = ufshcd_dwc_link_startup_notify,
0027     .phy_initialization = tc_dwc_g210_config_20_bit,
0028 };
0029 
0030 static struct ufs_hba_variant_ops tc_dwc_g210_40bit_pltfm_hba_vops = {
0031     .name                   = "tc-dwc-g210-pltfm",
0032     .link_startup_notify    = ufshcd_dwc_link_startup_notify,
0033     .phy_initialization = tc_dwc_g210_config_40_bit,
0034 };
0035 
0036 static const struct of_device_id tc_dwc_g210_pltfm_match[] = {
0037     {
0038         .compatible = "snps,g210-tc-6.00-20bit",
0039         .data = &tc_dwc_g210_20bit_pltfm_hba_vops,
0040     },
0041     {
0042         .compatible = "snps,g210-tc-6.00-40bit",
0043         .data = &tc_dwc_g210_40bit_pltfm_hba_vops,
0044     },
0045     { },
0046 };
0047 MODULE_DEVICE_TABLE(of, tc_dwc_g210_pltfm_match);
0048 
0049 /**
0050  * tc_dwc_g210_pltfm_probe()
0051  * @pdev: pointer to platform device structure
0052  *
0053  */
0054 static int tc_dwc_g210_pltfm_probe(struct platform_device *pdev)
0055 {
0056     int err;
0057     const struct of_device_id *of_id;
0058     struct ufs_hba_variant_ops *vops;
0059     struct device *dev = &pdev->dev;
0060 
0061     of_id = of_match_node(tc_dwc_g210_pltfm_match, dev->of_node);
0062     vops = (struct ufs_hba_variant_ops *)of_id->data;
0063 
0064     /* Perform generic probe */
0065     err = ufshcd_pltfrm_init(pdev, vops);
0066     if (err)
0067         dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
0068 
0069     return err;
0070 }
0071 
0072 /**
0073  * tc_dwc_g210_pltfm_remove()
0074  * @pdev: pointer to platform device structure
0075  *
0076  */
0077 static int tc_dwc_g210_pltfm_remove(struct platform_device *pdev)
0078 {
0079     struct ufs_hba *hba =  platform_get_drvdata(pdev);
0080 
0081     pm_runtime_get_sync(&(pdev)->dev);
0082     ufshcd_remove(hba);
0083 
0084     return 0;
0085 }
0086 
0087 static const struct dev_pm_ops tc_dwc_g210_pltfm_pm_ops = {
0088     SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume)
0089     SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL)
0090 };
0091 
0092 static struct platform_driver tc_dwc_g210_pltfm_driver = {
0093     .probe      = tc_dwc_g210_pltfm_probe,
0094     .remove     = tc_dwc_g210_pltfm_remove,
0095     .shutdown = ufshcd_pltfrm_shutdown,
0096     .driver     = {
0097         .name   = "tc-dwc-g210-pltfm",
0098         .pm = &tc_dwc_g210_pltfm_pm_ops,
0099         .of_match_table = of_match_ptr(tc_dwc_g210_pltfm_match),
0100     },
0101 };
0102 
0103 module_platform_driver(tc_dwc_g210_pltfm_driver);
0104 
0105 MODULE_ALIAS("platform:tc-dwc-g210-pltfm");
0106 MODULE_DESCRIPTION("Synopsys Test Chip G210 platform glue driver");
0107 MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>");
0108 MODULE_LICENSE("Dual BSD/GPL");