[PATCH 21/25] USB OTG Langwell: Switch to common data structure for Intel MID platform.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hao Wu <hao.wu@xxxxxxxxx>

This patch only modified Langwell OTG transceiver driver,
and it needs host/client driver related patch to work.

Main changes:
- update to use intel_mid_otg common data structure.

Signed-off-by: Hao Wu <hao.wu@xxxxxxxxx>
Signed-off-by: Alan Cox <alan@xxxxxxxxxxxxxxx>
---

 drivers/usb/otg/langwell_otg.c   | 1587 +++++++++++++++++++-------------------
 include/linux/usb/langwell_otg.h |   97 --
 2 files changed, 821 insertions(+), 863 deletions(-)


diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c
index 4378c64..c23471c 100644
--- a/drivers/usb/otg/langwell_otg.c
+++ b/drivers/usb/otg/langwell_otg.c
@@ -139,11 +139,11 @@ static struct list_head active_timers;
 static struct langwell_otg *the_transceiver;
 
 /* host/client notify transceiver when event affects HNP state */
-void langwell_update_transceiver()
+void langwell_update_transceiver(void)
 {
 	struct langwell_otg *lnw = the_transceiver;
 
-	dev_dbg(&lnw->pdev->dev, "transceiver is updated\n");
+	dev_dbg(lnw->dev, "transceiver is updated\n");
 
 	if (!lnw->qwork)
 		return ;
@@ -175,137 +175,138 @@ static int langwell_otg_set_power(struct otg_transceiver *otg,
 }
 
 /* A-device drives vbus, controlled through PMIC CHRGCNTL register*/
-static void langwell_otg_drv_vbus(int on)
+static int langwell_otg_set_vbus(struct otg_transceiver *otg, bool enabled)
 {
 	struct langwell_otg		*lnw = the_transceiver;
 	u8 r;
 
-	dev_dbg(&lnw->pdev->dev, "%s <--- %s\n", __func__, on ? "on" : "off");
+	dev_dbg(lnw->dev, "%s <--- %s\n", __func__, enabled ? "on" : "off");
 
 	/* FIXME: surely we should cache this on the first read. If not use
 	   readv to avoid two transactions */
 	if (intel_scu_ipc_ioread8(0x00, &r) < 0) {
-		dev_dbg(&lnw->pdev->dev, "Failed to read PMIC register 0xD2");
-		return;
+		dev_dbg(lnw->dev, "Failed to read PMIC register 0xD2");
+		return -EBUSY;
 	}
 	if ((r & 0x03) != 0x02) {
-		dev_dbg(&lnw->pdev->dev, "not NEC PMIC attached\n");
-		return;
+		dev_dbg(lnw->dev, "not NEC PMIC attached\n");
+		return -EBUSY;
 	}
 
 	if (intel_scu_ipc_ioread8(0x20, &r) < 0) {
-		dev_dbg(&lnw->pdev->dev, "Failed to read PMIC register 0xD2");
-		return;
+		dev_dbg(lnw->dev, "Failed to read PMIC register 0xD2");
+		return -EBUSY;
 	}
 
 	if ((r & 0x20) == 0) {
-		dev_dbg(&lnw->pdev->dev, "no battery attached\n");
-		return;
+		dev_dbg(lnw->dev, "no battery attached\n");
+		return -EBUSY;
 	}
 
 	/* Workaround for battery attachment issue */
 	if (r == 0x34) {
-		dev_dbg(&lnw->pdev->dev, "no battery attached on SH\n");
-		return;
+		dev_dbg(lnw->dev, "no battery attached on SH\n");
+		return -EBUSY;
 	}
 
-	dev_dbg(&lnw->pdev->dev, "battery attached. 2 reg = %x\n", r);
+	dev_dbg(lnw->dev, "battery attached. 2 reg = %x\n", r);
 
 	/* workaround: FW detect writing 0x20/0xc0 to d4 event.
 	 * this is only for NEC PMIC.
 	 */
 
-	if (intel_scu_ipc_iowrite8(0xD4, on ? 0x20 : 0xC0))
-		dev_dbg(&lnw->pdev->dev, "Failed to write PMIC.\n");
+	if (intel_scu_ipc_iowrite8(0xD4, enabled ? 0x20 : 0xC0))
+		dev_dbg(lnw->dev, "Failed to write PMIC.\n");
+
+	dev_dbg(lnw->dev, "%s --->\n", __func__);
 
-	dev_dbg(&lnw->pdev->dev, "%s --->\n", __func__);
+	return 0;
 }
 
 /* charge vbus or discharge vbus through a resistor to ground */
 static void langwell_otg_chrg_vbus(int on)
 {
-
+	struct langwell_otg	*lnw = the_transceiver;
 	u32	val;
 
-	val = readl(the_transceiver->regs + CI_OTGSC);
+	val = readl(lnw->iotg.base + CI_OTGSC);
 
 	if (on)
 		writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC,
-				the_transceiver->regs + CI_OTGSC);
+				lnw->iotg.base + CI_OTGSC);
 	else
 		writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD,
-				the_transceiver->regs + CI_OTGSC);
-
+				lnw->iotg.base + CI_OTGSC);
 }
 
 /* Start SRP */
 static int langwell_otg_start_srp(struct otg_transceiver *otg)
 {
-	struct langwell_otg	*lnw = the_transceiver;
-	u32	val;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	u32				val;
 
-	dev_dbg(&lnw->pdev->dev, "%s --->\n", __func__);
+	dev_dbg(lnw->dev, "%s --->\n", __func__);
 
-	val = readl(lnw->regs + CI_OTGSC);
+	val = readl(iotg->base + CI_OTGSC);
 
-	writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP, lnw->regs + CI_OTGSC);
+	writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP,
+				iotg->base + CI_OTGSC);
 
 	/* Check if the data plus is finished or not */
 	msleep(8);
-	val = readl(lnw->regs + CI_OTGSC);
+	val = readl(iotg->base + CI_OTGSC);
 	if (val & (OTGSC_HADP | OTGSC_DP))
-		dev_dbg(&lnw->pdev->dev, "DataLine SRP Error\n");
+		dev_dbg(lnw->dev, "DataLine SRP Error\n");
 
 	/* Disable interrupt - b_sess_vld */
-	val = readl(lnw->regs + CI_OTGSC);
+	val = readl(iotg->base + CI_OTGSC);
 	val &= (~(OTGSC_BSVIE | OTGSC_BSEIE));
-	writel(val, lnw->regs + CI_OTGSC);
+	writel(val, iotg->base + CI_OTGSC);
 
 	/* Start VBus SRP, drive vbus to generate VBus pulse */
-	langwell_otg_drv_vbus(1);
+	iotg->otg.set_vbus(&iotg->otg, true);
 	msleep(15);
-	langwell_otg_drv_vbus(0);
+	iotg->otg.set_vbus(&iotg->otg, false);
 
 	/* Enable interrupt - b_sess_vld*/
-	val = readl(lnw->regs + CI_OTGSC);
-	dev_dbg(&lnw->pdev->dev, "After VBUS pulse OTGSC = %x\n", val);
+	val = readl(iotg->base + CI_OTGSC);
+	dev_dbg(lnw->dev, "after VBUS pulse otgsc = %x\n", val);
+
 	val |= (OTGSC_BSVIE | OTGSC_BSEIE);
-	writel(val, lnw->regs + CI_OTGSC);
+	writel(val, iotg->base + CI_OTGSC);
 
 	/* If Vbus is valid, then update the hsm */
 	if (val & OTGSC_BSV) {
-		dev_dbg(&lnw->pdev->dev, "no b_sess_vld interrupt\n");
+		dev_dbg(lnw->dev, "no b_sess_vld interrupt\n");
 
-		lnw->hsm.b_sess_vld = 1;
+		lnw->iotg.hsm.b_sess_vld = 1;
 		langwell_update_transceiver();
 	}
 
-	dev_dbg(&lnw->pdev->dev, "%s <---\n", __func__);
+	dev_dbg(lnw->dev, "%s <---\n", __func__);
 	return 0;
 }
 
-
 /* stop SOF via bus_suspend */
 static void langwell_otg_loc_sof(int on)
 {
 	struct langwell_otg	*lnw = the_transceiver;
-	struct usb_hcd	*hcd;
-	int		err;
+	struct usb_hcd		*hcd;
+	int			err;
 
-	dev_dbg(&lnw->pdev->dev,
-			"%s ---> %s\n", __func__, on ? "suspend" : "resume");
+	dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "suspend" : "resume");
 
-	hcd = bus_to_hcd(lnw->otg.host);
+	hcd = bus_to_hcd(lnw->iotg.otg.host);
 	if (on)
 		err = hcd->driver->bus_resume(hcd);
 	else
 		err = hcd->driver->bus_suspend(hcd);
 
 	if (err)
-		dev_dbg(&lnw->pdev->dev,
-			"Fail to resume/suspend USB bus - %d\n", err);
+		dev_dbg(lnw->dev, "Fail to resume/suspend USB bus - %d\n", err);
 
-	dev_dbg(&lnw->pdev->dev, "%s <---\n", __func__);
+	dev_dbg(lnw->dev, "%s <---\n", __func__);
 }
 
 static int langwell_otg_check_otgsc(void)
@@ -313,66 +314,67 @@ static int langwell_otg_check_otgsc(void)
 	struct langwell_otg		*lnw = the_transceiver;
 	u32				otgsc, usbcfg;
 
-	dev_dbg(&lnw->pdev->dev, "check sync OTGSC and USBCFG registers\n");
+	dev_dbg(lnw->dev, "check sync OTGSC and USBCFG registers\n");
 
-	otgsc = readl(lnw->regs + CI_OTGSC);
+	otgsc = readl(lnw->iotg.base + CI_OTGSC);
 	usbcfg = readl(lnw->usbcfg);
 
