Loading Documentation/devicetree/bindings/usb/msm-hsusb.txt +16 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,16 @@ Required properties : Optional properties : - qcom,usb2-enable-hsphy2: If present, select second PHY for USB operation. - pinctrl-names : This should be defined if a target uses pinctrl framework. See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-pinctrl.txt. It should specify the names of the configs that pinctrl can install in driver Following are the pinctrl configs that can be installed "ehci_active" : Active configuration of pins, this should specify active config defined in pin groups of used gpio's from resume and ext-hub-reset. "ehci_sleep" : Disabled configuration of pins, this should specify sleep config defined in pin groups of used gpio's from resume and ext-hub-reset. - qcom,resume-gpio: if present then peripheral connected to usb controller cannot wakeup from XO shutdown using in-band usb bus resume. Use resume gpio to wakeup peripheral. Loading @@ -179,6 +189,12 @@ Example MSM HSUSB EHCI controller device node : reg = <0xf9a55000 0x400>; interrupts = <0 134 0>, <0 140 0>; interrupt-names = "core_irq", "async_irq"; /* If pinctrl is used and ext-hub-reset and resume gpio's are present*/ pinctrl-names = "ehci_active","ehci_sleep"; pinctrl-0 = <&ehci_reset_act &resume_act>; pinctrl-1 = <&ehci_reset_sus &resume_sus>; qcom,resume-gpio = <&msm_gpio 80 0>; qcom,ext-hub-reset-gpio = <&msm_gpio 0 0>; hsusb_vdd_dig-supply = <&pm8841_s2_corner>; HSUSB_1p8-supply = <&pm8941_l6>; HSUSB_3p3-supply = <&pm8941_l24>; Loading drivers/usb/host/ehci-msm2.c +52 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/pm_wakeup.h> #include <linux/pm_runtime.h> #include <linux/dma-mapping.h> #include <linux/pinctrl/consumer.h> #include <linux/regulator/consumer.h> #include <linux/usb.h> #include <linux/usb/hcd.h> Loading Loading @@ -87,6 +88,7 @@ struct msm_hcd { bool wakeup_irq_enabled; int wakeup_irq; void __iomem *usb_phy_ctrl_reg; struct pinctrl *hsusb_pinctrl; }; static inline struct msm_hcd *hcd_to_mhcd(struct usb_hcd *hcd) Loading Loading @@ -1283,6 +1285,7 @@ static int ehci_msm2_probe(struct platform_device *pdev) struct usb_hcd *hcd; struct resource *res; struct msm_hcd *mhcd; struct pinctrl_state *set_state; const struct msm_usb_host_platform_data *pdata; char pdev_name[PDEV_NAME_LEN]; int ret; Loading Loading @@ -1377,6 +1380,33 @@ static int ehci_msm2_probe(struct platform_device *pdev) goto free_xo_handle; } /* Get pinctrl if target uses pinctrl */ mhcd->hsusb_pinctrl = devm_pinctrl_get(&pdev->dev); if (IS_ERR(mhcd->hsusb_pinctrl)) { if (of_property_read_bool(pdev->dev.of_node, "pinctrl-names")) { dev_err(&pdev->dev, "Error encountered while getting pinctrl"); ret = PTR_ERR(mhcd->hsusb_pinctrl); goto devote_xo_handle; } pr_debug("Target does not use pinctrl\n"); mhcd->hsusb_pinctrl = NULL; } if (mhcd->hsusb_pinctrl) { set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl, "ehci_active"); if (IS_ERR(set_state)) { pr_err("cannot get hsusb pinctrl active state\n"); ret = PTR_ERR(set_state); goto devote_xo_handle; } ret = pinctrl_select_state(mhcd->hsusb_pinctrl, set_state); if (ret) { pr_err("cannot set hsusb pinctrl active state\n"); goto devote_xo_handle; } } if (pdata && gpio_is_valid(pdata->resume_gpio)) { mhcd->resume_gpio = pdata->resume_gpio; ret = devm_gpio_request(&pdev->dev, mhcd->resume_gpio, Loading @@ -1401,7 +1431,7 @@ static int ehci_msm2_probe(struct platform_device *pdev) dev_err(&pdev->dev, "reset gpio(%d) request failed:%d\n", pdata->ext_hub_reset_gpio, ret); goto devote_xo_handle; goto pinctrl_sleep; } else { /* reset external hub */ gpio_direction_output(pdata->ext_hub_reset_gpio, 0); Loading @@ -1420,13 +1450,13 @@ static int ehci_msm2_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "unable to initialize VDDCX\n"); ret = -ENODEV; goto devote_xo_handle; goto pinctrl_sleep; } ret = msm_ehci_config_vddcx(mhcd, 1); if (ret) { dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); goto devote_xo_handle; goto deinit_vddcx; } ret = msm_ehci_ldo_init(mhcd, 1); Loading Loading @@ -1534,6 +1564,15 @@ deinit_ldo: msm_ehci_ldo_init(mhcd, 0); deinit_vddcx: msm_ehci_init_vddcx(mhcd, 0); pinctrl_sleep: if (mhcd->hsusb_pinctrl) { set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl, "ehci_sleep"); if (IS_ERR(set_state)) pr_err("cannot get hsusb pinctrl sleep state\n"); else pinctrl_select_state(mhcd->hsusb_pinctrl, set_state); } devote_xo_handle: if (mhcd->xo_clk) clk_disable_unprepare(mhcd->xo_clk); Loading Loading @@ -1561,6 +1600,7 @@ static int ehci_msm2_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct msm_hcd *mhcd = hcd_to_mhcd(hcd); struct pinctrl_state *set_state; if (mhcd->pmic_gpio_dp_irq) { if (mhcd->pmic_gpio_dp_irq_enabled) Loading Loading @@ -1594,6 +1634,15 @@ static int ehci_msm2_remove(struct platform_device *pdev) msm_ehci_ldo_init(mhcd, 0); msm_ehci_init_vddcx(mhcd, 0); if (mhcd->hsusb_pinctrl) { set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl, "ehci_sleep"); if (IS_ERR(set_state)) pr_err("cannot get hsusb pinctrl sleep state\n"); else pinctrl_select_state(mhcd->hsusb_pinctrl, set_state); } msm_ehci_init_clocks(mhcd, 0); wakeup_source_trash(&mhcd->ws); iounmap(hcd->regs); Loading Loading
Documentation/devicetree/bindings/usb/msm-hsusb.txt +16 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,16 @@ Required properties : Optional properties : - qcom,usb2-enable-hsphy2: If present, select second PHY for USB operation. - pinctrl-names : This should be defined if a target uses pinctrl framework. See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-pinctrl.txt. It should specify the names of the configs that pinctrl can install in driver Following are the pinctrl configs that can be installed "ehci_active" : Active configuration of pins, this should specify active config defined in pin groups of used gpio's from resume and ext-hub-reset. "ehci_sleep" : Disabled configuration of pins, this should specify sleep config defined in pin groups of used gpio's from resume and ext-hub-reset. - qcom,resume-gpio: if present then peripheral connected to usb controller cannot wakeup from XO shutdown using in-band usb bus resume. Use resume gpio to wakeup peripheral. Loading @@ -179,6 +189,12 @@ Example MSM HSUSB EHCI controller device node : reg = <0xf9a55000 0x400>; interrupts = <0 134 0>, <0 140 0>; interrupt-names = "core_irq", "async_irq"; /* If pinctrl is used and ext-hub-reset and resume gpio's are present*/ pinctrl-names = "ehci_active","ehci_sleep"; pinctrl-0 = <&ehci_reset_act &resume_act>; pinctrl-1 = <&ehci_reset_sus &resume_sus>; qcom,resume-gpio = <&msm_gpio 80 0>; qcom,ext-hub-reset-gpio = <&msm_gpio 0 0>; hsusb_vdd_dig-supply = <&pm8841_s2_corner>; HSUSB_1p8-supply = <&pm8941_l6>; HSUSB_3p3-supply = <&pm8941_l24>; Loading
drivers/usb/host/ehci-msm2.c +52 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/pm_wakeup.h> #include <linux/pm_runtime.h> #include <linux/dma-mapping.h> #include <linux/pinctrl/consumer.h> #include <linux/regulator/consumer.h> #include <linux/usb.h> #include <linux/usb/hcd.h> Loading Loading @@ -87,6 +88,7 @@ struct msm_hcd { bool wakeup_irq_enabled; int wakeup_irq; void __iomem *usb_phy_ctrl_reg; struct pinctrl *hsusb_pinctrl; }; static inline struct msm_hcd *hcd_to_mhcd(struct usb_hcd *hcd) Loading Loading @@ -1283,6 +1285,7 @@ static int ehci_msm2_probe(struct platform_device *pdev) struct usb_hcd *hcd; struct resource *res; struct msm_hcd *mhcd; struct pinctrl_state *set_state; const struct msm_usb_host_platform_data *pdata; char pdev_name[PDEV_NAME_LEN]; int ret; Loading Loading @@ -1377,6 +1380,33 @@ static int ehci_msm2_probe(struct platform_device *pdev) goto free_xo_handle; } /* Get pinctrl if target uses pinctrl */ mhcd->hsusb_pinctrl = devm_pinctrl_get(&pdev->dev); if (IS_ERR(mhcd->hsusb_pinctrl)) { if (of_property_read_bool(pdev->dev.of_node, "pinctrl-names")) { dev_err(&pdev->dev, "Error encountered while getting pinctrl"); ret = PTR_ERR(mhcd->hsusb_pinctrl); goto devote_xo_handle; } pr_debug("Target does not use pinctrl\n"); mhcd->hsusb_pinctrl = NULL; } if (mhcd->hsusb_pinctrl) { set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl, "ehci_active"); if (IS_ERR(set_state)) { pr_err("cannot get hsusb pinctrl active state\n"); ret = PTR_ERR(set_state); goto devote_xo_handle; } ret = pinctrl_select_state(mhcd->hsusb_pinctrl, set_state); if (ret) { pr_err("cannot set hsusb pinctrl active state\n"); goto devote_xo_handle; } } if (pdata && gpio_is_valid(pdata->resume_gpio)) { mhcd->resume_gpio = pdata->resume_gpio; ret = devm_gpio_request(&pdev->dev, mhcd->resume_gpio, Loading @@ -1401,7 +1431,7 @@ static int ehci_msm2_probe(struct platform_device *pdev) dev_err(&pdev->dev, "reset gpio(%d) request failed:%d\n", pdata->ext_hub_reset_gpio, ret); goto devote_xo_handle; goto pinctrl_sleep; } else { /* reset external hub */ gpio_direction_output(pdata->ext_hub_reset_gpio, 0); Loading @@ -1420,13 +1450,13 @@ static int ehci_msm2_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "unable to initialize VDDCX\n"); ret = -ENODEV; goto devote_xo_handle; goto pinctrl_sleep; } ret = msm_ehci_config_vddcx(mhcd, 1); if (ret) { dev_err(&pdev->dev, "hsusb vddcx configuration failed\n"); goto devote_xo_handle; goto deinit_vddcx; } ret = msm_ehci_ldo_init(mhcd, 1); Loading Loading @@ -1534,6 +1564,15 @@ deinit_ldo: msm_ehci_ldo_init(mhcd, 0); deinit_vddcx: msm_ehci_init_vddcx(mhcd, 0); pinctrl_sleep: if (mhcd->hsusb_pinctrl) { set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl, "ehci_sleep"); if (IS_ERR(set_state)) pr_err("cannot get hsusb pinctrl sleep state\n"); else pinctrl_select_state(mhcd->hsusb_pinctrl, set_state); } devote_xo_handle: if (mhcd->xo_clk) clk_disable_unprepare(mhcd->xo_clk); Loading Loading @@ -1561,6 +1600,7 @@ static int ehci_msm2_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct msm_hcd *mhcd = hcd_to_mhcd(hcd); struct pinctrl_state *set_state; if (mhcd->pmic_gpio_dp_irq) { if (mhcd->pmic_gpio_dp_irq_enabled) Loading Loading @@ -1594,6 +1634,15 @@ static int ehci_msm2_remove(struct platform_device *pdev) msm_ehci_ldo_init(mhcd, 0); msm_ehci_init_vddcx(mhcd, 0); if (mhcd->hsusb_pinctrl) { set_state = pinctrl_lookup_state(mhcd->hsusb_pinctrl, "ehci_sleep"); if (IS_ERR(set_state)) pr_err("cannot get hsusb pinctrl sleep state\n"); else pinctrl_select_state(mhcd->hsusb_pinctrl, set_state); } msm_ehci_init_clocks(mhcd, 0); wakeup_source_trash(&mhcd->ws); iounmap(hcd->regs); Loading