From d16ab536aad208421c5ed32cdcb01b5ab6aa1f19 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 10 Sep 2019 10:54:52 +0800 Subject: usb: chipidea: udc: add new API ci_hdrc_gadget_connect This API is used enable device function, it is called at below situations: - VBUS is connected during boots up - Hot plug occurs during runtime Signed-off-by: Peter Chen Signed-off-by: Jun Li --- drivers/usb/chipidea/udc.c | 63 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 31 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 0b6166a64d72..8c4383862373 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1524,6 +1524,33 @@ static const struct usb_ep_ops usb_ep_ops = { /****************************************************************************** * GADGET block *****************************************************************************/ +/** + * ci_hdrc_gadget_connect: caller makes sure gadget driver is binded + */ +static void ci_hdrc_gadget_connect(struct usb_gadget *_gadget, int is_active) +{ + struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); + + if (is_active) { + pm_runtime_get_sync(&_gadget->dev); + hw_device_reset(ci); + hw_device_state(ci, ci->ep0out->qh.dma); + usb_gadget_set_state(_gadget, USB_STATE_POWERED); + usb_udc_vbus_handler(_gadget, true); + } else { + usb_udc_vbus_handler(_gadget, false); + if (ci->driver) + ci->driver->disconnect(&ci->gadget); + hw_device_state(ci, 0); + if (ci->platdata->notify_event) + ci->platdata->notify_event(ci, + CI_HDRC_CONTROLLER_STOPPED_EVENT); + _gadget_stop_activity(&ci->gadget); + pm_runtime_put_sync(&_gadget->dev); + usb_gadget_set_state(_gadget, USB_STATE_NOTATTACHED); + } +} + static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); @@ -1540,26 +1567,8 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) usb_phy_set_charger_state(ci->usb_phy, is_active ? USB_CHARGER_PRESENT : USB_CHARGER_ABSENT); - if (gadget_ready) { - if (is_active) { - pm_runtime_get_sync(&_gadget->dev); - hw_device_reset(ci); - hw_device_state(ci, ci->ep0out->qh.dma); - usb_gadget_set_state(_gadget, USB_STATE_POWERED); - usb_udc_vbus_handler(_gadget, true); - } else { - usb_udc_vbus_handler(_gadget, false); - if (ci->driver) - ci->driver->disconnect(&ci->gadget); - hw_device_state(ci, 0); - if (ci->platdata->notify_event) - ci->platdata->notify_event(ci, - CI_HDRC_CONTROLLER_STOPPED_EVENT); - _gadget_stop_activity(&ci->gadget); - pm_runtime_put_sync(&_gadget->dev); - usb_gadget_set_state(_gadget, USB_STATE_NOTATTACHED); - } - } + if (gadget_ready) + ci_hdrc_gadget_connect(_gadget, is_active); return 0; } @@ -1785,18 +1794,10 @@ static int ci_udc_start(struct usb_gadget *gadget, return retval; } - pm_runtime_get_sync(&ci->gadget.dev); - if (ci->vbus_active) { - hw_device_reset(ci); - } else { + if (ci->vbus_active) + ci_hdrc_gadget_connect(gadget, 1); + else usb_udc_vbus_handler(&ci->gadget, false); - pm_runtime_put_sync(&ci->gadget.dev); - return retval; - } - - retval = hw_device_state(ci, ci->ep0out->qh.dma); - if (retval) - pm_runtime_put_sync(&ci->gadget.dev); return retval; } -- cgit From 72dc8df7920fc24eba0f586c56e900a1643ff2b3 Mon Sep 17 00:00:00 2001 From: Jun Li Date: Tue, 10 Sep 2019 14:54:57 +0800 Subject: usb: chipidea: udc: protect usb interrupt enable We hit the problem with below sequence: - ci_udc_vbus_session() update vbus_active flag and ci->driver is valid, - before calling the ci_hdrc_gadget_connect(), usb_gadget_udc_stop() is called by application remove gadget driver, - ci_udc_vbus_session() will contine do ci_hdrc_gadget_connect() as gadget_ready is 1, so udc interrupt is enabled, but ci->driver is NULL. - USB connection irq generated but ci->driver is NULL. As udc irq only should be enabled when gadget driver is binded, so add spinlock to protect the usb irq enable for vbus session handling. Signed-off-by: Jun Li Signed-off-by: Peter Chen --- drivers/usb/chipidea/udc.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 8c4383862373..ffaf46f5d062 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1530,13 +1530,18 @@ static const struct usb_ep_ops usb_ep_ops = { static void ci_hdrc_gadget_connect(struct usb_gadget *_gadget, int is_active) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); + unsigned long flags; if (is_active) { pm_runtime_get_sync(&_gadget->dev); hw_device_reset(ci); - hw_device_state(ci, ci->ep0out->qh.dma); - usb_gadget_set_state(_gadget, USB_STATE_POWERED); - usb_udc_vbus_handler(_gadget, true); + spin_lock_irqsave(&ci->lock, flags); + if (ci->driver) { + hw_device_state(ci, ci->ep0out->qh.dma); + usb_gadget_set_state(_gadget, USB_STATE_POWERED); + usb_udc_vbus_handler(_gadget, true); + } + spin_unlock_irqrestore(&ci->lock, flags); } else { usb_udc_vbus_handler(_gadget, false); if (ci->driver) @@ -1555,19 +1560,16 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); unsigned long flags; - int gadget_ready = 0; spin_lock_irqsave(&ci->lock, flags); ci->vbus_active = is_active; - if (ci->driver) - gadget_ready = 1; spin_unlock_irqrestore(&ci->lock, flags); if (ci->usb_phy) usb_phy_set_charger_state(ci->usb_phy, is_active ? USB_CHARGER_PRESENT : USB_CHARGER_ABSENT); - if (gadget_ready) + if (ci->driver) ci_hdrc_gadget_connect(_gadget, is_active); return 0; @@ -1827,6 +1829,7 @@ static int ci_udc_stop(struct usb_gadget *gadget) unsigned long flags; spin_lock_irqsave(&ci->lock, flags); + ci->driver = NULL; if (ci->vbus_active) { hw_device_state(ci, 0); @@ -1839,7 +1842,6 @@ static int ci_udc_stop(struct usb_gadget *gadget) pm_runtime_put(&ci->gadget.dev); } - ci->driver = NULL; spin_unlock_irqrestore(&ci->lock, flags); ci_udc_stop_for_otg_fsm(ci); -- cgit From 93c2c7330a3b6d973cd82dfd7bcbd6df035752f6 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Mon, 9 Sep 2019 14:41:41 +0800 Subject: usb: chipidea: imx: enable vbus and id wakeup only for OTG events If ID or VBUS is from external block, don't enable its wakeup because it isn't used at all. Signed-off-by: Li Jun Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_imx.c | 8 ++++++++ drivers/usb/chipidea/ci_hdrc_imx.h | 2 ++ drivers/usb/chipidea/usbmisc_imx.c | 31 +++++++++++++++++++++++-------- 3 files changed, 33 insertions(+), 8 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index df8812c30640..2fde44ca4a48 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -433,6 +433,14 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) goto err_clk; } + if (!IS_ERR(pdata.id_extcon.edev) || + of_property_read_bool(np, "usb-role-switch")) + data->usbmisc_data->ext_id = 1; + + if (!IS_ERR(pdata.vbus_extcon.edev) || + of_property_read_bool(np, "usb-role-switch")) + data->usbmisc_data->ext_vbus = 1; + ret = imx_usbmisc_init_post(data->usbmisc_data); if (ret) { dev_err(dev, "usbmisc post failed, ret=%d\n", ret); diff --git a/drivers/usb/chipidea/ci_hdrc_imx.h b/drivers/usb/chipidea/ci_hdrc_imx.h index c842e03f8767..de2aac9a2868 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.h +++ b/drivers/usb/chipidea/ci_hdrc_imx.h @@ -22,6 +22,8 @@ struct imx_usbmisc_data { unsigned int evdo:1; /* set external vbus divider option */ unsigned int ulpi:1; /* connected to an ULPI phy */ unsigned int hsic:1; /* HSIC controlller */ + unsigned int ext_id:1; /* ID from exteranl event */ + unsigned int ext_vbus:1; /* Vbus from exteranl event */ }; int imx_usbmisc_init(struct imx_usbmisc_data *data); diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 078c1fdce493..e81e33c26e6c 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -100,6 +100,9 @@ #define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2) #define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3) +#define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \ + MX6_BM_ID_WAKEUP) + struct usbmisc_ops { /* It's called once when probe a usb device */ int (*init)(struct imx_usbmisc_data *data); @@ -330,14 +333,25 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data) return 0; } +static u32 usbmisc_wakeup_setting(struct imx_usbmisc_data *data) +{ + u32 wakeup_setting = MX6_USB_OTG_WAKEUP_BITS; + + if (data->ext_id) + wakeup_setting &= ~MX6_BM_ID_WAKEUP; + + if (data->ext_vbus) + wakeup_setting &= ~MX6_BM_VBUS_WAKEUP; + + return wakeup_setting; +} + static int usbmisc_imx6q_set_wakeup (struct imx_usbmisc_data *data, bool enabled) { struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); unsigned long flags; u32 val; - u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE | - MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP); int ret = 0; if (data->index > 3) @@ -346,11 +360,12 @@ static int usbmisc_imx6q_set_wakeup spin_lock_irqsave(&usbmisc->lock, flags); val = readl(usbmisc->base + data->index * 4); if (enabled) { - val |= wakeup_setting; + val &= ~MX6_USB_OTG_WAKEUP_BITS; + val |= usbmisc_wakeup_setting(data); } else { if (val & MX6_BM_WAKEUP_INTR) pr_debug("wakeup int at ci_hdrc.%d\n", data->index); - val &= ~wakeup_setting; + val &= ~MX6_USB_OTG_WAKEUP_BITS; } writel(val, usbmisc->base + data->index * 4); spin_unlock_irqrestore(&usbmisc->lock, flags); @@ -547,17 +562,17 @@ static int usbmisc_imx7d_set_wakeup struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); unsigned long flags; u32 val; - u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE | - MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP); spin_lock_irqsave(&usbmisc->lock, flags); val = readl(usbmisc->base); if (enabled) { - writel(val | wakeup_setting, usbmisc->base); + val &= ~MX6_USB_OTG_WAKEUP_BITS; + val |= usbmisc_wakeup_setting(data); + writel(val, usbmisc->base); } else { if (val & MX6_BM_WAKEUP_INTR) dev_dbg(data->dev, "wakeup int\n"); - writel(val & ~wakeup_setting, usbmisc->base); + writel(val & ~MX6_USB_OTG_WAKEUP_BITS, usbmisc->base); } spin_unlock_irqrestore(&usbmisc->lock, flags); -- cgit From 782c1c49f3dbf335de6b95f2d97b105cca236bc9 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 23 Sep 2019 10:34:38 +0800 Subject: usb: chipidea: core: change vbus-regulator as optional Vbus regualtor is an optional regulator, for platforms, which doesn't have this regulator, it will get a dummy regulator and show warning message. Signed-off-by: Peter Chen --- drivers/usb/chipidea/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 98ee575ee500..dce5db41501c 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -683,7 +683,7 @@ static int ci_get_platdata(struct device *dev, if (platdata->dr_mode != USB_DR_MODE_PERIPHERAL) { /* Get the vbus regulator */ - platdata->reg_vbus = devm_regulator_get(dev, "vbus"); + platdata->reg_vbus = devm_regulator_get_optional(dev, "vbus"); if (PTR_ERR(platdata->reg_vbus) == -EPROBE_DEFER) { return -EPROBE_DEFER; } else if (PTR_ERR(platdata->reg_vbus) == -ENODEV) { -- cgit From df17aa9fb31f6a41aad37b984909d8ef1a958271 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Wed, 9 Oct 2019 10:52:28 +0800 Subject: usb: chipidea: imx: check data->usbmisc_data against NULL before access As usbmisc_data is optional, so add the check before access its member, this fix below static checker warning: drivers/usb/chipidea/ci_hdrc_imx.c:438 ci_hdrc_imx_probe() warn: 'data->usbmisc_data' can also be NULL which is introduced by Patch 15b80f7c3a7f: "usb: chipidea: imx: enable vbus and id wakeup only for OTG events" Reported-by: Dan Carpenter Signed-off-by: Li Jun Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_imx.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 2fde44ca4a48..16700170bc34 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -433,13 +433,15 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) goto err_clk; } - if (!IS_ERR(pdata.id_extcon.edev) || - of_property_read_bool(np, "usb-role-switch")) - data->usbmisc_data->ext_id = 1; - - if (!IS_ERR(pdata.vbus_extcon.edev) || - of_property_read_bool(np, "usb-role-switch")) - data->usbmisc_data->ext_vbus = 1; + if (data->usbmisc_data) { + if (!IS_ERR(pdata.id_extcon.edev) || + of_property_read_bool(np, "usb-role-switch")) + data->usbmisc_data->ext_id = 1; + + if (!IS_ERR(pdata.vbus_extcon.edev) || + of_property_read_bool(np, "usb-role-switch")) + data->usbmisc_data->ext_vbus = 1; + } ret = imx_usbmisc_init_post(data->usbmisc_data); if (ret) { -- cgit From 7d5ec335f94e74e885ca2f6c97a3479fe9fe3b15 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 10 Oct 2019 08:40:46 +0800 Subject: usb: chipidea: imx: change hsic power regulator as optional Not every platform needs this regulator. Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_imx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 16700170bc34..25a38ed27aa8 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -359,7 +359,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) return PTR_ERR(data->pinctrl_hsic_active); } - data->hsic_pad_regulator = devm_regulator_get(dev, "hsic"); + data->hsic_pad_regulator = + devm_regulator_get_optional(dev, "hsic"); if (PTR_ERR(data->hsic_pad_regulator) == -EPROBE_DEFER) { return -EPROBE_DEFER; } else if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) { -- cgit From 3f4aad6e1a4c26a20700fb4f630e4e6c6831db47 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 10 Oct 2019 08:59:14 +0800 Subject: usb: chipidea: imx: refine the error handling for hsic - -EPROBE_DEFER is an error, but without need show error message - If pintrol is not existed, as pintrol is NULL Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_imx.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 25a38ed27aa8..c34fcc079cd4 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -330,8 +330,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) pdata.flags |= CI_HDRC_IMX_IS_HSIC; data->usbmisc_data->hsic = 1; data->pinctrl = devm_pinctrl_get(dev); - if (IS_ERR(data->pinctrl)) { - dev_err(dev, "pinctrl get failed, err=%ld\n", + if (PTR_ERR(data->pinctrl) == -ENODEV) + data->pinctrl = NULL; + else if (IS_ERR(data->pinctrl)) { + if (PTR_ERR(data->pinctrl) != -EPROBE_DEFER) + dev_err(dev, "pinctrl get failed, err=%ld\n", PTR_ERR(data->pinctrl)); return PTR_ERR(data->pinctrl); } @@ -361,13 +364,13 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) data->hsic_pad_regulator = devm_regulator_get_optional(dev, "hsic"); - if (PTR_ERR(data->hsic_pad_regulator) == -EPROBE_DEFER) { - return -EPROBE_DEFER; - } else if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) { + if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) { /* no pad regualator is needed */ data->hsic_pad_regulator = NULL; } else if (IS_ERR(data->hsic_pad_regulator)) { - dev_err(dev, "Get HSIC pad regulator error: %ld\n", + if (PTR_ERR(data->hsic_pad_regulator) != -EPROBE_DEFER) + dev_err(dev, + "Get HSIC pad regulator error: %ld\n", PTR_ERR(data->hsic_pad_regulator)); return PTR_ERR(data->hsic_pad_regulator); } -- cgit From 4d6141288c33b73027260e73df262464cbe1fd0d Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 10 Oct 2019 09:20:26 +0800 Subject: usb: chipidea: imx: pinctrl for HSIC is optional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For imx chipidea controllers, if they use mxs PHY, they need pinctrl for HSIC. Otherwise, it doesn't need pinctrl and usbmisc control. Like imx7d and imx8mm. Reported-by: André Draszik Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_imx.c | 63 +++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 28 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index c34fcc079cd4..d8e7eb2f97b9 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -274,11 +274,14 @@ static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event) switch (event) { case CI_HDRC_IMX_HSIC_ACTIVE_EVENT: - ret = pinctrl_select_state(data->pinctrl, - data->pinctrl_hsic_active); - if (ret) - dev_err(dev, "hsic_active select failed, err=%d\n", - ret); + if (data->pinctrl) { + ret = pinctrl_select_state(data->pinctrl, + data->pinctrl_hsic_active); + if (ret) + dev_err(dev, + "hsic_active select failed, err=%d\n", + ret); + } break; case CI_HDRC_IMX_HSIC_SUSPEND_EVENT: ret = imx_usbmisc_hsic_set_connect(data->usbmisc_data); @@ -306,7 +309,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) const struct ci_hdrc_imx_platform_flag *imx_platform_flag; struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; - struct pinctrl_state *pinctrl_hsic_idle; of_id = of_match_device(ci_hdrc_imx_dt_ids, dev); if (!of_id) @@ -339,6 +341,33 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) return PTR_ERR(data->pinctrl); } + data->hsic_pad_regulator = + devm_regulator_get_optional(dev, "hsic"); + if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) { + /* no pad regualator is needed */ + data->hsic_pad_regulator = NULL; + } else if (IS_ERR(data->hsic_pad_regulator)) { + if (PTR_ERR(data->hsic_pad_regulator) != -EPROBE_DEFER) + dev_err(dev, + "Get HSIC pad regulator error: %ld\n", + PTR_ERR(data->hsic_pad_regulator)); + return PTR_ERR(data->hsic_pad_regulator); + } + + if (data->hsic_pad_regulator) { + ret = regulator_enable(data->hsic_pad_regulator); + if (ret) { + dev_err(dev, + "Failed to enable HSIC pad regulator\n"); + return ret; + } + } + } + + /* HSIC pinctrl handling */ + if (data->pinctrl) { + struct pinctrl_state *pinctrl_hsic_idle; + pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle"); if (IS_ERR(pinctrl_hsic_idle)) { dev_err(dev, @@ -361,28 +390,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) PTR_ERR(data->pinctrl_hsic_active)); return PTR_ERR(data->pinctrl_hsic_active); } - - data->hsic_pad_regulator = - devm_regulator_get_optional(dev, "hsic"); - if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) { - /* no pad regualator is needed */ - data->hsic_pad_regulator = NULL; - } else if (IS_ERR(data->hsic_pad_regulator)) { - if (PTR_ERR(data->hsic_pad_regulator) != -EPROBE_DEFER) - dev_err(dev, - "Get HSIC pad regulator error: %ld\n", - PTR_ERR(data->hsic_pad_regulator)); - return PTR_ERR(data->hsic_pad_regulator); - } - - if (data->hsic_pad_regulator) { - ret = regulator_enable(data->hsic_pad_regulator); - if (ret) { - dev_err(dev, - "Failed to enable HSIC pad regulator\n"); - return ret; - } - } } if (pdata.flags & CI_HDRC_PMQOS) -- cgit