-	dev_dbg(&lnw->pdev->dev, "OTGSC = %08x, USBCFG = %08x\n",
+	dev_dbg(lnw->dev, "OTGSC = %08x, USBCFG = %08x\n",
 					otgsc, usbcfg);
-	dev_dbg(&lnw->pdev->dev, "OTGSC_AVV = %d\n", !!(otgsc & OTGSC_AVV));
-	dev_dbg(&lnw->pdev->dev, "USBCFG.VBUSVAL = %d\n",
+	dev_dbg(lnw->dev, "OTGSC_AVV = %d\n", !!(otgsc & OTGSC_AVV));
+	dev_dbg(lnw->dev, "USBCFG.VBUSVAL = %d\n",
 					!!(usbcfg & USBCFG_VBUSVAL));
-	dev_dbg(&lnw->pdev->dev, "OTGSC_ASV = %d\n", !!(otgsc & OTGSC_ASV));
-	dev_dbg(&lnw->pdev->dev, "USBCFG.AVALID = %d\n",
+	dev_dbg(lnw->dev, "OTGSC_ASV = %d\n", !!(otgsc & OTGSC_ASV));
+	dev_dbg(lnw->dev, "USBCFG.AVALID = %d\n",
 					!!(usbcfg & USBCFG_AVALID));
-	dev_dbg(&lnw->pdev->dev, "OTGSC_BSV = %d\n", !!(otgsc & OTGSC_BSV));
-	dev_dbg(&lnw->pdev->dev, "USBCFG.BVALID = %d\n",
+	dev_dbg(lnw->dev, "OTGSC_BSV = %d\n", !!(otgsc & OTGSC_BSV));
+	dev_dbg(lnw->dev, "USBCFG.BVALID = %d\n",
 					!!(usbcfg & USBCFG_BVALID));
-	dev_dbg(&lnw->pdev->dev, "OTGSC_BSE = %d\n", !!(otgsc & OTGSC_BSE));
-	dev_dbg(&lnw->pdev->dev, "USBCFG.SESEND = %d\n",
+	dev_dbg(lnw->dev, "OTGSC_BSE = %d\n", !!(otgsc & OTGSC_BSE));
+	dev_dbg(lnw->dev, "USBCFG.SESEND = %d\n",
 					!!(usbcfg & USBCFG_SESEND));
 
 	/* Check USBCFG VBusValid/AValid/BValid/SessEnd */
 	if (!!(otgsc & OTGSC_AVV) ^ !!(usbcfg & USBCFG_VBUSVAL)) {
-		dev_dbg(&lnw->pdev->dev, "OTGSC.AVV != USBCFG.VBUSVAL\n");
+		dev_dbg(lnw->dev, "OTGSC.AVV != USBCFG.VBUSVAL\n");
 		goto err;
 	}
 	if (!!(otgsc & OTGSC_ASV) ^ !!(usbcfg & USBCFG_AVALID)) {
-		dev_dbg(&lnw->pdev->dev, "OTGSC.ASV != USBCFG.AVALID\n");
+		dev_dbg(lnw->dev, "OTGSC.ASV != USBCFG.AVALID\n");
 		goto err;
 	}
 	if (!!(otgsc & OTGSC_BSV) ^ !!(usbcfg & USBCFG_BVALID)) {
-		dev_dbg(&lnw->pdev->dev, "OTGSC.BSV != USBCFG.BVALID\n");
+		dev_dbg(lnw->dev, "OTGSC.BSV != USBCFG.BVALID\n");
 		goto err;
 	}
 	if (!!(otgsc & OTGSC_BSE) ^ !!(usbcfg & USBCFG_SESEND)) {
-		dev_dbg(&lnw->pdev->dev, "OTGSC.BSE != USBCFG.SESSEN\n");
+		dev_dbg(lnw->dev, "OTGSC.BSE != USBCFG.SESSEN\n");
 		goto err;
 	}
 
-	dev_dbg(&lnw->pdev->dev, "OTGSC and USBCFG are synced\n");
+	dev_dbg(lnw->dev, "OTGSC and USBCFG are synced\n");
 
 	return 0;
 
 err:
-	dev_warn(&lnw->pdev->dev, "OTGSC isn't equal to USBCFG\n");
+	dev_warn(lnw->dev, "OTGSC isn't equal to USBCFG\n");
 	return -EPIPE;
 }
 
 
 static void langwell_otg_phy_low_power(int on)
 {
-	struct langwell_otg	*lnw = the_transceiver;
-	u8			val, phcd;
-	int			retval;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	u8				val, phcd;
+	int				retval;
 
-	dev_dbg(&lnw->pdev->dev, "%s ---> %s mode\n",
+	dev_dbg(lnw->dev, "%s ---> %s mode\n",
 			__func__, on ? "Low power" : "Normal");
 
 	phcd = 0x40;
 
-	val = readb(lnw->regs + CI_HOSTPC1 + 2);
+	val = readb(iotg->base + CI_HOSTPC1 + 2);
 
 	if (on) {
 		/* Due to hardware issue, after set PHCD, sync will failed
@@ -381,14 +383,15 @@ static void langwell_otg_phy_low_power(int on)
 		 * not touch PHCD bit */
 		retval = langwell_otg_check_otgsc();
 		if (retval) {
-			dev_dbg(&lnw->pdev->dev, "Skip PHCD programming..\n");
+			dev_dbg(lnw->dev, "Skip PHCD programming..\n");
 			return ;
 		}
-		writeb(val | phcd, lnw->regs + CI_HOSTPC1 + 2);
+
+		writeb(val | phcd, iotg->base + CI_HOSTPC1 + 2);
 	} else
-		writeb(val & ~phcd, lnw->regs + CI_HOSTPC1 + 2);
+		writeb(val & ~phcd, iotg->base + CI_HOSTPC1 + 2);
 
-	dev_dbg(&lnw->pdev->dev, "%s <--- done\n", __func__);
+	dev_dbg(lnw->dev, "%s <--- done\n", __func__);
 }
 
 /* After drv vbus, add 2 ms delay to set PHCD */
@@ -396,7 +399,7 @@ static void langwell_otg_phy_low_power_wait(int on)
 {
 	struct langwell_otg	*lnw = the_transceiver;
 
-	dev_dbg(&lnw->pdev->dev, "add 2ms delay before programing PHCD\n");
+	dev_dbg(lnw->dev, "add 2ms delay before programing PHCD\n");
 
 	mdelay(2);
 	langwell_otg_phy_low_power(on);
@@ -405,58 +408,64 @@ static void langwell_otg_phy_low_power_wait(int on)
 /* Enable/Disable OTG interrupt */
 static void langwell_otg_intr(int on)
 {
-	struct langwell_otg	*lnw = the_transceiver;
-	u32 val;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	u32				val;
 
-	dev_dbg(&lnw->pdev->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
+	dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
 
-	val = readl(lnw->regs + CI_OTGSC);
+	val = readl(iotg->base + CI_OTGSC);
+
+	/* OTGSC_INT_MASK doesn't contains 1msInt */
 	if (on) {
 		val = val | (OTGSC_INT_MASK);
-		writel(val, lnw->regs + CI_OTGSC);
+		writel(val, iotg->base + CI_OTGSC);
 	} else {
 		val = val & ~(OTGSC_INT_MASK);
-		writel(val, lnw->regs + CI_OTGSC);
+		writel(val, iotg->base + CI_OTGSC);
 	}
-	dev_dbg(&lnw->pdev->dev, "%s <---\n", __func__);
+
+	dev_dbg(lnw->dev, "%s <---\n", __func__);
 }
 
 /* set HAAR: Hardware Assist Auto-Reset */
 static void langwell_otg_HAAR(int on)
 {
-	struct langwell_otg	*lnw = the_transceiver;
-	u32	val;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	u32				val;
 
-	dev_dbg(&lnw->pdev->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
+	dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
 
-	val = readl(lnw->regs + CI_OTGSC);
+	val = readl(iotg->base + CI_OTGSC);
 	if (on)
 		writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR,
-				lnw->regs + CI_OTGSC);
+					iotg->base + CI_OTGSC);
 	else
 		writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR,
-				lnw->regs + CI_OTGSC);
+					iotg->base + CI_OTGSC);
 
-	dev_dbg(&lnw->pdev->dev, "%s <---\n", __func__);
+	dev_dbg(lnw->dev, "%s <---\n", __func__);
 }
 
 /* set HABA: Hardware Assist B-Disconnect to A-Connect */
 static void langwell_otg_HABA(int on)
 {
-	struct langwell_otg	*lnw = the_transceiver;
-	u32	val;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	u32				val;
 
-	dev_dbg(&lnw->pdev->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
+	dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
 
-	val = readl(lnw->regs + CI_OTGSC);
+	val = readl(iotg->base + CI_OTGSC);
 	if (on)
 		writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA,
-				lnw->regs + CI_OTGSC);
+					iotg->base + CI_OTGSC);
 	else
 		writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA,
-				lnw->regs + CI_OTGSC);
+					iotg->base + CI_OTGSC);
 
-	dev_dbg(&lnw->pdev->dev, "%s <---\n", __func__);
+	dev_dbg(lnw->dev, "%s <---\n", __func__);
 }
 
 static int langwell_otg_check_se0_srp(int on)
@@ -465,17 +474,17 @@ static int langwell_otg_check_se0_srp(int on)
 	int			delay_time = TB_SE0_SRP * 10;
 	u32			val;
 
-	dev_dbg(&lnw->pdev->dev, "%s --->\n", __func__);
+	dev_dbg(lnw->dev, "%s --->\n", __func__);
 
 	do {
 		udelay(100);
 		if (!delay_time--)
 			break;
-		val = readl(lnw->regs + CI_PORTSC1);
+		val = readl(lnw->iotg.base + CI_PORTSC1);
 		val &= PORTSC_LS;
 	} while (!val);
 
-	dev_dbg(&lnw->pdev->dev, "%s <---\n", __func__);
+	dev_dbg(lnw->dev, "%s <---\n", __func__);
 	return val;
 }
 
@@ -494,15 +503,15 @@ void langwell_otg_nsf_msg(unsigned long indicator)
 	case 4:
 	case 6:
 	case 7:
-		dev_warn(&lnw->pdev->dev,
+		dev_warn(lnw->dev,
 			"OTG:NSF-%lu - deivce not responding\n", indicator);
 		break;
 	case 3:
-		dev_warn(&lnw->pdev->dev,
+		dev_warn(lnw->dev,
 			"OTG:NSF-%lu - deivce not supported\n", indicator);
 		break;
 	default:
-		dev_warn(&lnw->pdev->dev, "Do not have this kind of NSF\n");
+		dev_warn(lnw->dev, "Do not have this kind of NSF\n");
 		break;
 	}
 }
@@ -547,7 +556,7 @@ static void langwell_otg_timer_fn(unsigned long indicator)
 
 	*(int *)indicator = 1;
 
-	dev_dbg(&lnw->pdev->dev, "kernel timer - timeout\n");
+	dev_dbg(lnw->dev, "kernel timer - timeout\n");
 
 	langwell_update_transceiver();
 }
@@ -555,48 +564,49 @@ static void langwell_otg_timer_fn(unsigned long indicator)
 /* kernel timer used instead of HW based interrupt */
 static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers)
 {
-	struct langwell_otg	*lnw = the_transceiver;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
 	unsigned long		j = jiffies;
 	unsigned long		data, time;
 
 	switch (timers) {
 	case TA_WAIT_VRISE_TMR:
-		lnw->hsm.a_wait_vrise_tmout = 0;
-		data = (unsigned long)&lnw->hsm.a_wait_vrise_tmout;
+		iotg->hsm.a_wait_vrise_tmout = 0;
+		data = (unsigned long)&iotg->hsm.a_wait_vrise_tmout;
 		time = TA_WAIT_VRISE;
 		break;
 	case TA_WAIT_BCON_TMR:
-		lnw->hsm.a_wait_bcon_tmout = 0;
-		data = (unsigned long)&lnw->hsm.a_wait_bcon_tmout;
+		iotg->hsm.a_wait_bcon_tmout = 0;
+		data = (unsigned long)&iotg->hsm.a_wait_bcon_tmout;
 		time = TA_WAIT_BCON;
 		break;
 	case TA_AIDL_BDIS_TMR:
-		lnw->hsm.a_aidl_bdis_tmout = 0;
-		data = (unsigned long)&lnw->hsm.a_aidl_bdis_tmout;
+		iotg->hsm.a_aidl_bdis_tmout = 0;
+		data = (unsigned long)&iotg->hsm.a_aidl_bdis_tmout;
 		time = TA_AIDL_BDIS;
 		break;
 	case TB_ASE0_BRST_TMR:
-		lnw->hsm.b_ase0_brst_tmout = 0;
-		data = (unsigned long)&lnw->hsm.b_ase0_brst_tmout;
+		iotg->hsm.b_ase0_brst_tmout = 0;
+		data = (unsigned long)&iotg->hsm.b_ase0_brst_tmout;
 		time = TB_ASE0_BRST;
 		break;
 	case TB_SRP_INIT_TMR:
-		lnw->hsm.b_srp_init_tmout = 0;
-		data = (unsigned long)&lnw->hsm.b_srp_init_tmout;
+		iotg->hsm.b_srp_init_tmout = 0;
+		data = (unsigned long)&iotg->hsm.b_srp_init_tmout;
 		time = TB_SRP_INIT;
 		break;
 	case TB_SRP_FAIL_TMR:
-		lnw->hsm.b_srp_fail_tmout = 0;
-		data = (unsigned long)&lnw->hsm.b_srp_fail_tmout;
+		iotg->hsm.b_srp_fail_tmout = 0;
+		data = (unsigned long)&iotg->hsm.b_srp_fail_tmout;
 		time = TB_SRP_FAIL;
 		break;
 	case TB_BUS_SUSPEND_TMR:
-		lnw->hsm.b_bus_suspend_tmout = 0;
-		data = (unsigned long)&lnw->hsm.b_bus_suspend_tmout;
+		iotg->hsm.b_bus_suspend_tmout = 0;
+		data = (unsigned long)&iotg->hsm.b_bus_suspend_tmout;
 		time = TB_BUS_SUSPEND;
 		break;
 	default:
-		dev_dbg(&lnw->pdev->dev, "unkown timer, cannot enable it\n");
+		dev_dbg(lnw->dev, "unkown timer, cannot enable it\n");
 		return;
 	}
 
@@ -606,7 +616,7 @@ static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers)
 
 	add_timer(&lnw->hsm_timer);
 
-	dev_dbg(&lnw->pdev->dev, "add timer successfully\n");
+	dev_dbg(lnw->dev, "add timer successfully\n");
 }
 
 /* Add timer to timer list */
@@ -614,6 +624,7 @@ static void langwell_otg_add_timer(void *gtimer)
 {
 	struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
 	struct langwell_otg_timer *tmp_timer;
+	struct intel_mid_otg_xceiv *iotg = &the_transceiver->iotg;
 	u32	val32;
 
 	/* Check if the timer is already in the active list,
@@ -627,8 +638,8 @@ static void langwell_otg_add_timer(void *gtimer)
 	timer->count = timer->expires;
 
 	if (list_empty(&active_timers)) {
-		val32 = readl(the_transceiver->regs + CI_OTGSC);
-		writel(val32 | OTGSC_1MSE, the_transceiver->regs + CI_OTGSC);
+		val32 = readl(iotg->base + CI_OTGSC);
+		writel(val32 | OTGSC_1MSE, iotg->base + CI_OTGSC);
 	}
 
 	list_add_tail(&timer->list, &active_timers);
@@ -637,6 +648,7 @@ static void langwell_otg_add_timer(void *gtimer)
 /* Remove timer from the timer list; clear timeout status */
 static void langwell_otg_del_timer(void *gtimer)
 {
+	struct langwell_otg *lnw = the_transceiver;
 	struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
 	struct langwell_otg_timer *tmp_timer, *del_tmp;
 	u32 val32;
@@ -646,8 +658,8 @@ static void langwell_otg_del_timer(void *gtimer)
 			list_del(&timer->list);
 
 	if (list_empty(&active_timers)) {
-		val32 = readl(the_transceiver->regs + CI_OTGSC);
-		writel(val32 & ~OTGSC_1MSE, the_transceiver->regs + CI_OTGSC);
+		val32 = readl(lnw->iotg.base + CI_OTGSC);
+		writel(val32 & ~OTGSC_1MSE, lnw->iotg.base + CI_OTGSC);
 	}
 }
 
@@ -669,7 +681,7 @@ static int langwell_otg_tick_timer(u32 *int_sts)
 	}
 
 	if (list_empty(&active_timers)) {
-		dev_dbg(&lnw->pdev->dev, "tick timer: disable 1ms int\n");
+		dev_dbg(lnw->dev, "tick timer: disable 1ms int\n");
 		*int_sts = *int_sts & ~OTGSC_1MSE;
 	}
 	return expired;
@@ -681,105 +693,108 @@ static void reset_otg(void)
 	int			delay_time = 1000;
 	u32			val;
 
-	dev_dbg(&lnw->pdev->dev, "reseting OTG controller ...\n");
-	val = readl(lnw->regs + CI_USBCMD);
-	writel(val | USBCMD_RST, lnw->regs + CI_USBCMD);
+	dev_dbg(lnw->dev, "reseting OTG controller ...\n");
+	val = readl(lnw->iotg.base + CI_USBCMD);
+	writel(val | USBCMD_RST, lnw->iotg.base + CI_USBCMD);
 	do {
 		udelay(100);
 		if (!delay_time--)
-			dev_dbg(&lnw->pdev->dev, "reset timeout\n");
-		val = readl(lnw->regs + CI_USBCMD);
+			dev_dbg(lnw->dev, "reset timeout\n");
+		val = readl(lnw->iotg.base + CI_USBCMD);
 		val &= USBCMD_RST;
 	} while (val != 0);
