1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2016, NVIDIA Corporation
7 #include <linux/module.h>
8 #include <linux/of_device.h>
9 #include <linux/reset.h>
11 #include <linux/usb/chipidea.h>
16 struct ci_hdrc_platform_data data
;
17 struct platform_device
*dev
;
23 struct tegra_udc_soc_info
{
27 static const struct tegra_udc_soc_info tegra_udc_soc_info
= {
28 .flags
= CI_HDRC_REQUIRES_ALIGNED_DMA
,
31 static const struct of_device_id tegra_udc_of_match
[] = {
33 .compatible
= "nvidia,tegra20-udc",
34 .data
= &tegra_udc_soc_info
,
36 .compatible
= "nvidia,tegra30-udc",
37 .data
= &tegra_udc_soc_info
,
39 .compatible
= "nvidia,tegra114-udc",
40 .data
= &tegra_udc_soc_info
,
42 .compatible
= "nvidia,tegra124-udc",
43 .data
= &tegra_udc_soc_info
,
48 MODULE_DEVICE_TABLE(of
, tegra_udc_of_match
);
50 static int tegra_udc_probe(struct platform_device
*pdev
)
52 const struct tegra_udc_soc_info
*soc
;
53 struct tegra_udc
*udc
;
56 udc
= devm_kzalloc(&pdev
->dev
, sizeof(*udc
), GFP_KERNEL
);
60 soc
= of_device_get_match_data(&pdev
->dev
);
62 dev_err(&pdev
->dev
, "failed to match OF data\n");
66 udc
->phy
= devm_usb_get_phy_by_phandle(&pdev
->dev
, "nvidia,phy", 0);
67 if (IS_ERR(udc
->phy
)) {
68 err
= PTR_ERR(udc
->phy
);
69 dev_err(&pdev
->dev
, "failed to get PHY: %d\n", err
);
73 udc
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
74 if (IS_ERR(udc
->clk
)) {
75 err
= PTR_ERR(udc
->clk
);
76 dev_err(&pdev
->dev
, "failed to get clock: %d\n", err
);
80 err
= clk_prepare_enable(udc
->clk
);
82 dev_err(&pdev
->dev
, "failed to enable clock: %d\n", err
);
87 * Tegra's USB PHY driver doesn't implement optional phy_init()
88 * hook, so we have to power on UDC controller before ChipIdea
89 * driver initialization kicks in.
91 usb_phy_set_suspend(udc
->phy
, 0);
93 /* setup and register ChipIdea HDRC device */
94 udc
->data
.name
= "tegra-udc";
95 udc
->data
.flags
= soc
->flags
;
96 udc
->data
.usb_phy
= udc
->phy
;
97 udc
->data
.capoffset
= DEF_CAPOFFSET
;
99 udc
->dev
= ci_hdrc_add_device(&pdev
->dev
, pdev
->resource
,
100 pdev
->num_resources
, &udc
->data
);
101 if (IS_ERR(udc
->dev
)) {
102 err
= PTR_ERR(udc
->dev
);
103 dev_err(&pdev
->dev
, "failed to add HDRC device: %d\n", err
);
107 platform_set_drvdata(pdev
, udc
);
112 usb_phy_set_suspend(udc
->phy
, 1);
113 clk_disable_unprepare(udc
->clk
);
117 static int tegra_udc_remove(struct platform_device
*pdev
)
119 struct tegra_udc
*udc
= platform_get_drvdata(pdev
);
121 ci_hdrc_remove_device(udc
->dev
);
122 usb_phy_set_suspend(udc
->phy
, 1);
123 clk_disable_unprepare(udc
->clk
);
128 static struct platform_driver tegra_udc_driver
= {
131 .of_match_table
= tegra_udc_of_match
,
133 .probe
= tegra_udc_probe
,
134 .remove
= tegra_udc_remove
,
136 module_platform_driver(tegra_udc_driver
);
138 MODULE_DESCRIPTION("NVIDIA Tegra USB device mode driver");
139 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
140 MODULE_ALIAS("platform:tegra-udc");
141 MODULE_LICENSE("GPL v2");