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

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

Merge "msm: ehci-hsic: Add support for pinctrl framework"

parents 45e239cc d034fbc8
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -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
@@ -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>;
+75 −25
Original line number Diff line number Diff line
@@ -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>
@@ -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;
@@ -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;
@@ -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;
}

@@ -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) {
@@ -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 */
@@ -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;
}

@@ -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");
@@ -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);