diff options
| -rw-r--r-- | drivers/phy/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/phy/phy-core.c | 16 | ||||
| -rw-r--r-- | drivers/phy/phy-twl4030-usb.c | 14 |
3 files changed, 19 insertions, 12 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index e7e117d5dbbe..0124d17bd9fe 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
| @@ -224,6 +224,7 @@ config PHY_MT65XX_USB3 | |||
| 224 | 224 | ||
| 225 | config PHY_HI6220_USB | 225 | config PHY_HI6220_USB |
| 226 | tristate "hi6220 USB PHY support" | 226 | tristate "hi6220 USB PHY support" |
| 227 | depends on (ARCH_HISI && ARM64) || COMPILE_TEST | ||
| 227 | select GENERIC_PHY | 228 | select GENERIC_PHY |
| 228 | select MFD_SYSCON | 229 | select MFD_SYSCON |
| 229 | help | 230 | help |
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 8c7f27db6ad3..e7e574dc667a 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
| @@ -275,20 +275,21 @@ EXPORT_SYMBOL_GPL(phy_exit); | |||
| 275 | 275 | ||
| 276 | int phy_power_on(struct phy *phy) | 276 | int phy_power_on(struct phy *phy) |
| 277 | { | 277 | { |
| 278 | int ret; | 278 | int ret = 0; |
| 279 | 279 | ||
| 280 | if (!phy) | 280 | if (!phy) |
| 281 | return 0; | 281 | goto out; |
| 282 | 282 | ||
| 283 | if (phy->pwr) { | 283 | if (phy->pwr) { |
| 284 | ret = regulator_enable(phy->pwr); | 284 | ret = regulator_enable(phy->pwr); |
| 285 | if (ret) | 285 | if (ret) |
| 286 | return ret; | 286 | goto out; |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | ret = phy_pm_runtime_get_sync(phy); | 289 | ret = phy_pm_runtime_get_sync(phy); |
| 290 | if (ret < 0 && ret != -ENOTSUPP) | 290 | if (ret < 0 && ret != -ENOTSUPP) |
| 291 | return ret; | 291 | goto err_pm_sync; |
| 292 | |||
| 292 | ret = 0; /* Override possible ret == -ENOTSUPP */ | 293 | ret = 0; /* Override possible ret == -ENOTSUPP */ |
| 293 | 294 | ||
| 294 | mutex_lock(&phy->mutex); | 295 | mutex_lock(&phy->mutex); |
| @@ -296,19 +297,20 @@ int phy_power_on(struct phy *phy) | |||
| 296 | ret = phy->ops->power_on(phy); | 297 | ret = phy->ops->power_on(phy); |
| 297 | if (ret < 0) { | 298 | if (ret < 0) { |
| 298 | dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); | 299 | dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); |
| 299 | goto out; | 300 | goto err_pwr_on; |
| 300 | } | 301 | } |
| 301 | } | 302 | } |
| 302 | ++phy->power_count; | 303 | ++phy->power_count; |
| 303 | mutex_unlock(&phy->mutex); | 304 | mutex_unlock(&phy->mutex); |
| 304 | return 0; | 305 | return 0; |
| 305 | 306 | ||
| 306 | out: | 307 | err_pwr_on: |
| 307 | mutex_unlock(&phy->mutex); | 308 | mutex_unlock(&phy->mutex); |
| 308 | phy_pm_runtime_put_sync(phy); | 309 | phy_pm_runtime_put_sync(phy); |
| 310 | err_pm_sync: | ||
| 309 | if (phy->pwr) | 311 | if (phy->pwr) |
| 310 | regulator_disable(phy->pwr); | 312 | regulator_disable(phy->pwr); |
| 311 | 313 | out: | |
| 312 | return ret; | 314 | return ret; |
| 313 | } | 315 | } |
| 314 | EXPORT_SYMBOL_GPL(phy_power_on); | 316 | EXPORT_SYMBOL_GPL(phy_power_on); |
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index 4a3fc6e59f8e..840f3eae428b 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c | |||
| @@ -715,6 +715,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
| 715 | pm_runtime_use_autosuspend(&pdev->dev); | 715 | pm_runtime_use_autosuspend(&pdev->dev); |
| 716 | pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); | 716 | pm_runtime_set_autosuspend_delay(&pdev->dev, 2000); |
| 717 | pm_runtime_enable(&pdev->dev); | 717 | pm_runtime_enable(&pdev->dev); |
| 718 | pm_runtime_get_sync(&pdev->dev); | ||
| 718 | 719 | ||
| 719 | /* Our job is to use irqs and status from the power module | 720 | /* Our job is to use irqs and status from the power module |
| 720 | * to keep the transceiver disabled when nothing's connected. | 721 | * to keep the transceiver disabled when nothing's connected. |
| @@ -750,6 +751,7 @@ static int twl4030_usb_remove(struct platform_device *pdev) | |||
| 750 | struct twl4030_usb *twl = platform_get_drvdata(pdev); | 751 | struct twl4030_usb *twl = platform_get_drvdata(pdev); |
| 751 | int val; | 752 | int val; |
| 752 | 753 | ||
| 754 | usb_remove_phy(&twl->phy); | ||
| 753 | pm_runtime_get_sync(twl->dev); | 755 | pm_runtime_get_sync(twl->dev); |
| 754 | cancel_delayed_work(&twl->id_workaround_work); | 756 | cancel_delayed_work(&twl->id_workaround_work); |
| 755 | device_remove_file(twl->dev, &dev_attr_vbus); | 757 | device_remove_file(twl->dev, &dev_attr_vbus); |
| @@ -757,6 +759,13 @@ static int twl4030_usb_remove(struct platform_device *pdev) | |||
| 757 | /* set transceiver mode to power on defaults */ | 759 | /* set transceiver mode to power on defaults */ |
| 758 | twl4030_usb_set_mode(twl, -1); | 760 | twl4030_usb_set_mode(twl, -1); |
| 759 | 761 | ||
| 762 | /* idle ulpi before powering off */ | ||
| 763 | if (cable_present(twl->linkstat)) | ||
| 764 | pm_runtime_put_noidle(twl->dev); | ||
| 765 | pm_runtime_mark_last_busy(twl->dev); | ||
| 766 | pm_runtime_put_sync_suspend(twl->dev); | ||
| 767 | pm_runtime_disable(twl->dev); | ||
| 768 | |||
| 760 | /* autogate 60MHz ULPI clock, | 769 | /* autogate 60MHz ULPI clock, |
| 761 | * clear dpll clock request for i2c access, | 770 | * clear dpll clock request for i2c access, |
| 762 | * disable 32KHz | 771 | * disable 32KHz |
| @@ -771,11 +780,6 @@ static int twl4030_usb_remove(struct platform_device *pdev) | |||
| 771 | /* disable complete OTG block */ | 780 | /* disable complete OTG block */ |
| 772 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); | 781 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); |
| 773 | 782 | ||
| 774 | if (cable_present(twl->linkstat)) | ||
| 775 | pm_runtime_put_noidle(twl->dev); | ||
| 776 | pm_runtime_mark_last_busy(twl->dev); | ||
| 777 | pm_runtime_put(twl->dev); | ||
| 778 | |||
| 779 | return 0; | 783 | return 0; |
| 780 | } | 784 | } |
| 781 | 785 | ||
