hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Synopsys G210 Test Chip driver
 *
 * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
 *
 * Authors: Joao Pinto <jpinto@synopsys.com>
 */
 
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/delay.h>
 
#include "ufshcd-pltfrm.h"
#include "ufshcd-dwc.h"
#include "tc-dwc-g210.h"
 
/*
 * UFS DWC specific variant operations
 */
static struct ufs_hba_variant_ops tc_dwc_g210_20bit_pltfm_hba_vops = {
   .name                   = "tc-dwc-g210-pltfm",
   .link_startup_notify    = ufshcd_dwc_link_startup_notify,
   .phy_initialization = tc_dwc_g210_config_20_bit,
};
 
static struct ufs_hba_variant_ops tc_dwc_g210_40bit_pltfm_hba_vops = {
   .name                   = "tc-dwc-g210-pltfm",
   .link_startup_notify    = ufshcd_dwc_link_startup_notify,
   .phy_initialization = tc_dwc_g210_config_40_bit,
};
 
static const struct of_device_id tc_dwc_g210_pltfm_match[] = {
   {
       .compatible = "snps,g210-tc-6.00-20bit",
       .data = &tc_dwc_g210_20bit_pltfm_hba_vops,
   },
   {
       .compatible = "snps,g210-tc-6.00-40bit",
       .data = &tc_dwc_g210_40bit_pltfm_hba_vops,
   },
   { },
};
MODULE_DEVICE_TABLE(of, tc_dwc_g210_pltfm_match);
 
/**
 * tc_dwc_g210_pltfm_probe()
 * @pdev: pointer to platform device structure
 *
 */
static int tc_dwc_g210_pltfm_probe(struct platform_device *pdev)
{
   int err;
   const struct of_device_id *of_id;
   struct ufs_hba_variant_ops *vops;
   struct device *dev = &pdev->dev;
 
   of_id = of_match_node(tc_dwc_g210_pltfm_match, dev->of_node);
   vops = (struct ufs_hba_variant_ops *)of_id->data;
 
   /* Perform generic probe */
   err = ufshcd_pltfrm_init(pdev, vops);
   if (err)
       dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
 
   return err;
}
 
/**
 * tc_dwc_g210_pltfm_remove()
 * @pdev: pointer to platform device structure
 *
 */
static int tc_dwc_g210_pltfm_remove(struct platform_device *pdev)
{
   struct ufs_hba *hba =  platform_get_drvdata(pdev);
 
   pm_runtime_get_sync(&(pdev)->dev);
   ufshcd_remove(hba);
 
   return 0;
}
 
static const struct dev_pm_ops tc_dwc_g210_pltfm_pm_ops = {
   .suspend    = ufshcd_pltfrm_suspend,
   .resume        = ufshcd_pltfrm_resume,
   .runtime_suspend = ufshcd_pltfrm_runtime_suspend,
   .runtime_resume  = ufshcd_pltfrm_runtime_resume,
   .runtime_idle    = ufshcd_pltfrm_runtime_idle,
};
 
static struct platform_driver tc_dwc_g210_pltfm_driver = {
   .probe        = tc_dwc_g210_pltfm_probe,
   .remove        = tc_dwc_g210_pltfm_remove,
   .shutdown = ufshcd_pltfrm_shutdown,
   .driver        = {
       .name    = "tc-dwc-g210-pltfm",
       .pm    = &tc_dwc_g210_pltfm_pm_ops,
       .of_match_table    = of_match_ptr(tc_dwc_g210_pltfm_match),
   },
};
 
module_platform_driver(tc_dwc_g210_pltfm_driver);
 
MODULE_ALIAS("platform:tc-dwc-g210-pltfm");
MODULE_DESCRIPTION("Synopsys Test Chip G210 platform glue driver");
MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>");
MODULE_LICENSE("Dual BSD/GPL");