diff options
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r-- | drivers/usb/phy/Kconfig | 6 | ||||
-rw-r--r-- | drivers/usb/phy/phy-msm-usb.c | 85 | ||||
-rw-r--r-- | drivers/usb/phy/phy-qcom-8x16-usb.c | 20 | ||||
-rw-r--r-- | drivers/usb/phy/phy.c | 57 |
4 files changed, 83 insertions, 85 deletions
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 3006f569c068..aff702c0eb9f 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -4,6 +4,7 @@ menu "USB Physical Layer drivers" config USB_PHY + select EXTCON def_bool n # @@ -109,7 +110,7 @@ config OMAP_OTG config TAHVO_USB tristate "Tahvo USB transceiver driver" - depends on MFD_RETU && EXTCON + depends on MFD_RETU depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y' select USB_PHY help @@ -141,7 +142,6 @@ config USB_MSM_OTG depends on (USB || USB_GADGET) && (ARCH_QCOM || COMPILE_TEST) depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y' depends on RESET_CONTROLLER - depends on EXTCON select USB_PHY help Enable this to support the USB OTG transceiver on Qualcomm chips. It @@ -155,7 +155,7 @@ config USB_MSM_OTG config USB_QCOM_8X16_PHY tristate "Qualcomm APQ8016/MSM8916 on-chip USB PHY controller support" depends on ARCH_QCOM || COMPILE_TEST - depends on RESET_CONTROLLER && EXTCON + depends on RESET_CONTROLLER select USB_PHY select USB_ULPI_VIEWPORT help diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 93d9aaad2994..8fb86a5f458e 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -146,17 +146,6 @@ struct msm_otg_platform_data { }; /** - * struct msm_usb_cable - structure for exteternal connector cable - * state tracking - * @nb: hold event notification callback - * @conn: used for notification registration - */ -struct msm_usb_cable { - struct notifier_block nb; - struct extcon_dev *extcon; -}; - -/** * struct msm_otg: OTG driver data. Shared by HCD and DCD. * @otg: USB OTG Transceiver structure. * @pdata: otg device platform data. @@ -215,9 +204,6 @@ struct msm_otg { bool manual_pullup; - struct msm_usb_cable vbus; - struct msm_usb_cable id; - struct gpio_desc *switch_gpio; struct notifier_block reboot; }; @@ -1612,8 +1598,8 @@ MODULE_DEVICE_TABLE(of, msm_otg_dt_match); static int msm_otg_vbus_notifier(struct notifier_block *nb, unsigned long event, void *ptr) { - struct msm_usb_cable *vbus = container_of(nb, struct msm_usb_cable, nb); - struct msm_otg *motg = container_of(vbus, struct msm_otg, vbus); + struct usb_phy *usb_phy = container_of(nb, struct usb_phy, vbus_nb); + struct msm_otg *motg = container_of(usb_phy, struct msm_otg, phy); if (event) set_bit(B_SESS_VLD, &motg->inputs); @@ -1636,8 +1622,8 @@ static int msm_otg_vbus_notifier(struct notifier_block *nb, unsigned long event, static int msm_otg_id_notifier(struct notifier_block *nb, unsigned long event, void *ptr) { - struct msm_usb_cable *id = container_of(nb, struct msm_usb_cable, nb); - struct msm_otg *motg = container_of(id, struct msm_otg, id); + struct usb_phy *usb_phy = container_of(nb, struct usb_phy, id_nb); + struct msm_otg *motg = container_of(usb_phy, struct msm_otg, phy); if (event) clear_bit(ID, &motg->inputs); @@ -1652,7 +1638,6 @@ static int msm_otg_id_notifier(struct notifier_block *nb, unsigned long event, static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) { struct msm_otg_platform_data *pdata; - struct extcon_dev *ext_id, *ext_vbus; struct device_node *node = pdev->dev.of_node; struct property *prop; int len, ret, words; @@ -1708,54 +1693,6 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) if (IS_ERR(motg->switch_gpio)) return PTR_ERR(motg->switch_gpio); - ext_id = ERR_PTR(-ENODEV); - ext_vbus = ERR_PTR(-ENODEV); - if (of_property_read_bool(node, "extcon")) { - - /* Each one of them is not mandatory */ - ext_vbus = extcon_get_edev_by_phandle(&pdev->dev, 0); - if (IS_ERR(ext_vbus) && PTR_ERR(ext_vbus) != -ENODEV) - return PTR_ERR(ext_vbus); - - ext_id = extcon_get_edev_by_phandle(&pdev->dev, 1); - if (IS_ERR(ext_id) && PTR_ERR(ext_id) != -ENODEV) - return PTR_ERR(ext_id); - } - - if (!IS_ERR(ext_vbus)) { - motg->vbus.extcon = ext_vbus; - motg->vbus.nb.notifier_call = msm_otg_vbus_notifier; - ret = devm_extcon_register_notifier(&pdev->dev, ext_vbus, - EXTCON_USB, &motg->vbus.nb); - if (ret < 0) { - dev_err(&pdev->dev, "register VBUS notifier failed\n"); - return ret; - } - - ret = extcon_get_state(ext_vbus, EXTCON_USB); - if (ret) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - } - - if (!IS_ERR(ext_id)) { - motg->id.extcon = ext_id; - motg->id.nb.notifier_call = msm_otg_id_notifier; - ret = devm_extcon_register_notifier(&pdev->dev, ext_id, - EXTCON_USB_HOST, &motg->id.nb); - if (ret < 0) { - dev_err(&pdev->dev, "register ID notifier failed\n"); - return ret; - } - - ret = extcon_get_state(ext_id, EXTCON_USB_HOST); - if (ret) - clear_bit(ID, &motg->inputs); - else - set_bit(ID, &motg->inputs); - } - prop = of_find_property(node, "qcom,phy-init-sequence", &len); if (!prop || !len) return 0; @@ -1932,6 +1869,8 @@ static int msm_otg_probe(struct platform_device *pdev) phy->init = msm_phy_init; phy->notify_disconnect = msm_phy_notify_disconnect; phy->type = USB_PHY_TYPE_USB2; + phy->vbus_nb.notifier_call = msm_otg_vbus_notifier; + phy->id_nb.notifier_call = msm_otg_id_notifier; phy->io_ops = &msm_otg_io_ops; @@ -1947,6 +1886,18 @@ static int msm_otg_probe(struct platform_device *pdev) goto disable_ldo; } + ret = extcon_get_state(phy->edev, EXTCON_USB); + if (ret) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + + ret = extcon_get_state(phy->id_edev, EXTCON_USB_HOST); + if (ret) + clear_bit(ID, &motg->inputs); + else + set_bit(ID, &motg->inputs); + platform_set_drvdata(pdev, motg); device_init_wakeup(&pdev->dev, 1); diff --git a/drivers/usb/phy/phy-qcom-8x16-usb.c b/drivers/usb/phy/phy-qcom-8x16-usb.c index fdf686398772..b6a83a5cbad3 100644 --- a/drivers/usb/phy/phy-qcom-8x16-usb.c +++ b/drivers/usb/phy/phy-qcom-8x16-usb.c @@ -69,9 +69,6 @@ struct phy_8x16 { struct reset_control *phy_reset; - struct extcon_dev *vbus_edev; - struct notifier_block vbus_notify; - struct gpio_desc *switch_gpio; struct notifier_block reboot_notify; }; @@ -131,7 +128,8 @@ static int phy_8x16_vbus_off(struct phy_8x16 *qphy) static int phy_8x16_vbus_notify(struct notifier_block *nb, unsigned long event, void *ptr) { - struct phy_8x16 *qphy = container_of(nb, struct phy_8x16, vbus_notify); + struct usb_phy *usb_phy = container_of(nb, struct usb_phy, vbus_nb); + struct phy_8x16 *qphy = container_of(usb_phy, struct phy_8x16, phy); if (event) phy_8x16_vbus_on(qphy); @@ -187,7 +185,7 @@ static int phy_8x16_init(struct usb_phy *phy) val = ULPI_PWR_OTG_COMP_DISABLE; usb_phy_io_write(phy, val, ULPI_SET(ULPI_PWR_CLK_MNG_REG)); - state = extcon_get_state(qphy->vbus_edev, EXTCON_USB); + state = extcon_get_state(qphy->phy.edev, EXTCON_USB); if (state) phy_8x16_vbus_on(qphy); else @@ -289,15 +287,13 @@ static int phy_8x16_probe(struct platform_device *pdev) phy->io_priv = qphy->regs + HSPHY_ULPI_VIEWPORT; phy->io_ops = &ulpi_viewport_access_ops; phy->type = USB_PHY_TYPE_USB2; + phy->vbus_nb.notifier_call = phy_8x16_vbus_notify; + phy->id_nb.notifier_call = NULL; ret = phy_8x16_read_devicetree(qphy); if (ret < 0) return ret; - qphy->vbus_edev = extcon_get_edev_by_phandle(phy->dev, 0); - if (IS_ERR(qphy->vbus_edev)) - return PTR_ERR(qphy->vbus_edev); - ret = clk_set_rate(qphy->core_clk, INT_MAX); if (ret < 0) dev_dbg(phy->dev, "Can't boost core clock\n"); @@ -315,12 +311,6 @@ static int phy_8x16_probe(struct platform_device *pdev) if (WARN_ON(ret)) goto off_clks; - qphy->vbus_notify.notifier_call = phy_8x16_vbus_notify; - ret = devm_extcon_register_notifier(&pdev->dev, qphy->vbus_edev, - EXTCON_USB, &qphy->vbus_notify); - if (ret < 0) - goto off_power; - ret = usb_add_phy_dev(&qphy->phy); if (ret) goto off_power; diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 98f75d2842b7..032f5afaad4b 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -100,6 +100,54 @@ static int devm_usb_phy_match(struct device *dev, void *res, void *match_data) return *phy == match_data; } +static int usb_add_extcon(struct usb_phy *x) +{ + int ret; + + if (of_property_read_bool(x->dev->of_node, "extcon")) { + x->edev = extcon_get_edev_by_phandle(x->dev, 0); + if (IS_ERR(x->edev)) + return PTR_ERR(x->edev); + + x->id_edev = extcon_get_edev_by_phandle(x->dev, 1); + if (IS_ERR(x->id_edev)) { + x->id_edev = NULL; + dev_info(x->dev, "No separate ID extcon device\n"); + } + + if (x->vbus_nb.notifier_call) { + ret = devm_extcon_register_notifier(x->dev, x->edev, + EXTCON_USB, + &x->vbus_nb); + if (ret < 0) { + dev_err(x->dev, + "register VBUS notifier failed\n"); + return ret; + } + } + + if (x->id_nb.notifier_call) { + struct extcon_dev *id_ext; + + if (x->id_edev) + id_ext = x->id_edev; + else + id_ext = x->edev; + + ret = devm_extcon_register_notifier(x->dev, id_ext, + EXTCON_USB_HOST, + &x->id_nb); + if (ret < 0) { + dev_err(x->dev, + "register ID notifier failed\n"); + return ret; + } + } + } + + return 0; +} + /** * devm_usb_get_phy - find the USB PHY * @dev - device that requests this phy @@ -388,6 +436,10 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type) return -EINVAL; } + ret = usb_add_extcon(x); + if (ret) + return ret; + ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier); spin_lock_irqsave(&phy_lock, flags); @@ -422,12 +474,17 @@ int usb_add_phy_dev(struct usb_phy *x) { struct usb_phy_bind *phy_bind; unsigned long flags; + int ret; if (!x->dev) { dev_err(x->dev, "no device provided for PHY\n"); return -EINVAL; } + ret = usb_add_extcon(x); + if (ret) + return ret; + ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier); spin_lock_irqsave(&phy_lock, flags); |