-	dev_dbg(&lnw->pdev->dev, "reset done.\n");
+	dev_dbg(lnw->dev, "reset done.\n");
 }
 
 static void set_host_mode(void)
 {
-	u32	val;
+	struct langwell_otg	*lnw = the_transceiver;
+	u32			val;
 
 	reset_otg();
-	val = readl(the_transceiver->regs + CI_USBMODE);
+	val = readl(lnw->iotg.base + CI_USBMODE);
 	val = (val & (~USBMODE_CM)) | USBMODE_HOST;
-	writel(val, the_transceiver->regs + CI_USBMODE);
+	writel(val, lnw->iotg.base + CI_USBMODE);
 }
 
 static void set_client_mode(void)
 {
-	u32	val;
+	struct langwell_otg	*lnw = the_transceiver;
+	u32			val;
 
 	reset_otg();
-	val = readl(the_transceiver->regs + CI_USBMODE);
+	val = readl(lnw->iotg.base + CI_USBMODE);
 	val = (val & (~USBMODE_CM)) | USBMODE_DEVICE;
-	writel(val, the_transceiver->regs + CI_USBMODE);
+	writel(val, lnw->iotg.base + CI_USBMODE);
 }
 
 static void init_hsm(void)
 {
-	struct langwell_otg	*lnw = the_transceiver;
-	u32			val32;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	u32				val32;
 
 	/* read OTGSC after reset */
-	val32 = readl(lnw->regs + CI_OTGSC);
-
-	dev_dbg(&lnw->pdev->dev, "%s: OTGSC value = 0x%x\n", __func__, val32);
+	val32 = readl(lnw->iotg.base + CI_OTGSC);
+	dev_dbg(lnw->dev, "%s: OTGSC init value = 0x%x\n", __func__, val32);
 
 	/* set init state */
 	if (val32 & OTGSC_ID) {
-		lnw->hsm.id = 1;
-		lnw->otg.default_a = 0;
+		iotg->hsm.id = 1;
+		iotg->otg.default_a = 0;
 		set_client_mode();
-		lnw->otg.state = OTG_STATE_B_IDLE;
-		langwell_otg_drv_vbus(0);
+		iotg->otg.state = OTG_STATE_B_IDLE;
 	} else {
-		lnw->hsm.id = 0;
-		lnw->otg.default_a = 1;
+		iotg->hsm.id = 0;
+		iotg->otg.default_a = 1;
 		set_host_mode();
-		lnw->otg.state = OTG_STATE_A_IDLE;
+		iotg->otg.state = OTG_STATE_A_IDLE;
 	}
 
 	/* set session indicator */
 	if (val32 & OTGSC_BSE)
-		lnw->hsm.b_sess_end = 1;
+		iotg->hsm.b_sess_end = 1;
 	if (val32 & OTGSC_BSV)
-		lnw->hsm.b_sess_vld = 1;
+		iotg->hsm.b_sess_vld = 1;
 	if (val32 & OTGSC_ASV)
-		lnw->hsm.a_sess_vld = 1;
+		iotg->hsm.a_sess_vld = 1;
 	if (val32 & OTGSC_AVV)
-		lnw->hsm.a_vbus_vld = 1;
+		iotg->hsm.a_vbus_vld = 1;
 
 	/* defautly power the bus */
-	lnw->hsm.a_bus_req = 1;
-	lnw->hsm.a_bus_drop = 0;
+	iotg->hsm.a_bus_req = 1;
+	iotg->hsm.a_bus_drop = 0;
 	/* defautly don't request bus as B device */
-	lnw->hsm.b_bus_req = 0;
+	iotg->hsm.b_bus_req = 0;
 	/* no system error */
-	lnw->hsm.a_clr_err = 0;
+	iotg->hsm.a_clr_err = 0;
 
 	langwell_otg_phy_low_power_wait(1);
 }
 
 static void update_hsm(void)
 {
-	struct langwell_otg	*lnw = the_transceiver;
-	u32			val32;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	u32				val32;
 
 	/* read OTGSC */
-	val32 = readl(lnw->regs + CI_OTGSC);
-	dev_dbg(&lnw->pdev->dev, "%s: OTGSC value = 0x%x\n", __func__, val32);
-
-	lnw->hsm.id = !!(val32 & OTGSC_ID);
-	lnw->hsm.b_sess_end = !!(val32 & OTGSC_BSE);
-	lnw->hsm.b_sess_vld = !!(val32 & OTGSC_BSV);
-	lnw->hsm.a_sess_vld = !!(val32 & OTGSC_ASV);
-	lnw->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV);
+	val32 = readl(lnw->iotg.base + CI_OTGSC);
+	dev_dbg(lnw->dev, "%s: OTGSC value = 0x%x\n", __func__, val32);
+
+	iotg->hsm.id = !!(val32 & OTGSC_ID);
+	iotg->hsm.b_sess_end = !!(val32 & OTGSC_BSE);
+	iotg->hsm.b_sess_vld = !!(val32 & OTGSC_BSV);
+	iotg->hsm.a_sess_vld = !!(val32 & OTGSC_ASV);
+	iotg->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV);
 }
 
 static irqreturn_t otg_dummy_irq(int irq, void *_dev)
 {
-	void __iomem	*reg_base = _dev;
-	u32	val;
-	u32	int_mask = 0;
+	struct langwell_otg	*lnw = the_transceiver;
+	void __iomem		*reg_base = _dev;
+	u32			val;
+	u32			int_mask = 0;
 
 	val = readl(reg_base + CI_USBMODE);
 	if ((val & USBMODE_CM) != USBMODE_DEVICE)
@@ -794,13 +809,14 @@ static irqreturn_t otg_dummy_irq(int irq, void *_dev)
 	/* clear hsm.b_conn here since host driver can't detect it
 	*  otg_dummy_irq called means B-disconnect happened.
 	*/
-	if (the_transceiver->hsm.b_conn) {
-		the_transceiver->hsm.b_conn = 0;
-		if (spin_trylock(&the_transceiver->wq_lock)) {
+	if (lnw->iotg.hsm.b_conn) {
+		lnw->iotg.hsm.b_conn = 0;
+		if (spin_trylock(&lnw->wq_lock)) {
 			langwell_update_transceiver();
-			spin_unlock(&the_transceiver->wq_lock);
+			spin_unlock(&lnw->wq_lock);
 		}
 	}
+
 	/* Clear interrupts */
 	writel(int_mask, reg_base + CI_USBSTS);
 	return IRQ_HANDLED;
@@ -808,56 +824,52 @@ static irqreturn_t otg_dummy_irq(int irq, void *_dev)
 
 static irqreturn_t otg_irq(int irq, void *_dev)
 {
-	struct	langwell_otg *lnw = _dev;
-	u32	int_sts, int_en;
-	u32	int_mask = 0;
-	int	flag = 0;
+	struct langwell_otg		*lnw = _dev;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	u32				int_sts, int_en;
+	u32				int_mask = 0;
+	int				flag = 0;
 
-	int_sts = readl(lnw->regs + CI_OTGSC);
+	int_sts = readl(lnw->iotg.base + CI_OTGSC);
 	int_en = (int_sts & OTGSC_INTEN_MASK) >> 8;
 	int_mask = int_sts & int_en;
 	if (int_mask == 0)
 		return IRQ_NONE;
 
 	if (int_mask & OTGSC_IDIS) {
-		dev_dbg(&lnw->pdev->dev, "%s: id change int\n", __func__);
-		lnw->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0;
-		dev_dbg(&lnw->pdev->dev, "id = %d\n", lnw->hsm.id);
+		dev_dbg(lnw->dev, "%s: id change int\n", __func__);
+		iotg->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0;
+		dev_dbg(lnw->dev, "id = %d\n", iotg->hsm.id);
 		flag = 1;
 	}
 	if (int_mask & OTGSC_DPIS) {
-		dev_dbg(&lnw->pdev->dev, "%s: data pulse int\n", __func__);
-		lnw->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0;
-		dev_dbg(&lnw->pdev->dev,
-				"data pulse = %d\n", lnw->hsm.a_srp_det);
+		dev_dbg(lnw->dev, "%s: data pulse int\n", __func__);
+		iotg->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0;
+		dev_dbg(lnw->dev, "data pulse = %d\n", iotg->hsm.a_srp_det);
 		flag = 1;
 	}
 	if (int_mask & OTGSC_BSEIS) {
-		dev_dbg(&lnw->pdev->dev, "%s: b session end int\n", __func__);
-		lnw->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0;
-		dev_dbg(&lnw->pdev->dev,
-				"b_sess_end = %d\n", lnw->hsm.b_sess_end);
+		dev_dbg(lnw->dev, "%s: b session end int\n", __func__);
+		iotg->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0;
+		dev_dbg(lnw->dev, "b_sess_end = %d\n", iotg->hsm.b_sess_end);
 		flag = 1;
 	}
 	if (int_mask & OTGSC_BSVIS) {
-		dev_dbg(&lnw->pdev->dev, "%s: b session valid int\n", __func__);
-		lnw->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0;
-		dev_dbg(&lnw->pdev->dev,
-				"b_sess_vld = %d\n", lnw->hsm.b_sess_end);
+		dev_dbg(lnw->dev, "%s: b session valid int\n", __func__);
+		iotg->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0;
+		dev_dbg(lnw->dev, "b_sess_vld = %d\n", iotg->hsm.b_sess_end);
 		flag = 1;
 	}
 	if (int_mask & OTGSC_ASVIS) {
-		dev_dbg(&lnw->pdev->dev, "%s: a session valid int\n", __func__);
-		lnw->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0;
-		dev_dbg(&lnw->pdev->dev,
-				"a_sess_vld = %d\n", lnw->hsm.a_sess_vld);
+		dev_dbg(lnw->dev, "%s: a session valid int\n", __func__);
+		iotg->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0;
+		dev_dbg(lnw->dev, "a_sess_vld = %d\n", iotg->hsm.a_sess_vld);
 		flag = 1;
 	}
 	if (int_mask & OTGSC_AVVIS) {
-		dev_dbg(&lnw->pdev->dev, "%s: a vbus valid int\n", __func__);
-		lnw->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0;
-		dev_dbg(&lnw->pdev->dev,
-				"a_vbus_vld = %d\n", lnw->hsm.a_vbus_vld);
+		dev_dbg(lnw->dev, "%s: a vbus valid int\n", __func__);
+		iotg->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0;
+		dev_dbg(lnw->dev, "a_vbus_vld = %d\n", iotg->hsm.a_vbus_vld);
 		flag = 1;
 	}
 
@@ -867,7 +879,8 @@ static irqreturn_t otg_irq(int irq, void *_dev)
 			flag = 1;
 	}
 
-	writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask, lnw->regs + CI_OTGSC);
+	writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask,
+					lnw->iotg.base + CI_OTGSC);
 	if (flag)
 		langwell_update_transceiver();
 
@@ -876,63 +889,70 @@ static irqreturn_t otg_irq(int irq, void *_dev)
 
 static void langwell_otg_work(struct work_struct *work)
 {
-	struct langwell_otg	*lnw;
-	int			retval;
+	struct langwell_otg		*lnw;
+	struct intel_mid_otg_xceiv	*iotg;
+	int				retval;
+	struct pci_dev			*pdev;
 
 	lnw = container_of(work, struct langwell_otg, work);
+	iotg = &lnw->iotg;
+	pdev = to_pci_dev(lnw->dev);
 
-	dev_dbg(&lnw->pdev->dev, "%s: old state = %s\n", __func__,
-			state_string(lnw->otg.state));
+	dev_dbg(lnw->dev, "%s: old state = %s\n", __func__,
+			state_string(iotg->otg.state));
 
-	switch (lnw->otg.state) {
+	switch (iotg->otg.state) {
 	case OTG_STATE_UNDEFINED:
 	case OTG_STATE_B_IDLE:
-		if (!lnw->hsm.id) {
+		if (!iotg->hsm.id) {
 			langwell_otg_del_timer(b_srp_init_tmr);
 			del_timer_sync(&lnw->hsm_timer);
-			lnw->otg.default_a = 1;
-			lnw->hsm.a_srp_det = 0;
+
+			iotg->otg.default_a = 1;
+			iotg->hsm.a_srp_det = 0;
+
 			langwell_otg_chrg_vbus(0);
 			set_host_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_A_IDLE;
+
+			iotg->otg.state = OTG_STATE_A_IDLE;
 			langwell_update_transceiver();
-		} else if (lnw->hsm.b_sess_vld) {
+		} else if (iotg->hsm.b_sess_vld) {
 			langwell_otg_del_timer(b_srp_init_tmr);
 			del_timer_sync(&lnw->hsm_timer);
-			lnw->hsm.b_sess_end = 0;
-			lnw->hsm.a_bus_suspend = 0;
+			iotg->hsm.b_sess_end = 0;
+			iotg->hsm.a_bus_suspend = 0;
 			langwell_otg_chrg_vbus(0);
-			if (lnw->client_ops) {
-				lnw->client_ops->resume(lnw->pdev);
-				lnw->otg.state = OTG_STATE_B_PERIPHERAL;
+
+			if (lnw->iotg.start_peripheral) {
+				lnw->iotg.start_peripheral(&lnw->iotg);
+				iotg->otg.state = OTG_STATE_B_PERIPHERAL;
 			} else
-				dev_dbg(&lnw->pdev->dev,
-					"client driver not loaded.\n");
+				dev_dbg(lnw->dev, "client driver not loaded\n");
 
-		} else if (lnw->hsm.b_srp_init_tmout) {
-			lnw->hsm.b_srp_init_tmout = 0;
-			dev_warn(&lnw->pdev->dev, "SRP init timeout\n");
-		} else if (lnw->hsm.b_srp_fail_tmout) {
-			lnw->hsm.b_srp_fail_tmout = 0;
-			lnw->hsm.b_bus_req = 0;
+		} else if (iotg->hsm.b_srp_init_tmout) {
+			iotg->hsm.b_srp_init_tmout = 0;
+			dev_warn(lnw->dev, "SRP init timeout\n");
+		} else if (iotg->hsm.b_srp_fail_tmout) {
+			iotg->hsm.b_srp_fail_tmout = 0;
+			iotg->hsm.b_bus_req = 0;
+
+			/* No silence failure */
 			langwell_otg_nsf_msg(6);
-		} else if (lnw->hsm.b_bus_req &&
-				(lnw->hsm.b_sess_end)) {
+		} else if (iotg->hsm.b_bus_req && iotg->hsm.b_sess_end) {
 			del_timer_sync(&lnw->hsm_timer);
 			/* workaround for b_se0_srp detection */
 			retval = langwell_otg_check_se0_srp(0);
 			if (retval) {
-				lnw->hsm.b_bus_req = 0;
-				dev_dbg(&lnw->pdev->dev,
-					"LS is not SE0, try again later\n");
+				iotg->hsm.b_bus_req = 0;
+				dev_dbg(lnw->dev, "LS isn't SE0, try later\n");
 			} else {
 				/* clear the PHCD before start srp */
 				langwell_otg_phy_low_power(0);
 
 				/* Start SRP */
 				langwell_otg_add_timer(b_srp_init_tmr);
-				langwell_otg_start_srp(&lnw->otg);
+				iotg->otg.start_srp(&iotg->otg);
 				langwell_otg_del_timer(b_srp_init_tmr);
 				langwell_otg_add_ktimer(TB_SRP_FAIL_TMR);
 
@@ -942,607 +962,645 @@ static void langwell_otg_work(struct work_struct *work)
 		}
 		break;
 	case OTG_STATE_B_SRP_INIT:
-		if (!lnw->hsm.id) {
-			lnw->otg.default_a = 1;
-			lnw->hsm.a_srp_det = 0;
-			langwell_otg_drv_vbus(0);
+		if (!iotg->hsm.id) {
+			iotg->otg.default_a = 1;
+			iotg->hsm.a_srp_det = 0;
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			langwell_otg_chrg_vbus(0);
 			set_host_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_A_IDLE;
+			iotg->otg.state = OTG_STATE_A_IDLE;
 			langwell_update_transceiver();
-		} else if (lnw->hsm.b_sess_vld) {
+		} else if (iotg->hsm.b_sess_vld) {
 			langwell_otg_chrg_vbus(0);
-			if (lnw->client_ops) {
-				lnw->client_ops->resume(lnw->pdev);
-				lnw->otg.state = OTG_STATE_B_PERIPHERAL;
+			if (lnw->iotg.start_peripheral) {
+				lnw->iotg.start_peripheral(&lnw->iotg);
+				iotg->otg.state = OTG_STATE_B_PERIPHERAL;
 			} else
-				dev_dbg(&lnw->pdev->dev,
-					"client driver not loaded.\n");
+				dev_dbg(lnw->dev, "client driver not loaded\n");
 		}
 		break;
 	case OTG_STATE_B_PERIPHERAL:
-		if (!lnw->hsm.id) {
-			lnw->otg.default_a = 1;
-			lnw->hsm.a_srp_det = 0;
+		if (!iotg->hsm.id) {
+			iotg->otg.default_a = 1;
+			iotg->hsm.a_srp_det = 0;
 
 			langwell_otg_chrg_vbus(0);
 
-			if (lnw->client_ops) {
-				lnw->client_ops->suspend(lnw->pdev,
-					PMSG_FREEZE);
-			} else
-				dev_dbg(&lnw->pdev->dev,
+			if (lnw->iotg.stop_peripheral)
+				lnw->iotg.stop_peripheral(&lnw->iotg);
+			else
+				dev_dbg(lnw->dev,
 					"client driver has been removed.\n");
 
 			set_host_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_A_IDLE;
+			iotg->otg.state = OTG_STATE_A_IDLE;
 			langwell_update_transceiver();
-		} else if (!lnw->hsm.b_sess_vld) {
-			lnw->hsm.b_hnp_enable = 0;
+		} else if (!iotg->hsm.b_sess_vld) {
+			iotg->hsm.b_hnp_enable = 0;
 
-			if (lnw->client_ops) {
-				lnw->client_ops->suspend(lnw->pdev,
-					PMSG_FREEZE);
-			} else
-				dev_dbg(&lnw->pdev->dev,
+			if (lnw->iotg.stop_peripheral)
+				lnw->iotg.stop_peripheral(&lnw->iotg);
+			else
+				dev_dbg(lnw->dev,
 					"client driver has been removed.\n");
 
-			lnw->otg.state = OTG_STATE_B_IDLE;
-		} else if (lnw->hsm.b_bus_req && lnw->otg.gadget
-			&& lnw->otg.gadget->b_hnp_enable
-			&& lnw->hsm.a_bus_suspend) {
+			iotg->otg.state = OTG_STATE_B_IDLE;
+		} else if (iotg->hsm.b_bus_req && iotg->otg.gadget &&
+					iotg->otg.gadget->b_hnp_enable &&
+					iotg->hsm.a_bus_suspend) {
 
-			if (lnw->client_ops) {
-				lnw->client_ops->suspend(lnw->pdev,
-					PMSG_FREEZE);
-			} else
-				dev_dbg(&lnw->pdev->dev,
+			if (lnw->iotg.stop_peripheral)
+				lnw->iotg.stop_peripheral(&lnw->iotg);
+			else
+				dev_dbg(lnw->dev,
 					"client driver has been removed.\n");
 
 			langwell_otg_HAAR(1);
-			lnw->hsm.a_conn = 0;
+			iotg->hsm.a_conn = 0;
 
-			if (lnw->host_ops) {
-				lnw->host_ops->probe(lnw->pdev,
-					lnw->host_ops->id_table);
-				lnw->otg.state = OTG_STATE_B_WAIT_ACON;
+			if (lnw->iotg.start_host) {
+				lnw->iotg.start_host(&lnw->iotg);
+				iotg->otg.state = OTG_STATE_B_WAIT_ACON;
 			} else
-				dev_dbg(&lnw->pdev->dev,
-					"host driver not loaded.\n");
+				dev_dbg(lnw->dev,
+						"host driver not loaded.\n");
 
-			lnw->hsm.a_bus_resume = 0;
+			iotg->hsm.a_bus_resume = 0;
 			langwell_otg_add_ktimer(TB_ASE0_BRST_TMR);
 		}
 		break;
 
 	case OTG_STATE_B_WAIT_ACON:
-		if (!lnw->hsm.id) {
+		if (!iotg->hsm.id) {
 			/* delete hsm timer for b_ase0_brst_tmr */
 			del_timer_sync(&lnw->hsm_timer);
 
-			lnw->otg.default_a = 1;
-			lnw->hsm.a_srp_det = 0;
+			iotg->otg.default_a = 1;
+			iotg->hsm.a_srp_det = 0;
 
 			langwell_otg_chrg_vbus(0);
 
 			langwell_otg_HAAR(0);
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
+
 			set_host_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_A_IDLE;
+			iotg->otg.state = OTG_STATE_A_IDLE;
 			langwell_update_transceiver();
-		} else if (!lnw->hsm.b_sess_vld) {
+		} else if (!iotg->hsm.b_sess_vld) {
 			/* delete hsm timer for b_ase0_brst_tmr */
 			del_timer_sync(&lnw->hsm_timer);
 
-			lnw->hsm.b_hnp_enable = 0;
-			lnw->hsm.b_bus_req = 0;
+			iotg->hsm.b_hnp_enable = 0;
+			iotg->hsm.b_bus_req = 0;
+
 			langwell_otg_chrg_vbus(0);
 			langwell_otg_HAAR(0);
 
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
 
 			set_client_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
-		} else if (lnw->hsm.a_conn) {
+			iotg->otg.state = OTG_STATE_B_IDLE;
+		} else if (iotg->hsm.a_conn) {
 			/* delete hsm timer for b_ase0_brst_tmr */
 			del_timer_sync(&lnw->hsm_timer);
+
 			langwell_otg_HAAR(0);
-			lnw->otg.state = OTG_STATE_B_HOST;
+			iotg->otg.state = OTG_STATE_B_HOST;
 			langwell_update_transceiver();
-		} else if (lnw->hsm.a_bus_resume ||
-				lnw->hsm.b_ase0_brst_tmout) {
+		} else if (iotg->hsm.a_bus_resume ||
+				iotg->hsm.b_ase0_brst_tmout) {
 			/* delete hsm timer for b_ase0_brst_tmr */
 			del_timer_sync(&lnw->hsm_timer);
+
 			langwell_otg_HAAR(0);
 			langwell_otg_nsf_msg(7);
 
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
 
-			lnw->hsm.a_bus_suspend = 0;
-			lnw->hsm.b_bus_req = 0;
+			iotg->hsm.a_bus_suspend = 0;
+			iotg->hsm.b_bus_req = 0;
 
-			if (lnw->client_ops)
-				lnw->client_ops->resume(lnw->pdev);
+			if (lnw->iotg.start_peripheral)
+				lnw->iotg.start_peripheral(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"client driver not loaded.\n");
 
-			lnw->otg.state = OTG_STATE_B_PERIPHERAL;
+			iotg->otg.state = OTG_STATE_B_PERIPHERAL;
 		}
 		break;
 
 	case OTG_STATE_B_HOST:
-		if (!lnw->hsm.id) {
-			lnw->otg.default_a = 1;
-			lnw->hsm.a_srp_det = 0;
+		if (!iotg->hsm.id) {
+			iotg->otg.default_a = 1;
+			iotg->hsm.a_srp_det = 0;
 
 			langwell_otg_chrg_vbus(0);
 
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
+
 			set_host_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_A_IDLE;
+			iotg->otg.state = OTG_STATE_A_IDLE;
 			langwell_update_transceiver();
-		} else if (!lnw->hsm.b_sess_vld) {
-			lnw->hsm.b_hnp_enable = 0;
-			lnw->hsm.b_bus_req = 0;
+		} else if (!iotg->hsm.b_sess_vld) {
+			iotg->hsm.b_hnp_enable = 0;
+			iotg->hsm.b_bus_req = 0;
+
 			langwell_otg_chrg_vbus(0);
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
 
 			set_client_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
-		} else if ((!lnw->hsm.b_bus_req) ||
-				(!lnw->hsm.a_conn)) {
-			lnw->hsm.b_bus_req = 0;
+			iotg->otg.state = OTG_STATE_B_IDLE;
+		} else if ((!iotg->hsm.b_bus_req) ||
+				(!iotg->hsm.a_conn)) {
+			iotg->hsm.b_bus_req = 0;
 			langwell_otg_loc_sof(0);
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
 
-			lnw->hsm.a_bus_suspend = 0;
+			iotg->hsm.a_bus_suspend = 0;
 
-			if (lnw->client_ops)
-				lnw->client_ops->resume(lnw->pdev);
+			if (lnw->iotg.start_peripheral)
+				lnw->iotg.start_peripheral(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
-					"client driver not loaded.\n");
+				dev_dbg(lnw->dev,
+						"client driver not loaded.\n");
 
-			lnw->otg.state = OTG_STATE_B_PERIPHERAL;
+			iotg->otg.state = OTG_STATE_B_PERIPHERAL;
 		}
 		break;
 
 	case OTG_STATE_A_IDLE:
-		lnw->otg.default_a = 1;
-		if (lnw->hsm.id) {
-			lnw->otg.default_a = 0;
-			lnw->hsm.b_bus_req = 0;
-			lnw->hsm.vbus_srp_up = 0;
+		iotg->otg.default_a = 1;
+		if (iotg->hsm.id) {
+			iotg->otg.default_a = 0;
+			iotg->hsm.b_bus_req = 0;
+			iotg->hsm.vbus_srp_up = 0;
+
 			langwell_otg_chrg_vbus(0);
 			set_client_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
+			iotg->otg.state = OTG_STATE_B_IDLE;
 			langwell_update_transceiver();
-		} else if (!lnw->hsm.a_bus_drop &&
-			(lnw->hsm.a_srp_det || lnw->hsm.a_bus_req)) {
+		} else if (!iotg->hsm.a_bus_drop &&
+			(iotg->hsm.a_srp_det || iotg->hsm.a_bus_req)) {
 			langwell_otg_phy_low_power(0);
-			langwell_otg_drv_vbus(1);
-			lnw->hsm.vbus_srp_up = 0;
-			lnw->hsm.a_wait_vrise_tmout = 0;
+
+			/* Turn on VBus */
+			iotg->otg.set_vbus(&iotg->otg, true);
+
+			iotg->hsm.vbus_srp_up = 0;
+			iotg->hsm.a_wait_vrise_tmout = 0;
 			langwell_otg_add_timer(a_wait_vrise_tmr);
-			lnw->otg.state = OTG_STATE_A_WAIT_VRISE;
+			iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
 			langwell_update_transceiver();
-		} else if (!lnw->hsm.a_bus_drop && lnw->hsm.a_sess_vld) {
-			lnw->hsm.vbus_srp_up = 1;
-		} else if (!lnw->hsm.a_sess_vld && lnw->hsm.vbus_srp_up) {
+		} else if (!iotg->hsm.a_bus_drop && iotg->hsm.a_sess_vld) {
+			iotg->hsm.vbus_srp_up = 1;
+		} else if (!iotg->hsm.a_sess_vld && iotg->hsm.vbus_srp_up) {
 			msleep(10);
 			langwell_otg_phy_low_power(0);
-			langwell_otg_drv_vbus(1);
-			lnw->hsm.a_srp_det = 1;
-			lnw->hsm.vbus_srp_up = 0;
-			lnw->hsm.a_wait_vrise_tmout = 0;
+
+			/* Turn on VBus */
+			iotg->otg.set_vbus(&iotg->otg, true);
+			iotg->hsm.a_srp_det = 1;
+			iotg->hsm.vbus_srp_up = 0;
+			iotg->hsm.a_wait_vrise_tmout = 0;
 			langwell_otg_add_timer(a_wait_vrise_tmr);
-			lnw->otg.state = OTG_STATE_A_WAIT_VRISE;
+			iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
 			langwell_update_transceiver();
-		} else if (!lnw->hsm.a_sess_vld &&
-				!lnw->hsm.vbus_srp_up) {
+		} else if (!iotg->hsm.a_sess_vld &&
+				!iotg->hsm.vbus_srp_up) {
 			langwell_otg_phy_low_power(1);
 		}
 		break;
 	case OTG_STATE_A_WAIT_VRISE:
-		if (lnw->hsm.id) {
+		if (iotg->hsm.id) {
 			langwell_otg_del_timer(a_wait_vrise_tmr);
-			lnw->hsm.b_bus_req = 0;
-			lnw->otg.default_a = 0;
-			langwell_otg_drv_vbus(0);
+			iotg->hsm.b_bus_req = 0;
+			iotg->otg.default_a = 0;
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			set_client_mode();
 			langwell_otg_phy_low_power_wait(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
-		} else if (lnw->hsm.a_vbus_vld) {
+			iotg->otg.state = OTG_STATE_B_IDLE;
+		} else if (iotg->hsm.a_vbus_vld) {
 			langwell_otg_del_timer(a_wait_vrise_tmr);
-			lnw->hsm.b_conn = 0;
-			if (lnw->host_ops)
-				lnw->host_ops->probe(lnw->pdev,
-						lnw->host_ops->id_table);
+			iotg->hsm.b_conn = 0;
+			if (lnw->iotg.start_host)
+				lnw->iotg.start_host(&lnw->iotg);
 			else {
-				dev_dbg(&lnw->pdev->dev,
-					"host driver not loaded.\n");
+				dev_dbg(lnw->dev, "host driver not loaded.\n");
 				break;
 			}
 
 			langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-			lnw->otg.state = OTG_STATE_A_WAIT_BCON;
-		} else if (lnw->hsm.a_wait_vrise_tmout) {
-			lnw->hsm.b_conn = 0;
-			if (lnw->hsm.a_vbus_vld) {
-				if (lnw->host_ops)
-					lnw->host_ops->probe(
-						lnw->pdev,
-						lnw->host_ops->id_table);
+			iotg->otg.state = OTG_STATE_A_WAIT_BCON;
+		} else if (iotg->hsm.a_wait_vrise_tmout) {
+			iotg->hsm.b_conn = 0;
+			if (iotg->hsm.a_vbus_vld) {
+				if (lnw->iotg.start_host)
+					lnw->iotg.start_host(&lnw->iotg);
 				else {
-					dev_dbg(&lnw->pdev->dev,
+					dev_dbg(lnw->dev,
 						"host driver not loaded.\n");
 					break;
 				}
 				langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-				lnw->otg.state = OTG_STATE_A_WAIT_BCON;
+				iotg->otg.state = OTG_STATE_A_WAIT_BCON;
 			} else {
-				langwell_otg_drv_vbus(0);
+
+				/* Turn off VBus */
+				iotg->otg.set_vbus(&iotg->otg, false);
 				langwell_otg_phy_low_power_wait(1);
-				lnw->otg.state = OTG_STATE_A_VBUS_ERR;
+				iotg->otg.state = OTG_STATE_A_VBUS_ERR;
 			}
 		}
 		break;
 	case OTG_STATE_A_WAIT_BCON:
-		if (lnw->hsm.id) {
+		if (iotg->hsm.id) {
 			/* delete hsm timer for a_wait_bcon_tmr */
 			del_timer_sync(&lnw->hsm_timer);
 
-			lnw->otg.default_a = 0;
-			lnw->hsm.b_bus_req = 0;
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			iotg->otg.default_a = 0;
+			iotg->hsm.b_bus_req = 0;
+
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			set_client_mode();
 			langwell_otg_phy_low_power_wait(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
+			iotg->otg.state = OTG_STATE_B_IDLE;
 			langwell_update_transceiver();
-		} else if (!lnw->hsm.a_vbus_vld) {
+		} else if (!iotg->hsm.a_vbus_vld) {
 			/* delete hsm timer for a_wait_bcon_tmr */
 			del_timer_sync(&lnw->hsm_timer);
 
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			langwell_otg_phy_low_power_wait(1);
-			lnw->otg.state = OTG_STATE_A_VBUS_ERR;
-		} else if (lnw->hsm.a_bus_drop ||
-				(lnw->hsm.a_wait_bcon_tmout &&
-				!lnw->hsm.a_bus_req)) {
+			iotg->otg.state = OTG_STATE_A_VBUS_ERR;
+		} else if (iotg->hsm.a_bus_drop ||
+				(iotg->hsm.a_wait_bcon_tmout &&
+				!iotg->hsm.a_bus_req)) {
 			/* delete hsm timer for a_wait_bcon_tmr */
 			del_timer_sync(&lnw->hsm_timer);
 
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
-			lnw->otg.state = OTG_STATE_A_WAIT_VFALL;
-		} else if (lnw->hsm.b_conn) {
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
+			iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+		} else if (iotg->hsm.b_conn) {
 			/* delete hsm timer for a_wait_bcon_tmr */
 			del_timer_sync(&lnw->hsm_timer);
 
-			lnw->hsm.a_suspend_req = 0;
-			lnw->otg.state = OTG_STATE_A_HOST;
-			if (lnw->hsm.a_srp_det &&
-					!lnw->otg.host->b_hnp_enable) {
+			iotg->hsm.a_suspend_req = 0;
+			iotg->otg.state = OTG_STATE_A_HOST;
+			if (iotg->hsm.a_srp_det && iotg->otg.host &&
+					!iotg->otg.host->b_hnp_enable) {
 				/* SRP capable peripheral-only device */
-				lnw->hsm.a_bus_req = 1;
-				lnw->hsm.a_srp_det = 0;
-			} else if (!lnw->hsm.a_bus_req &&
-					lnw->otg.host->b_hnp_enable) {
+				iotg->hsm.a_bus_req = 1;
+				iotg->hsm.a_srp_det = 0;
+			} else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
+					iotg->otg.host->b_hnp_enable) {
 				/* It is not safe enough to do a fast
 				 * transistion from A_WAIT_BCON to
 				 * A_SUSPEND */
 				msleep(10000);
-				if (lnw->hsm.a_bus_req)
+				if (iotg->hsm.a_bus_req)
 					break;
 
-				if (request_irq(lnw->pdev->irq,
+				if (request_irq(pdev->irq,
 					otg_dummy_irq, IRQF_SHARED,
-					driver_name, lnw->regs) != 0) {
-					dev_dbg(&lnw->pdev->dev,
+					driver_name, iotg->base) != 0) {
+					dev_dbg(lnw->dev,
 						"request interrupt %d fail\n",
-						lnw->pdev->irq);
+						pdev->irq);
 				}
 
 				langwell_otg_HABA(1);
-				lnw->hsm.b_bus_resume = 0;
-				lnw->hsm.a_aidl_bdis_tmout = 0;
+				iotg->hsm.b_bus_resume = 0;
+				iotg->hsm.a_aidl_bdis_tmout = 0;
 
 				langwell_otg_loc_sof(0);
 				/* clear PHCD to enable HW timer */
 				langwell_otg_phy_low_power(0);
 				langwell_otg_add_timer(a_aidl_bdis_tmr);
-				lnw->otg.state = OTG_STATE_A_SUSPEND;
-			} else if (!lnw->hsm.a_bus_req &&
-				!lnw->otg.host->b_hnp_enable) {
-				if (lnw->host_ops)
-					lnw->host_ops->remove(lnw->pdev);
+				iotg->otg.state = OTG_STATE_A_SUSPEND;
+			} else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
+				!iotg->otg.host->b_hnp_enable) {
+				if (lnw->iotg.stop_host)
+					lnw->iotg.stop_host(&lnw->iotg);
 				else
-					dev_dbg(&lnw->pdev->dev,
+					dev_dbg(lnw->dev,
 						"host driver removed.\n");
-				langwell_otg_drv_vbus(0);
-				lnw->otg.state = OTG_STATE_A_WAIT_VFALL;
+
+				/* Turn off VBus */
+				iotg->otg.set_vbus(&iotg->otg, false);
+				iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
 			}
 		}
 		break;
 	case OTG_STATE_A_HOST:
-		if (lnw->hsm.id) {
-			lnw->otg.default_a = 0;
-			lnw->hsm.b_bus_req = 0;
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+		if (iotg->hsm.id) {
+			iotg->otg.default_a = 0;
+			iotg->hsm.b_bus_req = 0;
+
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			set_client_mode();
 			langwell_otg_phy_low_power_wait(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
+			iotg->otg.state = OTG_STATE_B_IDLE;
 			langwell_update_transceiver();
-		} else if (lnw->hsm.a_bus_drop ||
-				(!lnw->otg.host->b_hnp_enable &&
-					!lnw->hsm.a_bus_req)) {
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+		} else if (iotg->hsm.a_bus_drop ||
+				(iotg->otg.host &&
+				!iotg->otg.host->b_hnp_enable &&
+					!iotg->hsm.a_bus_req)) {
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
-			lnw->otg.state = OTG_STATE_A_WAIT_VFALL;
-		} else if (!lnw->hsm.a_vbus_vld) {
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
+			iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+		} else if (!iotg->hsm.a_vbus_vld) {
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			langwell_otg_phy_low_power_wait(1);
-			lnw->otg.state = OTG_STATE_A_VBUS_ERR;
-		} else if (lnw->otg.host->b_hnp_enable
-				&& !lnw->hsm.a_bus_req) {
+			iotg->otg.state = OTG_STATE_A_VBUS_ERR;
+		} else if (iotg->otg.host &&
+				iotg->otg.host->b_hnp_enable &&
+				!iotg->hsm.a_bus_req) {
 			/* Set HABA to enable hardware assistance to signal
 			 *  A-connect after receiver B-disconnect. Hardware
 			 *  will then set client mode and enable URE, SLE and
 			 *  PCE after the assistance. otg_dummy_irq is used to
 			 *  clean these ints when client driver is not resumed.
 			 */
-			if (request_irq(lnw->pdev->irq,
-				otg_dummy_irq, IRQF_SHARED, driver_name,
-				lnw->regs) != 0) {
-				dev_dbg(&lnw->pdev->dev,
+			if (request_irq(pdev->irq, otg_dummy_irq, IRQF_SHARED,
+					driver_name, iotg->base) != 0) {
+				dev_dbg(lnw->dev,
 					"request interrupt %d failed\n",
-						lnw->pdev->irq);
+						pdev->irq);
 			}
 
 			/* set HABA */
 			langwell_otg_HABA(1);
-			lnw->hsm.b_bus_resume = 0;
-			lnw->hsm.a_aidl_bdis_tmout = 0;
+			iotg->hsm.b_bus_resume = 0;
+			iotg->hsm.a_aidl_bdis_tmout = 0;
 			langwell_otg_loc_sof(0);
 			/* clear PHCD to enable HW timer */
 			langwell_otg_phy_low_power(0);
 			langwell_otg_add_timer(a_aidl_bdis_tmr);
-			lnw->otg.state = OTG_STATE_A_SUSPEND;
-		} else if (!lnw->hsm.b_conn || !lnw->hsm.a_bus_req) {
+			iotg->otg.state = OTG_STATE_A_SUSPEND;
+		} else if (!iotg->hsm.b_conn || !iotg->hsm.a_bus_req) {
 			langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-			lnw->otg.state = OTG_STATE_A_WAIT_BCON;
+			iotg->otg.state = OTG_STATE_A_WAIT_BCON;
 		}
 		break;
 	case OTG_STATE_A_SUSPEND:
-		if (lnw->hsm.id) {
+		if (iotg->hsm.id) {
 			langwell_otg_del_timer(a_aidl_bdis_tmr);
 			langwell_otg_HABA(0);
-			free_irq(lnw->pdev->irq, lnw->regs);
-			lnw->otg.default_a = 0;
-			lnw->hsm.b_bus_req = 0;
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			free_irq(pdev->irq, iotg->base);
+			iotg->otg.default_a = 0;
+			iotg->hsm.b_bus_req = 0;
+
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			set_client_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
+			iotg->otg.state = OTG_STATE_B_IDLE;
 			langwell_update_transceiver();
-		} else if (lnw->hsm.a_bus_req ||
-				lnw->hsm.b_bus_resume) {
+		} else if (iotg->hsm.a_bus_req ||
+				iotg->hsm.b_bus_resume) {
 			langwell_otg_del_timer(a_aidl_bdis_tmr);
 			langwell_otg_HABA(0);
-			free_irq(lnw->pdev->irq, lnw->regs);
-			lnw->hsm.a_suspend_req = 0;
+			free_irq(pdev->irq, iotg->base);
+			iotg->hsm.a_suspend_req = 0;
 			langwell_otg_loc_sof(1);
-			lnw->otg.state = OTG_STATE_A_HOST;
-		} else if (lnw->hsm.a_aidl_bdis_tmout ||
-				lnw->hsm.a_bus_drop) {
+			iotg->otg.state = OTG_STATE_A_HOST;
+		} else if (iotg->hsm.a_aidl_bdis_tmout ||
+				iotg->hsm.a_bus_drop) {
 			langwell_otg_del_timer(a_aidl_bdis_tmr);
 			langwell_otg_HABA(0);
-			free_irq(lnw->pdev->irq, lnw->regs);
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			free_irq(pdev->irq, iotg->base);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
-			lnw->otg.state = OTG_STATE_A_WAIT_VFALL;
-		} else if (!lnw->hsm.b_conn &&
-				lnw->otg.host->b_hnp_enable) {
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
+			iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+		} else if (!iotg->hsm.b_conn && iotg->otg.host &&
+				iotg->otg.host->b_hnp_enable) {
 			langwell_otg_del_timer(a_aidl_bdis_tmr);
 			langwell_otg_HABA(0);
-			free_irq(lnw->pdev->irq, lnw->regs);
+			free_irq(pdev->irq, iotg->base);
 
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
 
-			lnw->hsm.b_bus_suspend = 0;
-			lnw->hsm.b_bus_suspend_vld = 0;
+			iotg->hsm.b_bus_suspend = 0;
+			iotg->hsm.b_bus_suspend_vld = 0;
 
 			/* msleep(200); */
-			if (lnw->client_ops)
-				lnw->client_ops->resume(lnw->pdev);
+			if (lnw->iotg.start_peripheral)
+				lnw->iotg.start_peripheral(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"client driver not loaded.\n");
 
 			langwell_otg_add_ktimer(TB_BUS_SUSPEND_TMR);
-			lnw->otg.state = OTG_STATE_A_PERIPHERAL;
+			iotg->otg.state = OTG_STATE_A_PERIPHERAL;
 			break;
-		} else if (!lnw->hsm.a_vbus_vld) {
+		} else if (!iotg->hsm.a_vbus_vld) {
 			langwell_otg_del_timer(a_aidl_bdis_tmr);
 			langwell_otg_HABA(0);
-			free_irq(lnw->pdev->irq, lnw->regs);
-			if (lnw->host_ops)
-				lnw->host_ops->remove(lnw->pdev);
+			free_irq(pdev->irq, iotg->base);
+			if (lnw->iotg.stop_host)
+				lnw->iotg.stop_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"host driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			langwell_otg_phy_low_power_wait(1);
-			lnw->otg.state = OTG_STATE_A_VBUS_ERR;
+			iotg->otg.state = OTG_STATE_A_VBUS_ERR;
 		}
 		break;
 	case OTG_STATE_A_PERIPHERAL:
-		if (lnw->hsm.id) {
+		if (iotg->hsm.id) {
 			/* delete hsm timer for b_bus_suspend_tmr */
 			del_timer_sync(&lnw->hsm_timer);
-			lnw->otg.default_a = 0;
-			lnw->hsm.b_bus_req = 0;
-			if (lnw->client_ops)
-				lnw->client_ops->suspend(lnw->pdev,
-					PMSG_FREEZE);
+			iotg->otg.default_a = 0;
+			iotg->hsm.b_bus_req = 0;
+			if (lnw->iotg.stop_peripheral)
+				lnw->iotg.stop_peripheral(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"client driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			set_client_mode();
 			langwell_otg_phy_low_power_wait(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
+			iotg->otg.state = OTG_STATE_B_IDLE;
 			langwell_update_transceiver();
-		} else if (!lnw->hsm.a_vbus_vld) {
+		} else if (!iotg->hsm.a_vbus_vld) {
 			/* delete hsm timer for b_bus_suspend_tmr */
 			del_timer_sync(&lnw->hsm_timer);
-			if (lnw->client_ops)
-				lnw->client_ops->suspend(lnw->pdev,
-					PMSG_FREEZE);
+
+			if (lnw->iotg.stop_peripheral)
+				lnw->iotg.stop_peripheral(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"client driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
 			langwell_otg_phy_low_power_wait(1);
-			lnw->otg.state = OTG_STATE_A_VBUS_ERR;
-		} else if (lnw->hsm.a_bus_drop) {
+			iotg->otg.state = OTG_STATE_A_VBUS_ERR;
+		} else if (iotg->hsm.a_bus_drop) {
 			/* delete hsm timer for b_bus_suspend_tmr */
 			del_timer_sync(&lnw->hsm_timer);
 
-			if (lnw->client_ops)
-				lnw->client_ops->suspend(lnw->pdev,
-					PMSG_FREEZE);
+			if (lnw->iotg.stop_peripheral)
+				lnw->iotg.stop_peripheral(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"client driver has been removed.\n");
-			langwell_otg_drv_vbus(0);
-			lnw->otg.state = OTG_STATE_A_WAIT_VFALL;
-		} else if (lnw->hsm.b_bus_suspend) {
+
+			/* Turn off VBus */
+			iotg->otg.set_vbus(&iotg->otg, false);
+			iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
+		} else if (iotg->hsm.b_bus_suspend) {
 			/* delete hsm timer for b_bus_suspend_tmr */
 			del_timer_sync(&lnw->hsm_timer);
-			if (lnw->client_ops)
-				lnw->client_ops->suspend(lnw->pdev,
-					PMSG_FREEZE);
+
+			if (lnw->iotg.stop_peripheral)
+				lnw->iotg.stop_peripheral(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"client driver has been removed.\n");
-			if (lnw->host_ops)
-				lnw->host_ops->probe(lnw->pdev,
-						lnw->host_ops->id_table);
+
+			if (lnw->iotg.start_host)
+				lnw->iotg.start_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
-					"host driver not loaded.\n");
+				dev_dbg(lnw->dev,
+						"host driver not loaded.\n");
 			langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-			lnw->otg.state = OTG_STATE_A_WAIT_BCON;
-		} else if (lnw->hsm.b_bus_suspend_tmout) {
+			iotg->otg.state = OTG_STATE_A_WAIT_BCON;
+		} else if (iotg->hsm.b_bus_suspend_tmout) {
 			u32	val;
-			val = readl(lnw->regs + CI_PORTSC1);
+			val = readl(lnw->iotg.base + CI_PORTSC1);
 			if (!(val & PORTSC_SUSP))
 				break;
-			if (lnw->client_ops)
-				lnw->client_ops->suspend(lnw->pdev,
-						PMSG_FREEZE);
+
+			if (lnw->iotg.stop_peripheral)
+				lnw->iotg.stop_peripheral(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
+				dev_dbg(lnw->dev,
 					"client driver has been removed.\n");
-			if (lnw->host_ops)
-				lnw->host_ops->probe(lnw->pdev,
-						lnw->host_ops->id_table);
+
+			if (lnw->iotg.start_host)
+				lnw->iotg.start_host(&lnw->iotg);
 			else
-				dev_dbg(&lnw->pdev->dev,
-					"host driver not loaded.\n");
+				dev_dbg(lnw->dev,
+						"host driver not loaded.\n");
 			langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
-			lnw->otg.state = OTG_STATE_A_WAIT_BCON;
+			iotg->otg.state = OTG_STATE_A_WAIT_BCON;
 		}
 		break;
 	case OTG_STATE_A_VBUS_ERR:
-		if (lnw->hsm.id) {
-			lnw->otg.default_a = 0;
-			lnw->hsm.a_clr_err = 0;
-			lnw->hsm.a_srp_det = 0;
+		if (iotg->hsm.id) {
+			iotg->otg.default_a = 0;
+			iotg->hsm.a_clr_err = 0;
+			iotg->hsm.a_srp_det = 0;
 			set_client_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
+			iotg->otg.state = OTG_STATE_B_IDLE;
 			langwell_update_transceiver();
-		} else if (lnw->hsm.a_clr_err) {
-			lnw->hsm.a_clr_err = 0;
-			lnw->hsm.a_srp_det = 0;
+		} else if (iotg->hsm.a_clr_err) {
+			iotg->hsm.a_clr_err = 0;
+			iotg->hsm.a_srp_det = 0;
 			reset_otg();
 			init_hsm();
-			if (lnw->otg.state == OTG_STATE_A_IDLE)
+			if (iotg->otg.state == OTG_STATE_A_IDLE)
 				langwell_update_transceiver();
 		} else {
 			/* FW will clear PHCD bit when any VBus
@@ -1551,30 +1609,32 @@ static void langwell_otg_work(struct work_struct *work)
 		}
 		break;
 	case OTG_STATE_A_WAIT_VFALL:
-		if (lnw->hsm.id) {
-			lnw->otg.default_a = 0;
+		if (iotg->hsm.id) {
+			iotg->otg.default_a = 0;
 			set_client_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_B_IDLE;
+			iotg->otg.state = OTG_STATE_B_IDLE;
 			langwell_update_transceiver();
-		} else if (lnw->hsm.a_bus_req) {
-			langwell_otg_drv_vbus(1);
-			lnw->hsm.a_wait_vrise_tmout = 0;
+		} else if (iotg->hsm.a_bus_req) {
+
+			/* Turn on VBus */
+			iotg->otg.set_vbus(&iotg->otg, true);
+			iotg->hsm.a_wait_vrise_tmout = 0;
 			langwell_otg_add_timer(a_wait_vrise_tmr);
-			lnw->otg.state = OTG_STATE_A_WAIT_VRISE;
-		} else if (!lnw->hsm.a_sess_vld) {
-			lnw->hsm.a_srp_det = 0;
+			iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
+		} else if (!iotg->hsm.a_sess_vld) {
+			iotg->hsm.a_srp_det = 0;
 			set_host_mode();
 			langwell_otg_phy_low_power(1);
-			lnw->otg.state = OTG_STATE_A_IDLE;
+			iotg->otg.state = OTG_STATE_A_IDLE;
 		}
 		break;
 	default:
 		;
 	}
 
-	dev_dbg(&lnw->pdev->dev, "%s: new state = %s\n", __func__,
-			state_string(lnw->otg.state));
+	dev_dbg(lnw->dev, "%s: new state = %s\n", __func__,
+			state_string(iotg->otg.state));
 }
 
 static ssize_t
@@ -1597,15 +1657,15 @@ show_registers(struct device *_dev, struct device_attribute *attr, char *buf)
 		"HOSTPC1 = 0x%08x\n"
 		"OTGSC = 0x%08x\n"
 		"USBMODE = 0x%08x\n",
-		readl(lnw->regs + 0x30),
-		readl(lnw->regs + 0x34),
-		readl(lnw->regs + 0x38),
-		readl(lnw->regs + 0x48),
-		readl(lnw->regs + 0x74),
-		readl(lnw->regs + 0xb4),
-		readl(lnw->regs + 0xf4),
-		readl(lnw->regs + 0xf8)
-		);
+		readl(lnw->iotg.base + 0x30),
+		readl(lnw->iotg.base + 0x34),
+		readl(lnw->iotg.base + 0x38),
+		readl(lnw->iotg.base + 0x48),
+		readl(lnw->iotg.base + 0x74),
+		readl(lnw->iotg.base + 0xb4),
+		readl(lnw->iotg.base + 0xf4),
+		readl(lnw->iotg.base + 0xf8)
+	     );
 	size -= t;
 	next += t;
 
@@ -1616,18 +1676,19 @@ static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
 static ssize_t
 show_hsm(struct device *_dev, struct device_attribute *attr, char *buf)
 {
-	struct langwell_otg	*lnw = the_transceiver;
-	char			*next;
-	unsigned		size, t;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	char				*next;
+	unsigned			size, t;
 
 	next = buf;
 	size = PAGE_SIZE;
 
-	if (lnw->otg.host)
-		lnw->hsm.a_set_b_hnp_en = lnw->otg.host->b_hnp_enable;
+	if (iotg->otg.host)
+		iotg->hsm.a_set_b_hnp_en = iotg->otg.host->b_hnp_enable;
 
-	if (lnw->otg.gadget)
-		lnw->hsm.b_hnp_enable = lnw->otg.gadget->b_hnp_enable;
+	if (iotg->otg.gadget)
+		iotg->hsm.b_hnp_enable = iotg->otg.gadget->b_hnp_enable;
 
 	t = scnprintf(next, size,
 		"\n"
@@ -1659,34 +1720,34 @@ show_hsm(struct device *_dev, struct device_attribute *attr, char *buf)
 		"b_bus_req = \t%d\n"
 		"b_bus_suspend_tmout = \t%d\n"
 		"b_bus_suspend_vld = \t%d\n",
-		state_string(lnw->otg.state),
-		lnw->hsm.a_bus_resume,
-		lnw->hsm.a_bus_suspend,
-		lnw->hsm.a_conn,
-		lnw->hsm.a_sess_vld,
-		lnw->hsm.a_srp_det,
-		lnw->hsm.a_vbus_vld,
-		lnw->hsm.b_bus_resume,
-		lnw->hsm.b_bus_suspend,
-		lnw->hsm.b_conn,
-		lnw->hsm.b_se0_srp,
-		lnw->hsm.b_sess_end,
-		lnw->hsm.b_sess_vld,
-		lnw->hsm.id,
-		lnw->hsm.a_set_b_hnp_en,
-		lnw->hsm.b_srp_done,
-		lnw->hsm.b_hnp_enable,
-		lnw->hsm.a_wait_vrise_tmout,
-		lnw->hsm.a_wait_bcon_tmout,
-		lnw->hsm.a_aidl_bdis_tmout,
-		lnw->hsm.b_ase0_brst_tmout,
-		lnw->hsm.a_bus_drop,
-		lnw->hsm.a_bus_req,
-		lnw->hsm.a_clr_err,
-		lnw->hsm.a_suspend_req,
-		lnw->hsm.b_bus_req,
-		lnw->hsm.b_bus_suspend_tmout,
-		lnw->hsm.b_bus_suspend_vld
+		state_string(iotg->otg.state),
+		iotg->hsm.a_bus_resume,
+		iotg->hsm.a_bus_suspend,
+		iotg->hsm.a_conn,
+		iotg->hsm.a_sess_vld,
+		iotg->hsm.a_srp_det,
+		iotg->hsm.a_vbus_vld,
+		iotg->hsm.b_bus_resume,
+		iotg->hsm.b_bus_suspend,
+		iotg->hsm.b_conn,
+		iotg->hsm.b_se0_srp,
+		iotg->hsm.b_sess_end,
+		iotg->hsm.b_sess_vld,
+		iotg->hsm.id,
+		iotg->hsm.a_set_b_hnp_en,
+		iotg->hsm.b_srp_done,
+		iotg->hsm.b_hnp_enable,
+		iotg->hsm.a_wait_vrise_tmout,
+		iotg->hsm.a_wait_bcon_tmout,
+		iotg->hsm.a_aidl_bdis_tmout,
+		iotg->hsm.b_ase0_brst_tmout,
+		iotg->hsm.a_bus_drop,
+		iotg->hsm.a_bus_req,
+		iotg->hsm.a_clr_err,
+		iotg->hsm.a_suspend_req,
+		iotg->hsm.b_bus_req,
+		iotg->hsm.b_bus_suspend_tmout,
+		iotg->hsm.b_bus_suspend_vld
 		);
 	size -= t;
 	next += t;
@@ -1705,7 +1766,7 @@ get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
 	next = buf;
 	size = PAGE_SIZE;
 
-	t = scnprintf(next, size, "%d", lnw->hsm.a_bus_req);
+	t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_req);
 	size -= t;
 	next += t;
 
@@ -1716,22 +1777,23 @@ static ssize_t
 set_a_bus_req(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
-	struct langwell_otg	*lnw = the_transceiver;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
 
-	if (!lnw->otg.default_a)
+	if (!iotg->otg.default_a)
 		return -1;
 	if (count > 2)
 		return -1;
 
 	if (buf[0] == '0') {
-		lnw->hsm.a_bus_req = 0;
-		dev_dbg(&lnw->pdev->dev, "User request: a_bus_req = 0\n");
+		iotg->hsm.a_bus_req = 0;
+		dev_dbg(lnw->dev, "User request: a_bus_req = 0\n");
 	} else if (buf[0] == '1') {
 		/* If a_bus_drop is TRUE, a_bus_req can't be set */
-		if (lnw->hsm.a_bus_drop)
+		if (iotg->hsm.a_bus_drop)
 			return -1;
-		lnw->hsm.a_bus_req = 1;
-		dev_dbg(&lnw->pdev->dev, "User request: a_bus_req = 1\n");
+		iotg->hsm.a_bus_req = 1;
+		dev_dbg(lnw->dev, "User request: a_bus_req = 1\n");
 	}
 	if (spin_trylock(&lnw->wq_lock)) {
 		langwell_update_transceiver();
@@ -1751,7 +1813,7 @@ get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
 	next = buf;
 	size = PAGE_SIZE;
 
-	t = scnprintf(next, size, "%d", lnw->hsm.a_bus_drop);
+	t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_drop);
 	size -= t;
 	next += t;
 
@@ -1762,21 +1824,22 @@ static ssize_t
 set_a_bus_drop(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
-	struct langwell_otg	*lnw = the_transceiver;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
 
-	if (!lnw->otg.default_a)
+	if (!iotg->otg.default_a)
 		return -1;
 	if (count > 2)
 		return -1;
 
 	if (buf[0] == '0') {
-		lnw->hsm.a_bus_drop = 0;
-		dev_dbg(&lnw->pdev->dev, "User request: a_bus_drop = 0\n");
+		iotg->hsm.a_bus_drop = 0;
+		dev_dbg(lnw->dev, "User request: a_bus_drop = 0\n");
 	} else if (buf[0] == '1') {
-		lnw->hsm.a_bus_drop = 1;
-		lnw->hsm.a_bus_req = 0;
-		dev_dbg(&lnw->pdev->dev, "User request: a_bus_drop = 1\n");
-		dev_dbg(&lnw->pdev->dev, "User request: and a_bus_req = 0\n");
+		iotg->hsm.a_bus_drop = 1;
+		iotg->hsm.a_bus_req = 0;
+		dev_dbg(lnw->dev, "User request: a_bus_drop = 1\n");
+		dev_dbg(lnw->dev, "User request: and a_bus_req = 0\n");
 	}
 	if (spin_trylock(&lnw->wq_lock)) {
 		langwell_update_transceiver();
@@ -1797,7 +1860,7 @@ get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
 	next = buf;
 	size = PAGE_SIZE;
 
-	t = scnprintf(next, size, "%d", lnw->hsm.b_bus_req);
+	t = scnprintf(next, size, "%d", lnw->iotg.hsm.b_bus_req);
 	size -= t;
 	next += t;
 
@@ -1808,20 +1871,21 @@ static ssize_t
 set_b_bus_req(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
-	struct langwell_otg *lnw = the_transceiver;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
 
-	if (lnw->otg.default_a)
+	if (iotg->otg.default_a)
 		return -1;
 
 	if (count > 2)
 		return -1;
 
 	if (buf[0] == '0') {
-		lnw->hsm.b_bus_req = 0;
-		dev_dbg(&lnw->pdev->dev, "User request: b_bus_req = 0\n");
+		iotg->hsm.b_bus_req = 0;
+		dev_dbg(lnw->dev, "User request: b_bus_req = 0\n");
 	} else if (buf[0] == '1') {
-		lnw->hsm.b_bus_req = 1;
-		dev_dbg(&lnw->pdev->dev, "User request: b_bus_req = 1\n");
+		iotg->hsm.b_bus_req = 1;
+		dev_dbg(lnw->dev, "User request: b_bus_req = 1\n");
 	}
 	if (spin_trylock(&lnw->wq_lock)) {
 		langwell_update_transceiver();
@@ -1835,16 +1899,17 @@ static ssize_t
 set_a_clr_err(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
-	struct langwell_otg *lnw = the_transceiver;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
 
-	if (!lnw->otg.default_a)
+	if (!iotg->otg.default_a)
 		return -1;
 	if (count > 2)
 		return -1;
 
 	if (buf[0] == '1') {
-		lnw->hsm.a_clr_err = 1;
-		dev_dbg(&lnw->pdev->dev, "User request: a_clr_err = 1\n");
+		iotg->hsm.a_clr_err = 1;
+		dev_dbg(lnw->dev, "User request: a_clr_err = 1\n");
 	}
 	if (spin_trylock(&lnw->wq_lock)) {
 		langwell_update_transceiver();
@@ -1867,65 +1932,6 @@ static struct attribute_group debug_dev_attr_group = {
 	.attrs = inputs_attrs,
 };
 
-int langwell_register_host(struct pci_driver *host_driver)
-{
-	struct langwell_otg	*lnw = the_transceiver;
-	int	ret = 0;
-
-	lnw->host_ops = host_driver;
-	langwell_update_transceiver();
-	dev_dbg(&lnw->pdev->dev, "host controller driver is registered\n");
-
-	return ret;
-}
-EXPORT_SYMBOL(langwell_register_host);
-
-void langwell_unregister_host(struct pci_driver *host_driver)
-{
-	struct langwell_otg	*lnw = the_transceiver;
-
-	if (lnw->host_ops)
-		lnw->host_ops->remove(lnw->pdev);
-	lnw->host_ops = NULL;
-	lnw->hsm.a_bus_drop = 1;
-	langwell_update_transceiver();
-	dev_dbg(&lnw->pdev->dev, "host controller driver is unregistered\n");
-}
-EXPORT_SYMBOL(langwell_unregister_host);
-
-int langwell_register_peripheral(struct pci_driver *client_driver)
-{
-	struct langwell_otg	*lnw = the_transceiver;
-	int	ret = 0;
-
-	if (client_driver)
-		ret = client_driver->probe(lnw->pdev,
-				client_driver->id_table);
-	if (!ret) {
-		lnw->client_ops = client_driver;
-		langwell_update_transceiver();
-		dev_dbg(&lnw->pdev->dev,
-			"client controller driver is registered\n");
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL(langwell_register_peripheral);
-
-void langwell_unregister_peripheral(struct pci_driver *client_driver)
-{
-	struct langwell_otg	*lnw = the_transceiver;
-
-	if (lnw->client_ops)
-		lnw->client_ops->remove(lnw->pdev);
-	lnw->client_ops = NULL;
-	lnw->hsm.b_bus_req = 0;
-	langwell_update_transceiver();
-	dev_dbg(&lnw->pdev->dev,
-		"client controller driver is unregistered\n");
-}
-EXPORT_SYMBOL(langwell_unregister_peripheral);
-
 static int langwell_otg_probe(struct pci_dev *pdev,
 		const struct pci_device_id *id)
 {
@@ -1933,7 +1939,7 @@ static int langwell_otg_probe(struct pci_dev *pdev,
 	void __iomem		*base = NULL;
 	int			retval;
 	u32			val32;
-	struct langwell_otg	*langwell;
+	struct langwell_otg	*lnw;
 	char			qname[] = "langwell_otg_queue";
 
 	retval = 0;
@@ -1943,12 +1949,12 @@ static int langwell_otg_probe(struct pci_dev *pdev,
 		goto done;
 	}
 
-	langwell = kzalloc(sizeof *langwell, GFP_KERNEL);
-	if (langwell == NULL) {
+	lnw = kzalloc(sizeof *lnw, GFP_KERNEL);
+	if (lnw == NULL) {
 		retval = -ENOMEM;
 		goto done;
 	}
-	the_transceiver = langwell;
+	the_transceiver = lnw;
 
 	/* control register: BAR 0 */
 	resource = pci_resource_start(pdev, 0);
@@ -1957,20 +1963,20 @@ static int langwell_otg_probe(struct pci_dev *pdev,
 		retval = -EBUSY;
 		goto err;
 	}
-	langwell->region = 1;
+	lnw->region = 1;
 
 	base = ioremap_nocache(resource, len);
 	if (base == NULL) {
 		retval = -EFAULT;
 		goto err;
 	}
-	langwell->regs = base;
+	lnw->iotg.base = base;
 
 	if (!request_mem_region(USBCFG_ADDR, USBCFG_LEN, driver_name)) {
 		retval = -EBUSY;
 		goto err;
 	}
-	langwell->cfg_region = 1;
+	lnw->cfg_region = 1;
 
 	/* For the SCCB.USBCFG register */
 	base = ioremap_nocache(USBCFG_ADDR, USBCFG_LEN);
@@ -1978,7 +1984,7 @@ static int langwell_otg_probe(struct pci_dev *pdev,
 		retval = -EFAULT;
 		goto err;
 	}
-	langwell->usbcfg = base;
+	lnw->usbcfg = base;
 
 	if (!pdev->irq) {
 		dev_dbg(&pdev->dev, "No IRQ.\n");
@@ -1986,25 +1992,27 @@ static int langwell_otg_probe(struct pci_dev *pdev,
 		goto err;
 	}
 
-	langwell->qwork = create_singlethread_workqueue(qname);
-	if (!langwell->qwork) {
+	lnw->qwork = create_singlethread_workqueue(qname);
+	if (!lnw->qwork) {
 		dev_dbg(&pdev->dev, "cannot create workqueue %s\n", qname);
 		retval = -ENOMEM;
 		goto err;
 	}
-	INIT_WORK(&langwell->work, langwell_otg_work);
+	INIT_WORK(&lnw->work, langwell_otg_work);
 
 	/* OTG common part */
-	langwell->pdev = pdev;
-	langwell->otg.dev = &pdev->dev;
-	langwell->otg.label = driver_name;
-	langwell->otg.set_host = langwell_otg_set_host;
-	langwell->otg.set_peripheral = langwell_otg_set_peripheral;
-	langwell->otg.set_power = langwell_otg_set_power;
-	langwell->otg.start_srp = langwell_otg_start_srp;
-	langwell->otg.state = OTG_STATE_UNDEFINED;
-	if (otg_set_transceiver(&langwell->otg)) {
-		dev_dbg(&pdev->dev, "can't set transceiver\n");
+	lnw->dev = &pdev->dev;
+	lnw->iotg.otg.dev = lnw->dev;
+	lnw->iotg.otg.label = driver_name;
+	lnw->iotg.otg.set_host = langwell_otg_set_host;
+	lnw->iotg.otg.set_peripheral = langwell_otg_set_peripheral;
+	lnw->iotg.otg.set_power = langwell_otg_set_power;
+	lnw->iotg.otg.set_vbus = langwell_otg_set_vbus;
+	lnw->iotg.otg.start_srp = langwell_otg_start_srp;
+	lnw->iotg.otg.state = OTG_STATE_UNDEFINED;
+
+	if (otg_set_transceiver(&lnw->iotg.otg)) {
+		dev_dbg(lnw->dev, "can't set transceiver\n");
 		retval = -EBUSY;
 		goto err;
 	}
@@ -2012,19 +2020,19 @@ static int langwell_otg_probe(struct pci_dev *pdev,
 	reset_otg();
 	init_hsm();
 
-	spin_lock_init(&langwell->lock);
-	spin_lock_init(&langwell->wq_lock);
+	spin_lock_init(&lnw->lock);
+	spin_lock_init(&lnw->wq_lock);
 	INIT_LIST_HEAD(&active_timers);
-	retval = langwell_otg_init_timers(&langwell->hsm);
+	retval = langwell_otg_init_timers(&lnw->iotg.hsm);
 	if (retval) {
 		dev_dbg(&pdev->dev, "Failed to init timers\n");
 		goto err;
 	}
 
-	init_timer(&langwell->hsm_timer);
+	init_timer(&lnw->hsm_timer);
 	if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
-				driver_name, langwell) != 0) {
-		dev_dbg(&pdev->dev, "request interrupt %d failed\n", pdev->irq);
+				driver_name, lnw) != 0) {
+		dev_dbg(lnw->dev, "request interrupt %d failed\n", pdev->irq);
 		retval = -EBUSY;
 		goto err;
 	}
@@ -2032,29 +2040,29 @@ static int langwell_otg_probe(struct pci_dev *pdev,
 	/* enable OTGSC int */
 	val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE |
 		OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU;
-	writel(val32, langwell->regs + CI_OTGSC);
+	writel(val32, lnw->iotg.base + CI_OTGSC);
 
 	retval = device_create_file(&pdev->dev, &dev_attr_registers);
 	if (retval < 0) {
-		dev_dbg(&pdev->dev, "Can't register sysfs attribute: %d\n",
-					 retval);
+		dev_dbg(lnw->dev,
+			"Can't register sysfs attribute: %d\n", retval);
 		goto err;
 	}
 
 	retval = device_create_file(&pdev->dev, &dev_attr_hsm);
 	if (retval < 0) {
-		dev_dbg(&pdev->dev, "Can't hsm sysfs attribute: %d\n", retval);
+		dev_dbg(lnw->dev, "Can't hsm sysfs attribute: %d\n", retval);
 		goto err;
 	}
 
 	retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group);
 	if (retval < 0) {
-		dev_dbg(&pdev->dev, "Can't register sysfs attr group: %d\n",
-					retval);
+		dev_dbg(lnw->dev,
+			"Can't register sysfs attr group: %d\n", retval);
 		goto err;
 	}
 
-	if (langwell->otg.state == OTG_STATE_A_IDLE)
+	if (lnw->iotg.otg.state == OTG_STATE_A_IDLE)
 		langwell_update_transceiver();
 
 	return 0;
@@ -2068,28 +2076,26 @@ done:
 
 static void langwell_otg_remove(struct pci_dev *pdev)
 {
-	struct langwell_otg *langwell;
-
-	langwell = the_transceiver;
+	struct langwell_otg *lnw = the_transceiver;
 
-	if (langwell->qwork) {
-		flush_workqueue(langwell->qwork);
-		destroy_workqueue(langwell->qwork);
+	if (lnw->qwork) {
+		flush_workqueue(lnw->qwork);
+		destroy_workqueue(lnw->qwork);
 	}
 	langwell_otg_free_timers();
 
 	/* disable OTGSC interrupt as OTGSC doesn't change in reset */
-	writel(0, langwell->regs + CI_OTGSC);
+	writel(0, lnw->iotg.base + CI_OTGSC);
 
 	if (pdev->irq)
-		free_irq(pdev->irq, langwell);
-	if (langwell->usbcfg)
-		iounmap(langwell->usbcfg);
-	if (langwell->cfg_region)
+		free_irq(pdev->irq, lnw);
+	if (lnw->usbcfg)
+		iounmap(lnw->usbcfg);
+	if (lnw->cfg_region)
 		release_mem_region(USBCFG_ADDR, USBCFG_LEN);
-	if (langwell->regs)
-		iounmap(langwell->regs);
-	if (langwell->region)
+	if (lnw->iotg.base)
+		iounmap(lnw->iotg.base);
+	if (lnw->region)
 		release_mem_region(pci_resource_start(pdev, 0),
 				pci_resource_len(pdev, 0));
 
@@ -2098,8 +2104,8 @@ static void langwell_otg_remove(struct pci_dev *pdev)
 	sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group);
 	device_remove_file(&pdev->dev, &dev_attr_hsm);
 	device_remove_file(&pdev->dev, &dev_attr_registers);
-	kfree(langwell);
-	langwell = NULL;
+	kfree(lnw);
+	lnw = NULL;
 }
 
 static void transceiver_suspend(struct pci_dev *pdev)
@@ -2111,8 +2117,9 @@ static void transceiver_suspend(struct pci_dev *pdev)
 
 static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message)
 {
-	struct langwell_otg	*lnw = the_transceiver;
-	int			ret = 0;
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = &lnw->iotg;
+	int				ret = 0;
 
 	/* Disbale OTG interrupts */
 	langwell_otg_intr(0);
@@ -2126,9 +2133,9 @@ static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message)
 	lnw->qwork = NULL;
 
 	/* start actions */
-	switch (lnw->otg.state) {
+	switch (iotg->otg.state) {
 	case OTG_STATE_A_WAIT_VFALL:
-		lnw->otg.state = OTG_STATE_A_IDLE;
+		iotg->otg.state = OTG_STATE_A_IDLE;
 	case OTG_STATE_A_IDLE:
 	case OTG_STATE_B_IDLE:
 	case OTG_STATE_A_VBUS_ERR:
@@ -2136,96 +2143,104 @@ static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message)
 		break;
 	case OTG_STATE_A_WAIT_VRISE:
 		langwell_otg_del_timer(a_wait_vrise_tmr);
-		lnw->hsm.a_srp_det = 0;
+		iotg->hsm.a_srp_det = 0;
 
-		langwell_otg_drv_vbus(0);
-		lnw->otg.state = OTG_STATE_A_IDLE;
+		/* Turn off VBus */
+		iotg->otg.set_vbus(&iotg->otg, false);
+		iotg->otg.state = OTG_STATE_A_IDLE;
 		transceiver_suspend(pdev);
 		break;
 	case OTG_STATE_A_WAIT_BCON:
 		del_timer_sync(&lnw->hsm_timer);
-		if (lnw->host_ops)
-			lnw->host_ops->remove(pdev);
+		if (lnw->iotg.stop_host)
+			lnw->iotg.stop_host(&lnw->iotg);
 		else
 			dev_dbg(&pdev->dev, "host driver has been removed.\n");
 
-		lnw->hsm.a_srp_det = 0;
-
-		langwell_otg_drv_vbus(0);
+		iotg->hsm.a_srp_det = 0;
 
-		lnw->otg.state = OTG_STATE_A_IDLE;
+		/* Turn off VBus */
+		iotg->otg.set_vbus(&iotg->otg, false);
+		iotg->otg.state = OTG_STATE_A_IDLE;
 		transceiver_suspend(pdev);
 		break;
 	case OTG_STATE_A_HOST:
-		if (lnw->host_ops)
-			lnw->host_ops->remove(pdev);
+		if (lnw->iotg.stop_host)
+			lnw->iotg.stop_host(&lnw->iotg);
 		else
 			dev_dbg(&pdev->dev, "host driver has been removed.\n");
 
-		lnw->hsm.a_srp_det = 0;
+		iotg->hsm.a_srp_det = 0;
 
-		langwell_otg_drv_vbus(0);
-		lnw->otg.state = OTG_STATE_A_IDLE;
+		/* Turn off VBus */
+		iotg->otg.set_vbus(&iotg->otg, false);
+
+		iotg->otg.state = OTG_STATE_A_IDLE;
 		transceiver_suspend(pdev);
 		break;
 	case OTG_STATE_A_SUSPEND:
 		langwell_otg_del_timer(a_aidl_bdis_tmr);
 		langwell_otg_HABA(0);
-		if (lnw->host_ops)
-			lnw->host_ops->remove(pdev);
+		if (lnw->iotg.stop_host)
+			lnw->iotg.stop_host(&lnw->iotg);
 		else
-			dev_dbg(&pdev->dev, "host driver has been removed.\n");
-		lnw->hsm.a_srp_det = 0;
+			dev_dbg(lnw->dev, "host driver has been removed.\n");
+		iotg->hsm.a_srp_det = 0;
 
-		langwell_otg_drv_vbus(0);
-		lnw->otg.state = OTG_STATE_A_IDLE;
+		/* Turn off VBus */
+		iotg->otg.set_vbus(&iotg->otg, false);
+		iotg->otg.state = OTG_STATE_A_IDLE;
 		transceiver_suspend(pdev);
 		break;
 	case OTG_STATE_A_PERIPHERAL:
 		del_timer_sync(&lnw->hsm_timer);
-		if (lnw->client_ops)
-			lnw->client_ops->suspend(pdev, message);
+
+		if (lnw->iotg.stop_peripheral)
+			lnw->iotg.stop_peripheral(&lnw->iotg);
 		else
 			dev_dbg(&pdev->dev,
 				"client driver has been removed.\n");
-		lnw->hsm.a_srp_det = 0;
+		iotg->hsm.a_srp_det = 0;
 
-		langwell_otg_drv_vbus(0);
-		lnw->otg.state = OTG_STATE_A_IDLE;
+		/* Turn off VBus */
+		iotg->otg.set_vbus(&iotg->otg, false);
+		iotg->otg.state = OTG_STATE_A_IDLE;
 		transceiver_suspend(pdev);
 		break;
 	case OTG_STATE_B_HOST:
-		if (lnw->host_ops)
-			lnw->host_ops->remove(pdev);
+		if (lnw->iotg.stop_host)
+			lnw->iotg.stop_host(&lnw->iotg);
 		else
 			dev_dbg(&pdev->dev, "host driver has been removed.\n");
-		lnw->hsm.b_bus_req = 0;
-		lnw->otg.state = OTG_STATE_B_IDLE;
+		iotg->hsm.b_bus_req = 0;
+		iotg->otg.state = OTG_STATE_B_IDLE;
 		transceiver_suspend(pdev);
 		break;
 	case OTG_STATE_B_PERIPHERAL:
-		if (lnw->client_ops)
-			lnw->client_ops->suspend(pdev, message);
+		if (lnw->iotg.stop_peripheral)
+			lnw->iotg.stop_peripheral(&lnw->iotg);
 		else
 			dev_dbg(&pdev->dev,
 				"client driver has been removed.\n");
-		lnw->otg.state = OTG_STATE_B_IDLE;
+		iotg->otg.state = OTG_STATE_B_IDLE;
 		transceiver_suspend(pdev);
 		break;
 	case OTG_STATE_B_WAIT_ACON:
 		/* delete hsm timer for b_ase0_brst_tmr */
 		del_timer_sync(&lnw->hsm_timer);
+
 		langwell_otg_HAAR(0);
-		if (lnw->host_ops)
-			lnw->host_ops->remove(pdev);
+
+		if (lnw->iotg.stop_host)
+			lnw->iotg.stop_host(&lnw->iotg);
 		else
 			dev_dbg(&pdev->dev, "host driver has been removed.\n");
-		lnw->hsm.b_bus_req = 0;
-		lnw->otg.state = OTG_STATE_B_IDLE;
+		iotg->hsm.b_bus_req = 0;
+		iotg->otg.state = OTG_STATE_B_IDLE;
 		transceiver_suspend(pdev);
 		break;
 	default:
-		dev_dbg(&pdev->dev, "error state before suspend\n ");
+		dev_dbg(lnw->dev, "error state before suspend\n");
 		break;
 	}
 
diff --git a/include/linux/usb/langwell_otg.h b/include/linux/usb/langwell_otg.h
index a5a3744..5da7f59 100644
--- a/include/linux/usb/langwell_otg.h
+++ b/include/linux/usb/langwell_otg.h
@@ -17,21 +17,10 @@
  *
  */
 
-#ifndef __LANGWELL_OTG_H__
-#define __LANGWELL_OTG_H__
+#ifndef __LANGWELL_OTG_H
+#define __LANGWELL_OTG_H
 
-/* notify transceiver driver about OTG events */
-extern void langwell_update_transceiver(void);
-/* HCD register bus driver */
-extern int langwell_register_host(struct pci_driver *host_driver);
-/* HCD unregister bus driver */
-extern void langwell_unregister_host(struct pci_driver *host_driver);
-/* DCD register bus driver */
-extern int langwell_register_peripheral(struct pci_driver *client_driver);
-/* DCD unregister bus driver */
-extern void langwell_unregister_peripheral(struct pci_driver *client_driver);
-/* No silent failure, output warning message */
-extern void langwell_otg_nsf_msg(unsigned long message);
+#include <linux/usb/intel_mid_otg.h>
 
 #define CI_USBCMD		0x30
 #	define USBCMD_RST		BIT(1)
@@ -94,53 +83,6 @@ extern void langwell_otg_nsf_msg(unsigned long message);
 
 #define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI)
 
-struct otg_hsm {
-	/* Input */
-	int a_bus_resume;
-	int a_bus_suspend;
-	int a_conn;
-	int a_sess_vld;
-	int a_srp_det;
-	int a_vbus_vld;
-	int b_bus_resume;
-	int b_bus_suspend;
-	int b_conn;
-	int b_se0_srp;
-	int b_sess_end;
-	int b_sess_vld;
-	int id;
-
-	/* Internal variables */
-	int a_set_b_hnp_en;
-	int b_srp_done;
-	int b_hnp_enable;
-
-	/* Timeout indicator for timers */
-	int a_wait_vrise_tmout;
-	int a_wait_bcon_tmout;
-	int a_aidl_bdis_tmout;
-	int b_ase0_brst_tmout;
-	int b_bus_suspend_tmout;
-	int b_srp_init_tmout;
-	int b_srp_fail_tmout;
-
-	/* Informative variables */
-	int a_bus_drop;
-	int a_bus_req;
-	int a_clr_err;
-	int a_suspend_req;
-	int b_bus_req;
-
-	/* Output */
-	int drv_vbus;
-	int loc_conn;
-	int loc_sof;
-
-	/* Others */
-	int b_bus_suspend_vld;
-	int vbus_srp_up;
-};
-
 enum langwell_otg_timer_type {
 	TA_WAIT_VRISE_TMR,
 	TA_WAIT_BCON_TMR,
@@ -170,25 +112,26 @@ struct langwell_otg_timer {
 };
 
 struct langwell_otg {
-	struct otg_transceiver	otg;
-	struct otg_hsm		hsm;
-	void __iomem		*regs;
-	void __iomem		*usbcfg;	/* SCCB USB config Reg */
-	unsigned		region;
-	unsigned		cfg_region;
-	struct pci_driver	*host_ops;
-	struct pci_driver	*client_ops;
-	struct pci_dev		*pdev;
-	struct work_struct	work;
-	struct workqueue_struct	*qwork;
-	struct timer_list	hsm_timer;
-	spinlock_t		lock;
-	spinlock_t		wq_lock;
+	struct intel_mid_otg_xceiv	iotg;
+	struct device			*dev;
+
+	void __iomem			*usbcfg;	/* SCCBUSB config Reg */
+
+	unsigned			region;
+	unsigned			cfg_region;
+
+	struct work_struct		work;
+	struct workqueue_struct		*qwork;
+	struct timer_list		hsm_timer;
+
+	spinlock_t			lock;
+	spinlock_t			wq_lock;
 };
 
-static inline struct langwell_otg *otg_to_langwell(struct otg_transceiver *otg)
+static inline
+struct langwell_otg *mid_xceiv_to_lnw(struct intel_mid_otg_xceiv *iotg)
 {
-	return container_of(otg, struct langwell_otg, otg);
+	return container_of(iotg, struct langwell_otg, iotg);
 }
 
 #endif /* __LANGWELL_OTG_H__ */

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux