1 | // SPDX-License-Identifier: GPL-1.0+ |
2 | /* |
3 | * Renesas USB driver R-Car Gen. 2 initialization and power control |
4 | * |
5 | * Copyright (C) 2014 Ulrich Hecht |
6 | * Copyright (C) 2019 Renesas Electronics Corporation |
7 | */ |
8 | |
9 | #include <linux/phy/phy.h> |
10 | #include "common.h" |
11 | #include "rcar2.h" |
12 | |
13 | static int usbhs_rcar2_hardware_init(struct platform_device *pdev) |
14 | { |
15 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); |
16 | |
17 | if (IS_ENABLED(CONFIG_GENERIC_PHY)) { |
18 | struct phy *phy = phy_get(dev: &pdev->dev, string: "usb" ); |
19 | |
20 | if (IS_ERR(ptr: phy)) |
21 | return PTR_ERR(ptr: phy); |
22 | |
23 | priv->phy = phy; |
24 | return 0; |
25 | } |
26 | |
27 | return -ENXIO; |
28 | } |
29 | |
30 | static int usbhs_rcar2_hardware_exit(struct platform_device *pdev) |
31 | { |
32 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); |
33 | |
34 | if (priv->phy) { |
35 | phy_put(dev: &pdev->dev, phy: priv->phy); |
36 | priv->phy = NULL; |
37 | } |
38 | |
39 | return 0; |
40 | } |
41 | |
42 | static int usbhs_rcar2_power_ctrl(struct platform_device *pdev, |
43 | void __iomem *base, int enable) |
44 | { |
45 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); |
46 | int retval = -ENODEV; |
47 | |
48 | if (priv->phy) { |
49 | if (enable) { |
50 | retval = phy_init(phy: priv->phy); |
51 | |
52 | if (!retval) |
53 | retval = phy_power_on(phy: priv->phy); |
54 | } else { |
55 | phy_power_off(phy: priv->phy); |
56 | phy_exit(phy: priv->phy); |
57 | retval = 0; |
58 | } |
59 | } |
60 | |
61 | return retval; |
62 | } |
63 | |
64 | const struct renesas_usbhs_platform_info usbhs_rcar_gen2_plat_info = { |
65 | .platform_callback = { |
66 | .hardware_init = usbhs_rcar2_hardware_init, |
67 | .hardware_exit = usbhs_rcar2_hardware_exit, |
68 | .power_ctrl = usbhs_rcar2_power_ctrl, |
69 | .get_id = usbhs_get_id_as_gadget, |
70 | }, |
71 | .driver_param = { |
72 | .has_usb_dmac = 1, |
73 | .has_new_pipe_configs = 1, |
74 | }, |
75 | }; |
76 | |