summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.c156
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.h8
-rw-r--r--drivers/usb/chipidea/host.c43
-rw-r--r--drivers/usb/chipidea/usbmisc_imx.c121
-rw-r--r--include/linux/usb/chipidea.h3
5 files changed, 329 insertions, 2 deletions
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 52aab74a1b4e..549184b8acbf 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -24,6 +24,7 @@
#include <linux/mfd/syscon.h>
#include <linux/power/imx6_usb_charger.h>
#include <linux/busfreq-imx6.h>
+#include <linux/regulator/consumer.h>
#include "ci.h"
#include "ci_hdrc_imx.h"
@@ -72,8 +73,33 @@ struct ci_hdrc_imx_data {
bool imx6_usb_charger_detection;
struct usb_charger charger;
struct regmap *anatop;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pinctrl_hsic_active;
+ struct regulator *hsic_pad_regulator;
+ const struct ci_hdrc_imx_platform_flag *data;
};
+static inline bool is_imx6q_con(struct ci_hdrc_imx_data *imx_data)
+{
+ return imx_data->data == &imx6q_usb_data;
+}
+
+static inline bool is_imx6sl_con(struct ci_hdrc_imx_data *imx_data)
+{
+ return imx_data->data == &imx6sl_usb_data;
+}
+
+static inline bool is_imx6sx_con(struct ci_hdrc_imx_data *imx_data)
+{
+ return imx_data->data == &imx6sx_usb_data;
+}
+
+static inline bool imx_has_hsic_con(struct ci_hdrc_imx_data *imx_data)
+{
+ return is_imx6q_con(imx_data) || is_imx6sl_con(imx_data)
+ || is_imx6sx_con(imx_data);
+}
+
/* Common functions shared by usbmisc drivers */
static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
@@ -119,6 +145,26 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
if (of_find_property(np, "external-vbus-divider", NULL))
data->evdo = 1;
+ if (of_find_property(np, "osc-clkgate-delay", NULL)) {
+ ret = of_property_read_u32(np, "osc-clkgate-delay",
+ &data->osc_clkgate_delay);
+ if (ret) {
+ dev_err(dev,
+ "failed to get osc-clkgate-delay value\n");
+ return ERR_PTR(ret);
+ }
+ /*
+ * 0 <= osc_clkgate_delay <=7
+ * - 0x0 (default) is 0.5ms,
+ * - 0x1-0x7: 1-7ms
+ */
+ if (data->osc_clkgate_delay > 7) {
+ dev_err(dev,
+ "value of osc-clkgate-delay is incorrect\n");
+ return ERR_PTR(-EINVAL);
+ }
+ }
+
return data;
}
@@ -148,6 +194,28 @@ static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned event)
return ret;
imx6_usb_charger_detect_post(&data->charger);
break;
+ case CI_HDRC_IMX_HSIC_ACTIVE_EVENT:
+ if (!IS_ERR(data->pinctrl) &&
+ !IS_ERR(data->pinctrl_hsic_active)) {
+ ret = pinctrl_select_state(data->pinctrl,
+ data->pinctrl_hsic_active);
+ if (ret)
+ dev_err(dev,
+ "hsic_active select failed, err=%d\n",
+ ret);
+ return ret;
+ }
+ break;
+ case CI_HDRC_IMX_HSIC_SUSPEND_EVENT:
+ if (data->usbmisc_data) {
+ ret = imx_usbmisc_hsic_set_connect(data->usbmisc_data);
+ if (ret)
+ dev_err(dev,
+ "hsic_set_connect failed, err=%d\n",
+ ret);
+ return ret;
+ }
+ break;
default:
dev_dbg(dev, "unknown event\n");
}
@@ -169,6 +237,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
of_match_device(ci_hdrc_imx_dt_ids, &pdev->dev);
const struct ci_hdrc_imx_platform_flag *imx_platform_flag = of_id->data;
struct device_node *np = pdev->dev.of_node;
+ struct pinctrl_state *pinctrl_hsic_idle;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -176,10 +245,40 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
+ data->data = imx_platform_flag;
data->usbmisc_data = usbmisc_get_init_data(&pdev->dev);
if (IS_ERR(data->usbmisc_data))
return PTR_ERR(data->usbmisc_data);
+ data->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR(data->pinctrl)) {
+ dev_dbg(&pdev->dev, "pinctrl get failed, err=%ld\n",
+ PTR_ERR(data->pinctrl));
+ } else {
+ pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
+ if (IS_ERR(pinctrl_hsic_idle)) {
+ dev_dbg(&pdev->dev,
+ "pinctrl_hsic_idle lookup failed, err=%ld\n",
+ PTR_ERR(pinctrl_hsic_idle));
+ } else {
+ ret = pinctrl_select_state(data->pinctrl,
+ pinctrl_hsic_idle);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "hsic_idle select failed, err=%d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
+ "active");
+ if (IS_ERR(data->pinctrl_hsic_active))
+ dev_dbg(&pdev->dev,
+ "pinctrl_hsic_active lookup failed, err=%ld\n",
+ PTR_ERR(data->pinctrl_hsic_active));
+ }
+
data->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(data->clk)) {
dev_err(&pdev->dev,
@@ -214,6 +313,34 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
if (ret)
goto err_clk;
+ if (data->usbmisc_data->index > 1 && (imx_has_hsic_con(data))) {
+ pdata.flags |= CI_HDRC_IMX_IS_HSIC;
+ data->hsic_pad_regulator = devm_regulator_get(&pdev->dev,
+ "pad");
+ if (PTR_ERR(data->hsic_pad_regulator) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto err_clk;
+ } else 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(&pdev->dev,
+ "Get hsic pad regulator error: %ld\n",
+ PTR_ERR(data->hsic_pad_regulator));
+ ret = PTR_ERR(data->hsic_pad_regulator);
+ goto err_clk;
+ }
+
+ if (data->hsic_pad_regulator) {
+ ret = regulator_enable(data->hsic_pad_regulator);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Fail to enable hsic pad regulator\n");
+ goto err_clk;
+ }
+ }
+ }
+
if (of_find_property(np, "imx6-usb-charger-detection", NULL))
data->imx6_usb_charger_detection = true;
@@ -224,15 +351,17 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev,
"failed to find regmap for anatop\n");
ret = PTR_ERR(data->anatop);
- goto err_clk;
+ goto disable_hsic_regulator;
}
+ if (data->usbmisc_data)
+ data->usbmisc_data->anatop = data->anatop;
if (data->imx6_usb_charger_detection) {
data->charger.anatop = data->anatop;
data->charger.dev = &pdev->dev;
ret = imx6_usb_create_charger(&data->charger,
"imx6_usb_charger");
if (ret && ret != -ENODEV)
- goto err_clk;
+ goto disable_hsic_regulator;
if (!ret)
dev_dbg(&pdev->dev,
"USB Charger is created\n");
@@ -276,6 +405,9 @@ disable_device:
remove_charger:
if (data->imx6_usb_charger_detection)
imx6_usb_remove_charger(&data->charger);
+disable_hsic_regulator:
+ if (data->hsic_pad_regulator)
+ ret = regulator_disable(data->hsic_pad_regulator);
err_clk:
clk_disable_unprepare(data->clk);
release_bus_freq(BUS_FREQ_HIGH);
@@ -296,6 +428,8 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
release_bus_freq(BUS_FREQ_HIGH);
if (data->imx6_usb_charger_detection)
imx6_usb_remove_charger(&data->charger);
+ if (data->hsic_pad_regulator)
+ regulator_disable(data->hsic_pad_regulator);
return 0;
}
@@ -304,9 +438,19 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
static int imx_controller_suspend(struct device *dev)
{
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+ int ret;
dev_dbg(dev, "at %s\n", __func__);
+ if (data->usbmisc_data) {
+ ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, false);
+ if (ret) {
+ dev_err(dev,
+ "usbmisc hsic_set_clk failed, ret=%d\n", ret);
+ return ret;
+ }
+ }
+
clk_disable_unprepare(data->clk);
release_bus_freq(BUS_FREQ_HIGH);
data->in_lpm = true;
@@ -351,8 +495,16 @@ static int imx_controller_resume(struct device *dev)
goto clk_disable;
}
+ ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, true);
+ if (ret) {
+ dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
+ goto hsic_set_clk_fail;
+ }
+
return 0;
+hsic_set_clk_fail:
+ imx_usbmisc_set_wakeup(data->usbmisc_data, true);
clk_disable:
clk_disable_unprepare(data->clk);
release_bus_freq(BUS_FREQ_HIGH);
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.h b/drivers/usb/chipidea/ci_hdrc_imx.h
index 620c538c9a1a..99765ef6a6d0 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.h
+++ b/drivers/usb/chipidea/ci_hdrc_imx.h
@@ -18,11 +18,19 @@ struct imx_usbmisc_data {
unsigned int disable_oc:1; /* over current detect disabled */
unsigned int evdo:1; /* set external vbus divider option */
+ /*
+ * Specifies the delay between powering up the xtal 24MHz clock
+ * and release the clock to the digital logic inside the analog block
+ */
+ unsigned int osc_clkgate_delay;
+ struct regmap *anatop;
};
int imx_usbmisc_init(struct imx_usbmisc_data *);
int imx_usbmisc_init_post(struct imx_usbmisc_data *);
int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *, bool);
int imx_usbmisc_power_lost_check(struct imx_usbmisc_data *);
+int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *);
+int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *, bool);
#endif /* __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H */
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 20c720199cff..6e5a2b9f0088 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -43,6 +43,20 @@ struct ehci_ci_priv {
struct regulator *reg_vbus;
};
+/* This function is used to override WKCN, WKDN, and WKOC */
+static void ci_ehci_override_wakeup_flag(struct ehci_hcd *ehci,
+ u32 __iomem *reg, u32 flags, bool set)
+{
+ u32 val = ehci_readl(ehci, reg);
+
+ if (set)
+ val |= flags;
+ else
+ val &= ~flags;
+
+ ehci_writel(ehci, val, reg);
+}
+
static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -122,6 +136,8 @@ static int ci_imx_ehci_hub_control(
u32 temp;
unsigned long flags;
int retval = 0;
+ struct device *dev = hcd->self.controller;
+ struct ci_hdrc *ci = dev_get_drvdata(dev);
status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
@@ -146,6 +162,14 @@ static int ci_imx_ehci_hub_control(
PORT_SUSPEND, 5000))
ehci_err(ehci, "timeout waiting for SUSPEND\n");
+ if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
+ if (ci->platdata->notify_event)
+ ci->platdata->notify_event
+ (ci, CI_HDRC_IMX_HSIC_SUSPEND_EVENT);
+ ci_ehci_override_wakeup_flag(ehci, status_reg,
+ PORT_WKDISC_E | PORT_WKCONN_E, false);
+ }
+
spin_unlock_irqrestore(&ehci->lock, flags);
if (ehci_port_speed(ehci, temp) ==
USB_PORT_STAT_HIGH_SPEED && hcd->usb_phy) {
@@ -248,6 +272,11 @@ static int host_start(struct ci_hdrc *ci)
if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING)
hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
+ if (ci->platdata->notify_event &&
+ (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC))
+ ci->platdata->notify_event
+ (ci, CI_HDRC_IMX_HSIC_ACTIVE_EVENT);
+
return ret;
put_hcd:
@@ -361,6 +390,8 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int port;
u32 tmp;
+ struct device *dev = hcd->self.controller;
+ struct ci_hdrc *ci = dev_get_drvdata(dev);
int ret = orig_bus_suspend(hcd);
@@ -391,6 +422,18 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
*/
usleep_range(150, 200);
+ /*
+ * If a transaction is in progress, there may be a delay in
+ * suspending the port. Poll until the port is suspended.
+ */
+ if (ehci_handshake(ehci, reg, PORT_SUSPEND,
+ PORT_SUSPEND, 5000))
+ ehci_err(ehci, "timeout waiting for SUSPEND\n");
+
+ if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC)
+ ci_ehci_override_wakeup_flag(ehci, reg,
+ PORT_WKDISC_E | PORT_WKCONN_E, false);
+
if (hcd->usb_phy && test_bit(port, &ehci->bus_suspended)
&& (ehci_port_speed(ehci, portsc) ==
USB_PORT_STAT_HIGH_SPEED))
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index 4139ae11f6d9..3abe742b3684 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -14,6 +14,7 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <linux/regmap.h>
#include "ci_hdrc_imx.h"
@@ -56,10 +57,22 @@
#define MX6_BM_OVER_CUR_DIS BIT(7)
#define MX6_BM_WAKEUP_ENABLE BIT(10)
+#define MX6_BM_UTMI_ON_CLOCK BIT(13)
#define MX6_BM_ID_WAKEUP BIT(16)
#define MX6_BM_VBUS_WAKEUP BIT(17)
#define MX6SX_BM_DPDM_WAKEUP_EN BIT(29)
#define MX6_BM_WAKEUP_INTR BIT(31)
+
+#define MX6_USB_HSIC_CTRL_OFFSET 0x10
+/* Send resume signal without 480Mhz PHY clock */
+#define MX6SX_BM_HSIC_AUTO_RESUME BIT(23)
+/* set before portsc.suspendM = 1 */
+#define MX6_BM_HSIC_DEV_CONN BIT(21)
+/* HSIC enable */
+#define MX6_BM_HSIC_EN BIT(12)
+/* Force HSIC module 480M clock on, even when in Host is in suspend mode */
+#define MX6_BM_HSIC_CLK_ON BIT(11)
+
#define MX6_USB_OTG1_PHY_CTRL 0x18
/* For imx6dql, it is host-only controller, for later imx6, it is otg's */
#define MX6_USB_OTG2_PHY_CTRL 0x1c
@@ -71,6 +84,10 @@
#define VF610_OVER_CUR_DIS BIT(7)
+#define ANADIG_ANA_MISC0 0x150
+#define ANADIG_ANA_MISC0_SET 0x154
+#define ANADIG_ANA_MISC0_CLK_DELAY(x) ((x >> 26) & 0x7)
+
struct usbmisc_ops {
/* It's called once when probe a usb device */
int (*init)(struct imx_usbmisc_data *data);
@@ -80,6 +97,10 @@ struct usbmisc_ops {
int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
/* It's called when system resume from usb power lost */
int (*power_lost_check)(struct imx_usbmisc_data *data);
+ /* It's called before setting portsc.suspendM */
+ int (*hsic_set_connect)(struct imx_usbmisc_data *data);
+ /* It's called during suspend/resume */
+ int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled);
};
struct imx_usbmisc {
@@ -219,6 +240,49 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data)
return 0;
}
+static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data)
+{
+ unsigned long flags;
+ u32 val;
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ if (data->index == 2 || data->index == 3) {
+ val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+ if (!(val & MX6_BM_HSIC_DEV_CONN))
+ writel(val | MX6_BM_HSIC_DEV_CONN,
+ usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+ }
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ return 0;
+}
+
+static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on)
+{
+ unsigned long flags;
+ u32 val;
+ struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ if (data->index == 2 || data->index == 3) {
+ val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+ val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON;
+ if (on)
+ val |= MX6_BM_HSIC_CLK_ON;
+ else
+ val &= ~MX6_BM_HSIC_CLK_ON;
+ writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+ }
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ return 0;
+}
+
static int usbmisc_imx6q_set_wakeup
(struct imx_usbmisc_data *data, bool enabled)
{
@@ -296,6 +360,31 @@ static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data)
spin_unlock_irqrestore(&usbmisc->lock, flags);
}
+ /* For HSIC controller */
+ if (data->index == 2) {
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ val = readl(usbmisc->base + data->index * 4);
+ writel(val | MX6_BM_UTMI_ON_CLOCK,
+ usbmisc->base + data->index * 4);
+ val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+ val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON |
+ MX6SX_BM_HSIC_AUTO_RESUME;
+ writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET
+ + (data->index - 2) * 4);
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ /*
+ * Need to add delay to wait 24M OSC to be stable,
+ * it's board specific.
+ */
+ regmap_read(data->anatop, ANADIG_ANA_MISC0, &val);
+ /* 0 <= data->osc_clkgate_delay <= 7 */
+ if (data->osc_clkgate_delay > ANADIG_ANA_MISC0_CLK_DELAY(val))
+ regmap_write(data->anatop, ANADIG_ANA_MISC0_SET,
+ (data->osc_clkgate_delay) << 26);
+ }
+
return ret;
}
@@ -354,6 +443,8 @@ static const struct usbmisc_ops imx53_usbmisc_ops = {
static const struct usbmisc_ops imx6q_usbmisc_ops = {
.set_wakeup = usbmisc_imx6q_set_wakeup,
.init = usbmisc_imx6q_init,
+ .hsic_set_connect = usbmisc_imx6_hsic_set_connect,
+ .hsic_set_clk = usbmisc_imx6_hsic_set_clk,
};
static const struct usbmisc_ops vf610_usbmisc_ops = {
@@ -364,6 +455,8 @@ static const struct usbmisc_ops imx6sx_usbmisc_ops = {
.set_wakeup = usbmisc_imx6q_set_wakeup,
.init = usbmisc_imx6sx_init,
.power_lost_check = usbmisc_imx6sx_power_lost_check,
+ .hsic_set_connect = usbmisc_imx6_hsic_set_connect,
+ .hsic_set_clk = usbmisc_imx6_hsic_set_clk,
};
int imx_usbmisc_init(struct imx_usbmisc_data *data)
@@ -422,6 +515,34 @@ int imx_usbmisc_power_lost_check(struct imx_usbmisc_data *data)
}
EXPORT_SYMBOL_GPL(imx_usbmisc_power_lost_check);
+int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data)
+{
+ struct imx_usbmisc *usbmisc;
+
+ if (!data)
+ return 0;
+
+ usbmisc = dev_get_drvdata(data->dev);
+ if (!usbmisc->ops->hsic_set_connect)
+ return 0;
+ return usbmisc->ops->hsic_set_connect(data);
+}
+EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect);
+
+int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *data, bool on)
+{
+ struct imx_usbmisc *usbmisc;
+
+ if (!data)
+ return 0;
+
+ usbmisc = dev_get_drvdata(data->dev);
+ if (!usbmisc->ops->hsic_set_clk)
+ return 0;
+ return usbmisc->ops->hsic_set_clk(data, on);
+}
+EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_clk);
+
static const struct of_device_id usbmisc_imx_dt_ids[] = {
{
.compatible = "fsl,imx25-usbmisc",
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 7eefb513454d..d995f1e7d4ef 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -29,12 +29,15 @@ struct ci_hdrc_platform_data {
#define CI_HDRC_IMX28_WRITE_FIX BIT(5)
#define CI_HDRC_FORCE_FULLSPEED BIT(6)
#define CI_HDRC_IMX_EHCI_QUIRK BIT(7)
+#define CI_HDRC_IMX_IS_HSIC BIT(8)
enum usb_dr_mode dr_mode;
#define CI_HDRC_CONTROLLER_RESET_EVENT 0
#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
#define CI_HDRC_CONTROLLER_VBUS_EVENT 2
#define CI_HDRC_NOTIFY_RET_DEFER_EVENT 3
#define CI_HDRC_CONTROLLER_CHARGER_POST_EVENT 4
+#define CI_HDRC_IMX_HSIC_ACTIVE_EVENT 5
+#define CI_HDRC_IMX_HSIC_SUSPEND_EVENT 6
int (*notify_event)(struct ci_hdrc *ci, unsigned event);
struct regulator *reg_vbus;
bool tpl_support;