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

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

Merge "usb: xhci-msm-hsic: Add support for pinctrl framework"

parents 2aa36981 e29cc5ee
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -10,8 +10,22 @@ Required properties :
	change in power state.
- <supply-name>-supply: handle to the regulator device tree node
  Required "supply-name" are "hsic-vdd-dig" and "hsic-gdsc-supply".
- 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_xhci_active" : Active configuration of pins, this should specify active
	config defined in pin groups of used gpio's from strobe, data and
	host-ready.
	"hsic_xhci_sleep" : Disabled configuration of pins, this should specify sleep
	config defined in pin groups of used gpio's from strobe, data and
	host-ready.
- 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 only define gpio's which drives signals
  using gpiolib api's like host-ready 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.
  Required "gpio-name" are "strobe" and "data".
- qcom,vdd-voltage-level: This property must be a list of three integer
  values (no, min, max) where each value represents either a voltage in
@@ -41,12 +55,20 @@ Example MSM HSIC XHCI controller device node :
		interrupt-map-mask = <0xffffffff>;
		interrupt-map = <0 &intc 0 32 0
				1 &intc 0 29 0
				2 &msmgpio 107 0x8>;
				2 &msm_gpio 107 0x8>;
		interrupt-names = "core_irq", "pwr_event_irq", "wakeup_irq";
		hsic-vdd-dig-supply = <&pma8084_s2_corner>;
		hsic-gdsc-supply = <&gdsc_usb_hsic>;
		/* If pinctrl is used */
		pinctrl-names = "hsic_xhci_active","hsic_xhci_sleep";
		pinctrl-0 = <&hsic_act>;
		pinctrl-1 = <&hsic_sus>;
		qcom,host-ready-gpio = <&msm_gpio 106 0x00>;
		/* else (pinctrl is not used) */
		hsic,strobe-gpio = <&msmgpio 134 0x00>;
		hsic,data-gpio = <&msmgpio 135 0x00>;
		qcom,host-ready-gpio = <&msmgpio 106 0x00>;
		/* End */
		qcom,vdd-voltage-level = <1 5 7>;

		qcom,msm-bus,name = "hsic";
+70 −23
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/of_gpio.h>
#include <linux/irq.h>
#include <linux/dma-mapping.h>
#include <linux/pinctrl/consumer.h>
#include <linux/bitops.h>
#include <linux/workqueue.h>
#include <linux/clk/msm-clk.h>
@@ -117,6 +118,7 @@ struct mxhci_hsic_hcd {

	uint32_t		wakeup_int_cnt;
	uint32_t		pwr_evt_irq_inlpm;
	struct pinctrl		*hsic_pinctrl;
};

#define SYNOPSIS_DWC3_VENDOR	0x5533
@@ -361,18 +363,31 @@ static int mxhci_msm_config_gdsc(struct mxhci_hsic_hcd *mxhci, int on)
static int mxhci_hsic_config_gpios(struct mxhci_hsic_hcd *mxhci)
{
	int rc = 0;

	rc = devm_gpio_request(mxhci->dev, mxhci->strobe, "HSIC_STROBE_GPIO");
	struct pinctrl_state *set_state;

	if (mxhci->hsic_pinctrl) {
		set_state = pinctrl_lookup_state(mxhci->hsic_pinctrl,
				"hsic_xhci_active");
		if (IS_ERR(set_state)) {
			pr_err("cannot get hsic pinctrl active state\n");
			rc = PTR_ERR(set_state);
			goto out;
		}
		rc = pinctrl_select_state(mxhci->hsic_pinctrl, set_state);
	} else {
		rc = devm_gpio_request(mxhci->dev, mxhci->strobe,
				"HSIC_STROBE_GPIO");
		if (rc < 0) {
			dev_err(mxhci->dev, "gpio request failed for HSIC STROBE\n");
			goto out;
		}

	rc = devm_gpio_request(mxhci->dev, mxhci->data, "HSIC_DATA_GPIO");
		rc = devm_gpio_request(mxhci->dev, mxhci->data,
				"HSIC_DATA_GPIO");
		if (rc < 0) {
			dev_err(mxhci->dev, "gpio request failed for HSIC DATA\n");
			goto out;
		}
	}

	if (mxhci->host_ready) {
		rc = devm_gpio_request(mxhci->dev,
@@ -395,7 +410,6 @@ static int mxhci_hsic_config_gpios(struct mxhci_hsic_hcd *mxhci)
			rc = 0;
		}
	}

out:
	return rc;
}
@@ -982,6 +996,7 @@ static int mxhci_hsic_probe(struct platform_device *pdev)
	struct xhci_hcd		*xhci;
	struct resource *res;
	struct usb_hcd *hcd;
	struct pinctrl_state *set_state;
	unsigned int reg;
	int ret;
	int irq;
