0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/kernel.h>
0013 #include <linux/slab.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/clk.h>
0016 #include <linux/of.h>
0017 #include <linux/of_platform.h>
0018 #include <linux/regulator/consumer.h>
0019
0020 #define DWC3_EXYNOS_MAX_CLOCKS 4
0021
0022 struct dwc3_exynos_driverdata {
0023 const char *clk_names[DWC3_EXYNOS_MAX_CLOCKS];
0024 int num_clks;
0025 int suspend_clk_idx;
0026 };
0027
0028 struct dwc3_exynos {
0029 struct device *dev;
0030
0031 const char **clk_names;
0032 struct clk *clks[DWC3_EXYNOS_MAX_CLOCKS];
0033 int num_clks;
0034 int suspend_clk_idx;
0035
0036 struct regulator *vdd33;
0037 struct regulator *vdd10;
0038 };
0039
0040 static int dwc3_exynos_remove_child(struct device *dev, void *unused)
0041 {
0042 struct platform_device *pdev = to_platform_device(dev);
0043
0044 platform_device_unregister(pdev);
0045
0046 return 0;
0047 }
0048
0049 static int dwc3_exynos_probe(struct platform_device *pdev)
0050 {
0051 struct dwc3_exynos *exynos;
0052 struct device *dev = &pdev->dev;
0053 struct device_node *node = dev->of_node;
0054 const struct dwc3_exynos_driverdata *driver_data;
0055 int i, ret;
0056
0057 exynos = devm_kzalloc(dev, sizeof(*exynos), GFP_KERNEL);
0058 if (!exynos)
0059 return -ENOMEM;
0060
0061 driver_data = of_device_get_match_data(dev);
0062 exynos->dev = dev;
0063 exynos->num_clks = driver_data->num_clks;
0064 exynos->clk_names = (const char **)driver_data->clk_names;
0065 exynos->suspend_clk_idx = driver_data->suspend_clk_idx;
0066
0067 platform_set_drvdata(pdev, exynos);
0068
0069 for (i = 0; i < exynos->num_clks; i++) {
0070 exynos->clks[i] = devm_clk_get(dev, exynos->clk_names[i]);
0071 if (IS_ERR(exynos->clks[i])) {
0072 dev_err(dev, "failed to get clock: %s\n",
0073 exynos->clk_names[i]);
0074 return PTR_ERR(exynos->clks[i]);
0075 }
0076 }
0077
0078 for (i = 0; i < exynos->num_clks; i++) {
0079 ret = clk_prepare_enable(exynos->clks[i]);
0080 if (ret) {
0081 while (i-- > 0)
0082 clk_disable_unprepare(exynos->clks[i]);
0083 return ret;
0084 }
0085 }
0086
0087 if (exynos->suspend_clk_idx >= 0)
0088 clk_prepare_enable(exynos->clks[exynos->suspend_clk_idx]);
0089
0090 exynos->vdd33 = devm_regulator_get(dev, "vdd33");
0091 if (IS_ERR(exynos->vdd33)) {
0092 ret = PTR_ERR(exynos->vdd33);
0093 goto vdd33_err;
0094 }
0095 ret = regulator_enable(exynos->vdd33);
0096 if (ret) {
0097 dev_err(dev, "Failed to enable VDD33 supply\n");
0098 goto vdd33_err;
0099 }
0100
0101 exynos->vdd10 = devm_regulator_get(dev, "vdd10");
0102 if (IS_ERR(exynos->vdd10)) {
0103 ret = PTR_ERR(exynos->vdd10);
0104 goto vdd10_err;
0105 }
0106 ret = regulator_enable(exynos->vdd10);
0107 if (ret) {
0108 dev_err(dev, "Failed to enable VDD10 supply\n");
0109 goto vdd10_err;
0110 }
0111
0112 if (node) {
0113 ret = of_platform_populate(node, NULL, NULL, dev);
0114 if (ret) {
0115 dev_err(dev, "failed to add dwc3 core\n");
0116 goto populate_err;
0117 }
0118 } else {
0119 dev_err(dev, "no device node, failed to add dwc3 core\n");
0120 ret = -ENODEV;
0121 goto populate_err;
0122 }
0123
0124 return 0;
0125
0126 populate_err:
0127 regulator_disable(exynos->vdd10);
0128 vdd10_err:
0129 regulator_disable(exynos->vdd33);
0130 vdd33_err:
0131 for (i = exynos->num_clks - 1; i >= 0; i--)
0132 clk_disable_unprepare(exynos->clks[i]);
0133
0134 if (exynos->suspend_clk_idx >= 0)
0135 clk_disable_unprepare(exynos->clks[exynos->suspend_clk_idx]);
0136
0137 return ret;
0138 }
0139
0140 static int dwc3_exynos_remove(struct platform_device *pdev)
0141 {
0142 struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
0143 int i;
0144
0145 device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
0146
0147 for (i = exynos->num_clks - 1; i >= 0; i--)
0148 clk_disable_unprepare(exynos->clks[i]);
0149
0150 if (exynos->suspend_clk_idx >= 0)
0151 clk_disable_unprepare(exynos->clks[exynos->suspend_clk_idx]);
0152
0153 regulator_disable(exynos->vdd33);
0154 regulator_disable(exynos->vdd10);
0155
0156 return 0;
0157 }
0158
0159 static const struct dwc3_exynos_driverdata exynos5250_drvdata = {
0160 .clk_names = { "usbdrd30" },
0161 .num_clks = 1,
0162 .suspend_clk_idx = -1,
0163 };
0164
0165 static const struct dwc3_exynos_driverdata exynos5433_drvdata = {
0166 .clk_names = { "aclk", "susp_clk", "pipe_pclk", "phyclk" },
0167 .num_clks = 4,
0168 .suspend_clk_idx = 1,
0169 };
0170
0171 static const struct dwc3_exynos_driverdata exynos7_drvdata = {
0172 .clk_names = { "usbdrd30", "usbdrd30_susp_clk", "usbdrd30_axius_clk" },
0173 .num_clks = 3,
0174 .suspend_clk_idx = 1,
0175 };
0176
0177 static const struct of_device_id exynos_dwc3_match[] = {
0178 {
0179 .compatible = "samsung,exynos5250-dwusb3",
0180 .data = &exynos5250_drvdata,
0181 }, {
0182 .compatible = "samsung,exynos5433-dwusb3",
0183 .data = &exynos5433_drvdata,
0184 }, {
0185 .compatible = "samsung,exynos7-dwusb3",
0186 .data = &exynos7_drvdata,
0187 }, {
0188 }
0189 };
0190 MODULE_DEVICE_TABLE(of, exynos_dwc3_match);
0191
0192 #ifdef CONFIG_PM_SLEEP
0193 static int dwc3_exynos_suspend(struct device *dev)
0194 {
0195 struct dwc3_exynos *exynos = dev_get_drvdata(dev);
0196 int i;
0197
0198 for (i = exynos->num_clks - 1; i >= 0; i--)
0199 clk_disable_unprepare(exynos->clks[i]);
0200
0201 regulator_disable(exynos->vdd33);
0202 regulator_disable(exynos->vdd10);
0203
0204 return 0;
0205 }
0206
0207 static int dwc3_exynos_resume(struct device *dev)
0208 {
0209 struct dwc3_exynos *exynos = dev_get_drvdata(dev);
0210 int i, ret;
0211
0212 ret = regulator_enable(exynos->vdd33);
0213 if (ret) {
0214 dev_err(dev, "Failed to enable VDD33 supply\n");
0215 return ret;
0216 }
0217 ret = regulator_enable(exynos->vdd10);
0218 if (ret) {
0219 dev_err(dev, "Failed to enable VDD10 supply\n");
0220 return ret;
0221 }
0222
0223 for (i = 0; i < exynos->num_clks; i++) {
0224 ret = clk_prepare_enable(exynos->clks[i]);
0225 if (ret) {
0226 while (i-- > 0)
0227 clk_disable_unprepare(exynos->clks[i]);
0228 return ret;
0229 }
0230 }
0231
0232 return 0;
0233 }
0234
0235 static const struct dev_pm_ops dwc3_exynos_dev_pm_ops = {
0236 SET_SYSTEM_SLEEP_PM_OPS(dwc3_exynos_suspend, dwc3_exynos_resume)
0237 };
0238
0239 #define DEV_PM_OPS (&dwc3_exynos_dev_pm_ops)
0240 #else
0241 #define DEV_PM_OPS NULL
0242 #endif
0243
0244 static struct platform_driver dwc3_exynos_driver = {
0245 .probe = dwc3_exynos_probe,
0246 .remove = dwc3_exynos_remove,
0247 .driver = {
0248 .name = "exynos-dwc3",
0249 .of_match_table = exynos_dwc3_match,
0250 .pm = DEV_PM_OPS,
0251 },
0252 };
0253
0254 module_platform_driver(dwc3_exynos_driver);
0255
0256 MODULE_AUTHOR("Anton Tikhomirov <av.tikhomirov@samsung.com>");
0257 MODULE_LICENSE("GPL v2");
0258 MODULE_DESCRIPTION("DesignWare USB3 Exynos Glue Layer");