Loading Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt +22 −1 Original line number Diff line number Diff line Loading @@ -27,8 +27,22 @@ Optional properties : - interrupt-names : Optional interrupt resource entries are: "async_irq" : Interrupt from HSIC for asynchronous events in HSIC LPM. "wakeup" : Wakeup interrupt from HSIC during suspend (or XO shutdown). - 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 "hsic_ehci_active" : Active configuration of pins, this should specify active config defined in pin groups of used gpio's from strobe, data and resume. "hsic_ehci_sleep" : Disabled configuration of pins, this should specify sleep config defined in pin groups of used gpio's from strobe, data and resume. - hsic,<gpio-name>-gpio : handle to the GPIO node, see "gpios property" in Documentation/devicetree/bindings/gpio/gpio.txt. If pinctrl is being used we need to define only gpio's which drives signals using gpiolib api's like resume gpio in dt, the node name in such cases should be msm_gpio as defined in pinctrl-dtsi. For gpio's only installing active and sleep configs it is not required to specify the gpio in dt file. Optional "gpio-name" can be "strobe", "data" and "resume". - hsic,resume-gpio : if present then periperal connected to hsic controller cannot wakeup from XO shutdown using in-band hsic resume. Use resume Loading Loading @@ -109,13 +123,20 @@ Example MSM HSIC EHCI controller device node : interrupt-map-mask = <0xffffffff>; interrupt-map = <0 &intc 0 136 0 1 &intc 0 148 0 2 &msmgpio 144 0x8>; 2 &msm_gpio 144 0x8>; interrupt-names = "core_irq", "async_irq", "wakeup"; hsic_vdd_dig-supply = <&pm8841_s2_corner>; HSIC_GDSC-supply = <&gdsc_usb_hsic>; /* If pinctrl is used and resume gpio is present */ pinctrl-names = "hsic_ehci_active","hsic_ehci_sleep"; pinctrl-0 = <&hsic_act &resume_act>; pinctrl-1 = <&hsic_sus &resume_act>; hsic,resume-gpio = <&msm_gpio 80 0x00>; /* else (pinctrl is not present) */ hsic,strobe-gpio = <&msmgpio 144 0x00>; hsic,data-gpio = <&msmgpio 145 0x00>; hsic,resume-gpio = <&msmgpio 80 0x00>; /* End */ hsic,ignore-cal-pad-config; hsic,strobe-pad-offset = <0x2050>; hsic,data-pad-offset = <0x2054>; Loading drivers/usb/host/ehci-msm-hsic.c +75 −25 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/seq_file.h> #include <linux/wakelock.h> #include <linux/pm_runtime.h> #include <linux/pinctrl/consumer.h> #include <linux/regulator/consumer.h> #include <linux/usb.h> #include <linux/usb/hcd.h> Loading Loading @@ -114,6 +115,8 @@ struct msm_hsic_hcd { struct pm_qos_request pm_qos_req_dma; unsigned enable_hbm:1; struct pinctrl *hsic_pinctrl; }; struct msm_hsic_hcd *__mehci; Loading Loading @@ -533,6 +536,31 @@ static int ulpi_write(struct msm_hsic_hcd *mehci, u32 val, u32 reg) return 0; } static int msm_hsic_config_pinctrl(struct msm_hsic_hcd *mehci, int state) { struct pinctrl_state *set_state; int rc = 0; if (state) { set_state = pinctrl_lookup_state(mehci->hsic_pinctrl, "hsic_ehci_active"); if (IS_ERR(set_state)) { pr_err("cannot get hsic pinctrl active state\n"); return PTR_ERR(set_state); } rc = pinctrl_select_state(mehci->hsic_pinctrl, set_state); } else { set_state = pinctrl_lookup_state(mehci->hsic_pinctrl, "hsic_ehci_sleep"); if (IS_ERR(set_state)) { pr_err("cannot get hsic pinctrl sleep state\n"); return PTR_ERR(set_state); } rc = pinctrl_select_state(mehci->hsic_pinctrl, set_state); } return rc; } static int msm_hsic_config_gpios(struct msm_hsic_hcd *mehci, int gpio_en) { int rc = 0; Loading @@ -541,36 +569,35 @@ static int msm_hsic_config_gpios(struct msm_hsic_hcd *mehci, int gpio_en) pdata = mehci->dev->platform_data; if (!pdata || !pdata->strobe || !pdata->data) return rc; if (!pdata) return -ENODEV; if (gpio_status == gpio_en) if (gpio_status == gpio_en || mehci->hsic_pinctrl) return 0; gpio_status = gpio_en; if (!gpio_en) goto free_gpio; if (!pdata->strobe || !pdata->data) return -ENODEV; if (gpio_en) { rc = gpio_request(pdata->strobe, "HSIC_STROBE_GPIO"); if (rc < 0) { dev_err(mehci->dev, "gpio request failed for HSIC STROBE\n"); return rc; goto out; } rc = gpio_request(pdata->data, "HSIC_DATA_GPIO"); if (rc < 0) { dev_err(mehci->dev, "gpio request failed for HSIC DATA\n"); goto free_strobe; gpio_free(pdata->strobe); goto out; } return 0; free_gpio: } else { gpio_free(pdata->data); free_strobe: gpio_free(pdata->strobe); } gpio_status = gpio_en; out: return rc; } Loading Loading @@ -656,6 +683,14 @@ static int msm_hsic_start(struct msm_hsic_hcd *mehci) int ret; void __iomem *reg; if (mehci->hsic_pinctrl) { ret = msm_hsic_config_pinctrl(mehci, 1); if (ret) { dev_err(mehci->dev, "pinctrl configuarion failed:%d\n", ret); return ret; } } if (pdata && pdata->resume_gpio) { ret = gpio_request(pdata->resume_gpio, "HSIC_RESUME_GPIO"); if (ret < 0) { Loading @@ -667,7 +702,7 @@ static int msm_hsic_start(struct msm_hsic_hcd *mehci) /* HSIC init sequence when HSIC signals (Strobe/Data) are routed via GPIOs */ if (pdata && pdata->strobe && pdata->data) { if (pdata && ((pdata->strobe && pdata->data) || mehci->hsic_pinctrl)) { if (!pdata->ignore_cal_pad_config) { /* Enable LV_MODE in HSIC_CAL_PAD_CTL register */ Loading Loading @@ -739,7 +774,8 @@ static int msm_hsic_start(struct msm_hsic_hcd *mehci) free_resume_gpio: if (pdata && pdata->resume_gpio) gpio_free(pdata->resume_gpio); if (mehci->hsic_pinctrl) msm_hsic_config_pinctrl(mehci, 0); return ret; } Loading Loading @@ -2073,6 +2109,18 @@ static int ehci_hsic_msm_probe(struct platform_device *pdev) goto destroy_wq; } /* Check whether target uses pinctrl */ mehci->hsic_pinctrl = devm_pinctrl_get(&pdev->dev); if (IS_ERR(mehci->hsic_pinctrl)) { if (of_property_read_bool(pdev->dev.of_node, "pinctrl-names")) { dev_err(&pdev->dev, "Error encountered while getting pinctrl"); ret = PTR_ERR(mehci->hsic_pinctrl); goto destroy_wq; } dev_dbg(&pdev->dev, "Target does not use pinctrl\n"); mehci->hsic_pinctrl = NULL; } ret = msm_hsic_start(mehci); if (ret) { dev_err(&pdev->dev, "unable to initialize PHY\n"); Loading Loading @@ -2251,6 +2299,8 @@ static int ehci_hsic_msm_remove(struct platform_device *pdev) if (pdata && pdata->resume_gpio) gpio_free(pdata->resume_gpio); if (mehci->hsic_pinctrl) msm_hsic_config_pinctrl(mehci, 0); msm_hsic_init_vddcx(mehci, 0); msm_hsic_init_gdsc(mehci, 0); Loading Loading
Documentation/devicetree/bindings/usb/msm-ehci-hsic.txt +22 −1 Original line number Diff line number Diff line Loading @@ -27,8 +27,22 @@ Optional properties : - interrupt-names : Optional interrupt resource entries are: "async_irq" : Interrupt from HSIC for asynchronous events in HSIC LPM. "wakeup" : Wakeup interrupt from HSIC during suspend (or XO shutdown). - 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 "hsic_ehci_active" : Active configuration of pins, this should specify active config defined in pin groups of used gpio's from strobe, data and resume. "hsic_ehci_sleep" : Disabled configuration of pins, this should specify sleep config defined in pin groups of used gpio's from strobe, data and resume. - hsic,<gpio-name>-gpio : handle to the GPIO node, see "gpios property" in Documentation/devicetree/bindings/gpio/gpio.txt. If pinctrl is being used we need to define only gpio's which drives signals using gpiolib api's like resume gpio in dt, the node name in such cases should be msm_gpio as defined in pinctrl-dtsi. For gpio's only installing active and sleep configs it is not required to specify the gpio in dt file. Optional "gpio-name" can be "strobe", "data" and "resume". - hsic,resume-gpio : if present then periperal connected to hsic controller cannot wakeup from XO shutdown using in-band hsic resume. Use resume Loading Loading @@ -109,13 +123,20 @@ Example MSM HSIC EHCI controller device node : interrupt-map-mask = <0xffffffff>; interrupt-map = <0 &intc 0 136 0 1 &intc 0 148 0 2 &msmgpio 144 0x8>; 2 &msm_gpio 144 0x8>; interrupt-names = "core_irq", "async_irq", "wakeup"; hsic_vdd_dig-supply = <&pm8841_s2_corner>; HSIC_GDSC-supply = <&gdsc_usb_hsic>; /* If pinctrl is used and resume gpio is present */ pinctrl-names = "hsic_ehci_active","hsic_ehci_sleep"; pinctrl-0 = <&hsic_act &resume_act>; pinctrl-1 = <&hsic_sus &resume_act>; hsic,resume-gpio = <&msm_gpio 80 0x00>; /* else (pinctrl is not present) */ hsic,strobe-gpio = <&msmgpio 144 0x00>; hsic,data-gpio = <&msmgpio 145 0x00>; hsic,resume-gpio = <&msmgpio 80 0x00>; /* End */ hsic,ignore-cal-pad-config; hsic,strobe-pad-offset = <0x2050>; hsic,data-pad-offset = <0x2054>; Loading
drivers/usb/host/ehci-msm-hsic.c +75 −25 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/seq_file.h> #include <linux/wakelock.h> #include <linux/pm_runtime.h> #include <linux/pinctrl/consumer.h> #include <linux/regulator/consumer.h> #include <linux/usb.h> #include <linux/usb/hcd.h> Loading Loading @@ -114,6 +115,8 @@ struct msm_hsic_hcd { struct pm_qos_request pm_qos_req_dma; unsigned enable_hbm:1; struct pinctrl *hsic_pinctrl; }; struct msm_hsic_hcd *__mehci; Loading Loading @@ -533,6 +536,31 @@ static int ulpi_write(struct msm_hsic_hcd *mehci, u32 val, u32 reg) return 0; } static int msm_hsic_config_pinctrl(struct msm_hsic_hcd *mehci, int state) { struct pinctrl_state *set_state; int rc = 0; if (state) { set_state = pinctrl_lookup_state(mehci->hsic_pinctrl, "hsic_ehci_active"); if (IS_ERR(set_state)) { pr_err("cannot get hsic pinctrl active state\n"); return PTR_ERR(set_state); } rc = pinctrl_select_state(mehci->hsic_pinctrl, set_state); } else { set_state = pinctrl_lookup_state(mehci->hsic_pinctrl, "hsic_ehci_sleep"); if (IS_ERR(set_state)) { pr_err("cannot get hsic pinctrl sleep state\n"); return PTR_ERR(set_state); } rc = pinctrl_select_state(mehci->hsic_pinctrl, set_state); } return rc; } static int msm_hsic_config_gpios(struct msm_hsic_hcd *mehci, int gpio_en) { int rc = 0; Loading @@ -541,36 +569,35 @@ static int msm_hsic_config_gpios(struct msm_hsic_hcd *mehci, int gpio_en) pdata = mehci->dev->platform_data; if (!pdata || !pdata->strobe || !pdata->data) return rc; if (!pdata) return -ENODEV; if (gpio_status == gpio_en) if (gpio_status == gpio_en || mehci->hsic_pinctrl) return 0; gpio_status = gpio_en; if (!gpio_en) goto free_gpio; if (!pdata->strobe || !pdata->data) return -ENODEV; if (gpio_en) { rc = gpio_request(pdata->strobe, "HSIC_STROBE_GPIO"); if (rc < 0) { dev_err(mehci->dev, "gpio request failed for HSIC STROBE\n"); return rc; goto out; } rc = gpio_request(pdata->data, "HSIC_DATA_GPIO"); if (rc < 0) { dev_err(mehci->dev, "gpio request failed for HSIC DATA\n"); goto free_strobe; gpio_free(pdata->strobe); goto out; } return 0; free_gpio: } else { gpio_free(pdata->data); free_strobe: gpio_free(pdata->strobe); } gpio_status = gpio_en; out: return rc; } Loading Loading @@ -656,6 +683,14 @@ static int msm_hsic_start(struct msm_hsic_hcd *mehci) int ret; void __iomem *reg; if (mehci->hsic_pinctrl) { ret = msm_hsic_config_pinctrl(mehci, 1); if (ret) { dev_err(mehci->dev, "pinctrl configuarion failed:%d\n", ret); return ret; } } if (pdata && pdata->resume_gpio) { ret = gpio_request(pdata->resume_gpio, "HSIC_RESUME_GPIO"); if (ret < 0) { Loading @@ -667,7 +702,7 @@ static int msm_hsic_start(struct msm_hsic_hcd *mehci) /* HSIC init sequence when HSIC signals (Strobe/Data) are routed via GPIOs */ if (pdata && pdata->strobe && pdata->data) { if (pdata && ((pdata->strobe && pdata->data) || mehci->hsic_pinctrl)) { if (!pdata->ignore_cal_pad_config) { /* Enable LV_MODE in HSIC_CAL_PAD_CTL register */ Loading Loading @@ -739,7 +774,8 @@ static int msm_hsic_start(struct msm_hsic_hcd *mehci) free_resume_gpio: if (pdata && pdata->resume_gpio) gpio_free(pdata->resume_gpio); if (mehci->hsic_pinctrl) msm_hsic_config_pinctrl(mehci, 0); return ret; } Loading Loading @@ -2073,6 +2109,18 @@ static int ehci_hsic_msm_probe(struct platform_device *pdev) goto destroy_wq; } /* Check whether target uses pinctrl */ mehci->hsic_pinctrl = devm_pinctrl_get(&pdev->dev); if (IS_ERR(mehci->hsic_pinctrl)) { if (of_property_read_bool(pdev->dev.of_node, "pinctrl-names")) { dev_err(&pdev->dev, "Error encountered while getting pinctrl"); ret = PTR_ERR(mehci->hsic_pinctrl); goto destroy_wq; } dev_dbg(&pdev->dev, "Target does not use pinctrl\n"); mehci->hsic_pinctrl = NULL; } ret = msm_hsic_start(mehci); if (ret) { dev_err(&pdev->dev, "unable to initialize PHY\n"); Loading Loading @@ -2251,6 +2299,8 @@ static int ehci_hsic_msm_remove(struct platform_device *pdev) if (pdata && pdata->resume_gpio) gpio_free(pdata->resume_gpio); if (mehci->hsic_pinctrl) msm_hsic_config_pinctrl(mehci, 0); msm_hsic_init_vddcx(mehci, 0); msm_hsic_init_gdsc(mehci, 0); Loading