···4141config PHY_MIPHY365X4242 tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"4343 depends on ARCH_STI4444- depends on GENERIC_PHY4544 depends on HAS_IOMEM4645 depends on OF4646+ select GENERIC_PHY4747 help4848 Enable this to support the miphy transceiver (for SATA/PCIE)4949 that is part of STMicroelectronics STiH41x SoC series.
+1
drivers/phy/phy-exynos5-usbdrd.c
···542542 },543543 { },544544};545545+MODULE_DEVICE_TABLE(of, exynos5_usbdrd_phy_of_match);545546546547static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)547548{
+76-51
drivers/phy/phy-twl4030-usb.c
···3434#include <linux/delay.h>3535#include <linux/usb/otg.h>3636#include <linux/phy/phy.h>3737+#include <linux/pm_runtime.h>3738#include <linux/usb/musb-omap.h>3839#include <linux/usb/ulpi.h>3940#include <linux/i2c/twl.h>···423422 }424423}425424426426-static int twl4030_phy_power_off(struct phy *phy)425425+static int twl4030_usb_runtime_suspend(struct device *dev)427426{428428- struct twl4030_usb *twl = phy_get_drvdata(phy);427427+ struct twl4030_usb *twl = dev_get_drvdata(dev);429428429429+ dev_dbg(twl->dev, "%s\n", __func__);430430 if (twl->asleep)431431 return 0;432432433433 twl4030_phy_power(twl, 0);434434 twl->asleep = 1;435435- dev_dbg(twl->dev, "%s\n", __func__);435435+436436 return 0;437437}438438439439-static void __twl4030_phy_power_on(struct twl4030_usb *twl)439439+static int twl4030_usb_runtime_resume(struct device *dev)440440{441441+ struct twl4030_usb *twl = dev_get_drvdata(dev);442442+443443+ dev_dbg(twl->dev, "%s\n", __func__);444444+ if (!twl->asleep)445445+ return 0;446446+441447 twl4030_phy_power(twl, 1);442442- twl4030_i2c_access(twl, 1);443443- twl4030_usb_set_mode(twl, twl->usb_mode);444444- if (twl->usb_mode == T2_USB_MODE_ULPI)445445- twl4030_i2c_access(twl, 0);448448+ twl->asleep = 0;449449+450450+ return 0;451451+}452452+453453+static int twl4030_phy_power_off(struct phy *phy)454454+{455455+ struct twl4030_usb *twl = phy_get_drvdata(phy);456456+457457+ dev_dbg(twl->dev, "%s\n", __func__);458458+ pm_runtime_mark_last_busy(twl->dev);459459+ pm_runtime_put_autosuspend(twl->dev);460460+461461+ return 0;446462}447463448464static int twl4030_phy_power_on(struct phy *phy)449465{450466 struct twl4030_usb *twl = phy_get_drvdata(phy);451467452452- if (!twl->asleep)453453- return 0;454454- __twl4030_phy_power_on(twl);455455- twl->asleep = 0;456468 dev_dbg(twl->dev, "%s\n", __func__);469469+ pm_runtime_get_sync(twl->dev);470470+ twl4030_i2c_access(twl, 1);471471+ twl4030_usb_set_mode(twl, twl->usb_mode);472472+ if (twl->usb_mode == T2_USB_MODE_ULPI)473473+ twl4030_i2c_access(twl, 0);457474458475 /*459476 * XXX When VBUS gets driven after musb goes to A mode,···577558 * USB_LINK_VBUS state. musb_hdrc won't care until it578559 * starts to handle softconnect right.579560 */580580- omap_musb_mailbox(status);581581- }582582- sysfs_notify(&twl->dev->kobj, NULL, "vbus");583583-584584- return IRQ_HANDLED;585585-}586586-587587-static void twl4030_id_workaround_work(struct work_struct *work)588588-{589589- struct twl4030_usb *twl = container_of(work, struct twl4030_usb,590590- id_workaround_work.work);591591- enum omap_musb_vbus_id_status status;592592- bool status_changed = false;593593-594594- status = twl4030_usb_linkstat(twl);595595-596596- spin_lock_irq(&twl->lock);597597- if (status >= 0 && status != twl->linkstat) {598598- twl->linkstat = status;599599- status_changed = true;600600- }601601- spin_unlock_irq(&twl->lock);602602-603603- if (status_changed) {604604- dev_dbg(twl->dev, "handle missing status change to %d\n",605605- status);561561+ if ((status == OMAP_MUSB_VBUS_VALID) ||562562+ (status == OMAP_MUSB_ID_GROUND)) {563563+ if (twl->asleep)564564+ pm_runtime_get_sync(twl->dev);565565+ } else {566566+ if (!twl->asleep) {567567+ pm_runtime_mark_last_busy(twl->dev);568568+ pm_runtime_put_autosuspend(twl->dev);569569+ }570570+ }606571 omap_musb_mailbox(status);607572 }608573···595592 cancel_delayed_work(&twl->id_workaround_work);596593 schedule_delayed_work(&twl->id_workaround_work, HZ);597594 }595595+596596+ if (irq)597597+ sysfs_notify(&twl->dev->kobj, NULL, "vbus");598598+599599+ return IRQ_HANDLED;600600+}601601+602602+static void twl4030_id_workaround_work(struct work_struct *work)603603+{604604+ struct twl4030_usb *twl = container_of(work, struct twl4030_usb,605605+ id_workaround_work.work);606606+607607+ twl4030_usb_irq(0, twl);598608}599609600610static int twl4030_phy_init(struct phy *phy)···615599 struct twl4030_usb *twl = phy_get_drvdata(phy);616600 enum omap_musb_vbus_id_status status;617601618618- /*619619- * Start in sleep state, we'll get called through set_suspend()620620- * callback when musb is runtime resumed and it's time to start.621621- */622622- __twl4030_phy_power(twl, 0);623623- twl->asleep = 1;624624-602602+ pm_runtime_get_sync(twl->dev);625603 status = twl4030_usb_linkstat(twl);626604 twl->linkstat = status;627605628628- if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) {606606+ if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID)629607 omap_musb_mailbox(twl->linkstat);630630- twl4030_phy_power_on(phy);631631- }632608633609 sysfs_notify(&twl->dev->kobj, NULL, "vbus");610610+ pm_runtime_mark_last_busy(twl->dev);611611+ pm_runtime_put_autosuspend(twl->dev);612612+634613 return 0;635614}636615···659648 .power_on = twl4030_phy_power_on,660649 .power_off = twl4030_phy_power_off,661650 .owner = THIS_MODULE,651651+};652652+653653+static const struct dev_pm_ops twl4030_usb_pm_ops = {654654+ SET_RUNTIME_PM_OPS(twl4030_usb_runtime_suspend,655655+ twl4030_usb_runtime_resume, NULL)662656};663657664658static int twl4030_usb_probe(struct platform_device *pdev)···742726743727 ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);744728729729+ pm_runtime_use_autosuspend(&pdev->dev);730730+ pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);731731+ pm_runtime_enable(&pdev->dev);732732+ pm_runtime_get_sync(&pdev->dev);733733+745734 /* Our job is to use irqs and status from the power module746735 * to keep the transceiver disabled when nothing's connected.747736 *···765744 return status;766745 }767746747747+ pm_runtime_mark_last_busy(&pdev->dev);748748+ pm_runtime_put_autosuspend(twl->dev);749749+768750 dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");769751 return 0;770752}···777753 struct twl4030_usb *twl = platform_get_drvdata(pdev);778754 int val;779755756756+ pm_runtime_get_sync(twl->dev);780757 cancel_delayed_work(&twl->id_workaround_work);781758 device_remove_file(twl->dev, &dev_attr_vbus);782759···797772798773 /* disable complete OTG block */799774 twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);800800-801801- if (!twl->asleep)802802- twl4030_phy_power(twl, 0);775775+ pm_runtime_mark_last_busy(twl->dev);776776+ pm_runtime_put(twl->dev);803777804778 return 0;805779}···816792 .remove = twl4030_usb_remove,817793 .driver = {818794 .name = "twl4030_usb",795795+ .pm = &twl4030_usb_pm_ops,819796 .owner = THIS_MODULE,820797 .of_match_table = of_match_ptr(twl4030_usb_id_table),821798 },