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(&pdev->dev, "usb"); 19 20 if (IS_ERR(phy)) 21 return PTR_ERR(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(&pdev->dev, 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(priv->phy); 51 52 if (!retval) 53 retval = phy_power_on(priv->phy); 54 } else { 55 phy_power_off(priv->phy); 56 phy_exit(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