@@ -1033,6 +1048,19 @@ static int mxhci_hsic_probe(struct platform_device *pdev)
	mxhci = hcd_to_hsic(hcd);
	mxhci->dev = &pdev->dev;

	/* Get pinctrl if target uses pinctrl */
	mxhci->hsic_pinctrl = devm_pinctrl_get(&pdev->dev);
	if (IS_ERR(mxhci->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(mxhci->hsic_pinctrl);
			goto put_hcd;
		}
		dev_dbg(&pdev->dev, "Target does not use pinctrl\n");
		mxhci->hsic_pinctrl = NULL;
	}

	if (IS_ERR_OR_NULL(mxhci->hsic_pinctrl)) {
		mxhci->strobe = of_get_named_gpio(node, "hsic,strobe-gpio", 0);
		if (mxhci->strobe < 0) {
			ret = -EINVAL;
@@ -1044,7 +1072,7 @@ static int mxhci_hsic_probe(struct platform_device *pdev)
			ret = -EINVAL;
			goto put_hcd;
		}

	}
	mxhci->host_ready = of_get_named_gpio(node,
					"qcom,host-ready-gpio", 0);
	if (mxhci->host_ready < 0)
@@ -1136,13 +1164,13 @@ static int mxhci_hsic_probe(struct platform_device *pdev)
		if (ret) {
			dev_err(&pdev->dev,
					"request irq failed (wakeup irq)\n");
			goto deinit_vddcx;
			goto pinctrl_sleep;
		}
	}

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto deinit_vddcx;
		goto pinctrl_sleep;

	hcd = dev_get_drvdata(&pdev->dev);
	xhci = hcd_to_xhci(hcd);
@@ -1253,6 +1281,15 @@ remove_usb2_hcd:
	usb_remove_hcd(hcd);
deinit_vddcx:
	mxhci_hsic_init_vddcx(mxhci, 0);
pinctrl_sleep:
	if (mxhci->hsic_pinctrl) {
		set_state = pinctrl_lookup_state(mxhci->hsic_pinctrl,
				"hsic_xhci_sleep");
		if (IS_ERR(set_state))
			pr_err("cannot get hsic pinctrl sleep state\n");
		else
			pinctrl_select_state(mxhci->hsic_pinctrl, set_state);
	}
deinit_clocks:
	mxhci_hsic_init_clocks(mxhci, 0);
put_hcd:
@@ -1266,6 +1303,7 @@ static int mxhci_hsic_remove(struct platform_device *pdev)
	struct usb_hcd	*hcd = platform_get_drvdata(pdev);
	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
	struct mxhci_hsic_hcd *mxhci = hcd_to_hsic(hcd);
	struct pinctrl_state *set_state;
	u32 reg;

	xhci_dbg_log_event(&dbg_hsic, NULL,  "mxhci_hsic_remove", 0);
@@ -1307,6 +1345,15 @@ static int mxhci_hsic_remove(struct platform_device *pdev)

	destroy_workqueue(mxhci->wq);

	if (mxhci->hsic_pinctrl) {
		set_state = pinctrl_lookup_state(mxhci->hsic_pinctrl,
				"hsic_xhci_sleep");
		if (IS_ERR(set_state))
			pr_err("cannot get hsic pinctrl sleep state\n");
		else
			pinctrl_select_state(mxhci->hsic_pinctrl, set_state);
	}

	device_wakeup_disable(&pdev->dev);
	mxhci_hsic_init_vddcx(mxhci, 0);
	mxhci_hsic_init_clocks(mxhci, 0);