Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2aa36981 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: ehci-msm2: Add support for pinctrl framework"

parents 75c53c1a e4e4910c
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -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.
@@ -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>;
+52 −3
Original line number Diff line number Diff line
@@ -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>
@@ -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)
@@ -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;
@@ -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,
@@ -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);
@@ -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);
@@ -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);
@@ -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)
@@ -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);