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

Commit 84e250ff authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman
Browse files

musb: proper hookup to transceiver drivers



Let the otg_transceiver in MUSB be managed by an external driver;
don't assume it's integrated.  OMAP3 chips need it to be external,
and there may be ways to interact with the transceiver which add
functionality to the system.

Platform init code is responsible for setting up the transeciver,
probably using the NOP transceiver for integrated transceivers.
External ones will use whatever the board init code provided,
such as twl4030 or something more hands-off.

Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent cc835e32
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -10,6 +10,7 @@ comment "Enable Host or Gadget support to see Inventra options"
config USB_MUSB_HDRC
config USB_MUSB_HDRC
	depends on (USB || USB_GADGET) && HAVE_CLK
	depends on (USB || USB_GADGET) && HAVE_CLK
	depends on !SUPERH
	depends on !SUPERH
	select NOP_USB_XCEIV if ARCH_DAVINCI
	select TWL4030_USB if MACH_OMAP_3430SDP
	select TWL4030_USB if MACH_OMAP_3430SDP
	select USB_OTG_UTILS
	select USB_OTG_UTILS
	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
@@ -55,6 +56,7 @@ comment "Blackfin high speed USB Support"
config USB_TUSB6010
config USB_TUSB6010
	boolean "TUSB 6010 support"
	boolean "TUSB 6010 support"
	depends on USB_MUSB_HDRC && !USB_MUSB_SOC
	depends on USB_MUSB_HDRC && !USB_MUSB_SOC
	select NOP_USB_XCEIV
	default y
	default y
	help
	help
	  The TUSB 6010 chip, from Texas Instruments, connects a discrete
	  The TUSB 6010 chip, from Texas Instruments, connects a discrete
+8 −3
Original line number Original line Diff line number Diff line
@@ -143,7 +143,7 @@ static void musb_conn_timer_handler(unsigned long _musb)
	u16 val;
	u16 val;


	spin_lock_irqsave(&musb->lock, flags);
	spin_lock_irqsave(&musb->lock, flags);
	switch (musb->xceiv.state) {
	switch (musb->xceiv->state) {
	case OTG_STATE_A_IDLE:
	case OTG_STATE_A_IDLE:
	case OTG_STATE_A_WAIT_BCON:
	case OTG_STATE_A_WAIT_BCON:
		/* Start a new session */
		/* Start a new session */
@@ -154,7 +154,7 @@ static void musb_conn_timer_handler(unsigned long _musb)
		val = musb_readw(musb->mregs, MUSB_DEVCTL);
		val = musb_readw(musb->mregs, MUSB_DEVCTL);
		if (!(val & MUSB_DEVCTL_BDEVICE)) {
		if (!(val & MUSB_DEVCTL_BDEVICE)) {
			gpio_set_value(musb->config->gpio_vrsel, 1);
			gpio_set_value(musb->config->gpio_vrsel, 1);
			musb->xceiv.state = OTG_STATE_A_WAIT_BCON;
			musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
		} else {
		} else {
			gpio_set_value(musb->config->gpio_vrsel, 0);
			gpio_set_value(musb->config->gpio_vrsel, 0);


@@ -247,6 +247,11 @@ int __init musb_platform_init(struct musb *musb)
	}
	}
	gpio_direction_output(musb->config->gpio_vrsel, 0);
	gpio_direction_output(musb->config->gpio_vrsel, 0);


	usb_nop_xceiv_register();
	musb->xceiv = otg_get_transceiver();
	if (!musb->xceiv)
		return -ENODEV;

	if (ANOMALY_05000346) {
	if (ANOMALY_05000346) {
		bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
		bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
		SSYNC();
		SSYNC();
@@ -291,7 +296,7 @@ int __init musb_platform_init(struct musb *musb)
			musb_conn_timer_handler, (unsigned long) musb);
			musb_conn_timer_handler, (unsigned long) musb);
	}
	}
	if (is_peripheral_enabled(musb))
	if (is_peripheral_enabled(musb))
		musb->xceiv.set_power = bfin_set_power;
		musb->xceiv->set_power = bfin_set_power;


	musb->isr = blackfin_interrupt;
	musb->isr = blackfin_interrupt;


+22 −11
Original line number Original line Diff line number Diff line
@@ -215,7 +215,7 @@ static void otg_timer(unsigned long _musb)
	DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb));
	DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb));


	spin_lock_irqsave(&musb->lock, flags);
	spin_lock_irqsave(&musb->lock, flags);
	switch (musb->xceiv.state) {
	switch (musb->xceiv->state) {
	case OTG_STATE_A_WAIT_VFALL:
	case OTG_STATE_A_WAIT_VFALL:
		/* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL
		/* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL
		 * seems to mis-handle session "start" otherwise (or in our
		 * seems to mis-handle session "start" otherwise (or in our
@@ -226,7 +226,7 @@ static void otg_timer(unsigned long _musb)
			mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
			mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
			break;
			break;
		}
		}
		musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
		musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
		musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
		musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
			MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT);
			MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT);
		break;
		break;
@@ -251,7 +251,7 @@ static void otg_timer(unsigned long _musb)
		if (devctl & MUSB_DEVCTL_BDEVICE)
		if (devctl & MUSB_DEVCTL_BDEVICE)
			mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
			mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
		else
		else
			musb->xceiv.state = OTG_STATE_A_IDLE;
			musb->xceiv->state = OTG_STATE_A_IDLE;
		break;
		break;
	default:
	default:
		break;
		break;
@@ -325,21 +325,21 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
			 * to stop registering in devctl.
			 * to stop registering in devctl.
			 */
			 */
			musb->int_usb &= ~MUSB_INTR_VBUSERROR;
			musb->int_usb &= ~MUSB_INTR_VBUSERROR;
			musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
			musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
			mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
			mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
			WARNING("VBUS error workaround (delay coming)\n");
			WARNING("VBUS error workaround (delay coming)\n");
		} else if (is_host_enabled(musb) && drvvbus) {
		} else if (is_host_enabled(musb) && drvvbus) {
			musb->is_active = 1;
			musb->is_active = 1;
			MUSB_HST_MODE(musb);
			MUSB_HST_MODE(musb);
			musb->xceiv.default_a = 1;
			musb->xceiv->default_a = 1;
			musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
			musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
			portstate(musb->port1_status |= USB_PORT_STAT_POWER);
			portstate(musb->port1_status |= USB_PORT_STAT_POWER);
			del_timer(&otg_workaround);
			del_timer(&otg_workaround);
		} else {
		} else {
			musb->is_active = 0;
			musb->is_active = 0;
			MUSB_DEV_MODE(musb);
			MUSB_DEV_MODE(musb);
			musb->xceiv.default_a = 0;
			musb->xceiv->default_a = 0;
			musb->xceiv.state = OTG_STATE_B_IDLE;
			musb->xceiv->state = OTG_STATE_B_IDLE;
			portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
			portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
		}
		}


@@ -361,7 +361,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)


	/* poll for ID change */
	/* poll for ID change */
	if (is_otg_enabled(musb)
	if (is_otg_enabled(musb)
			&& musb->xceiv.state == OTG_STATE_B_IDLE)
			&& musb->xceiv->state == OTG_STATE_B_IDLE)
		mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
		mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);


	spin_unlock_irqrestore(&musb->lock, flags);
	spin_unlock_irqrestore(&musb->lock, flags);
@@ -380,6 +380,11 @@ int __init musb_platform_init(struct musb *musb)
	void __iomem	*tibase = musb->ctrl_base;
	void __iomem	*tibase = musb->ctrl_base;
	u32		revision;
	u32		revision;


	usb_nop_xceiv_register();
	musb->xceiv = otg_get_transceiver();
	if (!musb->xceiv)
		return -ENODEV;

	musb->mregs += DAVINCI_BASE_OFFSET;
	musb->mregs += DAVINCI_BASE_OFFSET;


	clk_enable(musb->clock);
	clk_enable(musb->clock);
@@ -387,7 +392,7 @@ int __init musb_platform_init(struct musb *musb)
	/* returns zero if e.g. not clocked */
	/* returns zero if e.g. not clocked */
	revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
	revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
	if (revision == 0)
	if (revision == 0)
		return -ENODEV;
		goto fail;


	if (is_host_enabled(musb))
	if (is_host_enabled(musb))
		setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
		setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
@@ -421,6 +426,10 @@ int __init musb_platform_init(struct musb *musb)


	musb->isr = davinci_interrupt;
	musb->isr = davinci_interrupt;
	return 0;
	return 0;

fail:
	usb_nop_xceiv_unregister();
	return -ENODEV;
}
}


int musb_platform_exit(struct musb *musb)
int musb_platform_exit(struct musb *musb)
@@ -431,7 +440,7 @@ int musb_platform_exit(struct musb *musb)
	davinci_source_power(musb, 0 /*off*/, 1);
	davinci_source_power(musb, 0 /*off*/, 1);


	/* delay, to avoid problems with module reload */
	/* delay, to avoid problems with module reload */
	if (is_host_enabled(musb) && musb->xceiv.default_a) {
	if (is_host_enabled(musb) && musb->xceiv->default_a) {
		int	maxdelay = 30;
		int	maxdelay = 30;
		u8	devctl, warn = 0;
		u8	devctl, warn = 0;


@@ -460,5 +469,7 @@ int musb_platform_exit(struct musb *musb)


	clk_disable(musb->clock);
	clk_disable(musb->clock);


	usb_nop_xceiv_unregister();

	return 0;
	return 0;
}
}
+52 −44
Original line number Original line Diff line number Diff line
@@ -267,7 +267,7 @@ void musb_load_testpacket(struct musb *musb)


const char *otg_state_string(struct musb *musb)
const char *otg_state_string(struct musb *musb)
{
{
	switch (musb->xceiv.state) {
	switch (musb->xceiv->state) {
	case OTG_STATE_A_IDLE:		return "a_idle";
	case OTG_STATE_A_IDLE:		return "a_idle";
	case OTG_STATE_A_WAIT_VRISE:	return "a_wait_vrise";
	case OTG_STATE_A_WAIT_VRISE:	return "a_wait_vrise";
	case OTG_STATE_A_WAIT_BCON:	return "a_wait_bcon";
	case OTG_STATE_A_WAIT_BCON:	return "a_wait_bcon";
@@ -302,11 +302,11 @@ void musb_otg_timer_func(unsigned long data)
	unsigned long	flags;
	unsigned long	flags;


	spin_lock_irqsave(&musb->lock, flags);
	spin_lock_irqsave(&musb->lock, flags);
	switch (musb->xceiv.state) {
	switch (musb->xceiv->state) {
	case OTG_STATE_B_WAIT_ACON:
	case OTG_STATE_B_WAIT_ACON:
		DBG(1, "HNP: b_wait_acon timeout; back to b_peripheral\n");
		DBG(1, "HNP: b_wait_acon timeout; back to b_peripheral\n");
		musb_g_disconnect(musb);
		musb_g_disconnect(musb);
		musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
		musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
		musb->is_active = 0;
		musb->is_active = 0;
		break;
		break;
	case OTG_STATE_A_WAIT_BCON:
	case OTG_STATE_A_WAIT_BCON:
@@ -331,20 +331,20 @@ void musb_hnp_stop(struct musb *musb)
	void __iomem	*mbase = musb->mregs;
	void __iomem	*mbase = musb->mregs;
	u8	reg;
	u8	reg;


	switch (musb->xceiv.state) {
	switch (musb->xceiv->state) {
	case OTG_STATE_A_PERIPHERAL:
	case OTG_STATE_A_PERIPHERAL:
	case OTG_STATE_A_WAIT_VFALL:
	case OTG_STATE_A_WAIT_VFALL:
	case OTG_STATE_A_WAIT_BCON:
	case OTG_STATE_A_WAIT_BCON:
		DBG(1, "HNP: Switching back to A-host\n");
		DBG(1, "HNP: Switching back to A-host\n");
		musb_g_disconnect(musb);
		musb_g_disconnect(musb);
		musb->xceiv.state = OTG_STATE_A_IDLE;
		musb->xceiv->state = OTG_STATE_A_IDLE;
		MUSB_HST_MODE(musb);
		MUSB_HST_MODE(musb);
		musb->is_active = 0;
		musb->is_active = 0;
		break;
		break;
	case OTG_STATE_B_HOST:
	case OTG_STATE_B_HOST:
		DBG(1, "HNP: Disabling HR\n");
		DBG(1, "HNP: Disabling HR\n");
		hcd->self.is_b_host = 0;
		hcd->self.is_b_host = 0;
		musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
		musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
		MUSB_DEV_MODE(musb);
		MUSB_DEV_MODE(musb);
		reg = musb_readb(mbase, MUSB_POWER);
		reg = musb_readb(mbase, MUSB_POWER);
		reg |= MUSB_POWER_SUSPENDM;
		reg |= MUSB_POWER_SUSPENDM;
@@ -402,7 +402,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,


		if (devctl & MUSB_DEVCTL_HM) {
		if (devctl & MUSB_DEVCTL_HM) {
#ifdef CONFIG_USB_MUSB_HDRC_HCD
#ifdef CONFIG_USB_MUSB_HDRC_HCD
			switch (musb->xceiv.state) {
			switch (musb->xceiv->state) {
			case OTG_STATE_A_SUSPEND:
			case OTG_STATE_A_SUSPEND:
				/* remote wakeup?  later, GetPortStatus
				/* remote wakeup?  later, GetPortStatus
				 * will stop RESUME signaling
				 * will stop RESUME signaling
@@ -425,12 +425,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
				musb->rh_timer = jiffies
				musb->rh_timer = jiffies
						+ msecs_to_jiffies(20);
						+ msecs_to_jiffies(20);


				musb->xceiv.state = OTG_STATE_A_HOST;
				musb->xceiv->state = OTG_STATE_A_HOST;
				musb->is_active = 1;
				musb->is_active = 1;
				usb_hcd_resume_root_hub(musb_to_hcd(musb));
				usb_hcd_resume_root_hub(musb_to_hcd(musb));
				break;
				break;
			case OTG_STATE_B_WAIT_ACON:
			case OTG_STATE_B_WAIT_ACON:
				musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
				musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
				musb->is_active = 1;
				musb->is_active = 1;
				MUSB_DEV_MODE(musb);
				MUSB_DEV_MODE(musb);
				break;
				break;
@@ -441,11 +441,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
			}
			}
#endif
#endif
		} else {
		} else {
			switch (musb->xceiv.state) {
			switch (musb->xceiv->state) {
#ifdef CONFIG_USB_MUSB_HDRC_HCD
#ifdef CONFIG_USB_MUSB_HDRC_HCD
			case OTG_STATE_A_SUSPEND:
			case OTG_STATE_A_SUSPEND:
				/* possibly DISCONNECT is upcoming */
				/* possibly DISCONNECT is upcoming */
				musb->xceiv.state = OTG_STATE_A_HOST;
				musb->xceiv->state = OTG_STATE_A_HOST;
				usb_hcd_resume_root_hub(musb_to_hcd(musb));
				usb_hcd_resume_root_hub(musb_to_hcd(musb));
				break;
				break;
#endif
#endif
@@ -490,7 +490,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
		 */
		 */
		musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
		musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
		musb->ep0_stage = MUSB_EP0_START;
		musb->ep0_stage = MUSB_EP0_START;
		musb->xceiv.state = OTG_STATE_A_IDLE;
		musb->xceiv->state = OTG_STATE_A_IDLE;
		MUSB_HST_MODE(musb);
		MUSB_HST_MODE(musb);
		musb_set_vbus(musb, 1);
		musb_set_vbus(musb, 1);


@@ -516,7 +516,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
		 * REVISIT:  do delays from lots of DEBUG_KERNEL checks
		 * REVISIT:  do delays from lots of DEBUG_KERNEL checks
		 * make trouble here, keeping VBUS < 4.4V ?
		 * make trouble here, keeping VBUS < 4.4V ?
		 */
		 */
		switch (musb->xceiv.state) {
		switch (musb->xceiv->state) {
		case OTG_STATE_A_HOST:
		case OTG_STATE_A_HOST:
			/* recovery is dicey once we've gotten past the
			/* recovery is dicey once we've gotten past the
			 * initial stages of enumeration, but if VBUS
			 * initial stages of enumeration, but if VBUS
@@ -602,11 +602,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
		MUSB_HST_MODE(musb);
		MUSB_HST_MODE(musb);


		/* indicate new connection to OTG machine */
		/* indicate new connection to OTG machine */
		switch (musb->xceiv.state) {
		switch (musb->xceiv->state) {
		case OTG_STATE_B_PERIPHERAL:
		case OTG_STATE_B_PERIPHERAL:
			if (int_usb & MUSB_INTR_SUSPEND) {
			if (int_usb & MUSB_INTR_SUSPEND) {
				DBG(1, "HNP: SUSPEND+CONNECT, now b_host\n");
				DBG(1, "HNP: SUSPEND+CONNECT, now b_host\n");
				musb->xceiv.state = OTG_STATE_B_HOST;
				musb->xceiv->state = OTG_STATE_B_HOST;
				hcd->self.is_b_host = 1;
				hcd->self.is_b_host = 1;
				int_usb &= ~MUSB_INTR_SUSPEND;
				int_usb &= ~MUSB_INTR_SUSPEND;
			} else
			} else
@@ -614,13 +614,13 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
			break;
			break;
		case OTG_STATE_B_WAIT_ACON:
		case OTG_STATE_B_WAIT_ACON:
			DBG(1, "HNP: Waiting to switch to b_host state\n");
			DBG(1, "HNP: Waiting to switch to b_host state\n");
			musb->xceiv.state = OTG_STATE_B_HOST;
			musb->xceiv->state = OTG_STATE_B_HOST;
			hcd->self.is_b_host = 1;
			hcd->self.is_b_host = 1;
			break;
			break;
		default:
		default:
			if ((devctl & MUSB_DEVCTL_VBUS)
			if ((devctl & MUSB_DEVCTL_VBUS)
					== (3 << MUSB_DEVCTL_VBUS_SHIFT)) {
					== (3 << MUSB_DEVCTL_VBUS_SHIFT)) {
				musb->xceiv.state = OTG_STATE_A_HOST;
				musb->xceiv->state = OTG_STATE_A_HOST;
				hcd->self.is_b_host = 0;
				hcd->self.is_b_host = 0;
			}
			}
			break;
			break;
@@ -650,7 +650,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
			}
			}
		} else if (is_peripheral_capable()) {
		} else if (is_peripheral_capable()) {
			DBG(1, "BUS RESET as %s\n", otg_state_string(musb));
			DBG(1, "BUS RESET as %s\n", otg_state_string(musb));
			switch (musb->xceiv.state) {
			switch (musb->xceiv->state) {
#ifdef CONFIG_USB_OTG
#ifdef CONFIG_USB_OTG
			case OTG_STATE_A_SUSPEND:
			case OTG_STATE_A_SUSPEND:
				/* We need to ignore disconnect on suspend
				/* We need to ignore disconnect on suspend
@@ -673,12 +673,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
			case OTG_STATE_B_WAIT_ACON:
			case OTG_STATE_B_WAIT_ACON:
				DBG(1, "HNP: RESET (%s), to b_peripheral\n",
				DBG(1, "HNP: RESET (%s), to b_peripheral\n",
					otg_state_string(musb));
					otg_state_string(musb));
				musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
				musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
				musb_g_reset(musb);
				musb_g_reset(musb);
				break;
				break;
#endif
#endif
			case OTG_STATE_B_IDLE:
			case OTG_STATE_B_IDLE:
				musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
				musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
				/* FALLTHROUGH */
				/* FALLTHROUGH */
			case OTG_STATE_B_PERIPHERAL:
			case OTG_STATE_B_PERIPHERAL:
				musb_g_reset(musb);
				musb_g_reset(musb);
@@ -763,7 +763,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
				MUSB_MODE(musb), devctl);
				MUSB_MODE(musb), devctl);
		handled = IRQ_HANDLED;
		handled = IRQ_HANDLED;


		switch (musb->xceiv.state) {
		switch (musb->xceiv->state) {
#ifdef CONFIG_USB_MUSB_HDRC_HCD
#ifdef CONFIG_USB_MUSB_HDRC_HCD
		case OTG_STATE_A_HOST:
		case OTG_STATE_A_HOST:
		case OTG_STATE_A_SUSPEND:
		case OTG_STATE_A_SUSPEND:
@@ -805,7 +805,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
				otg_state_string(musb), devctl, power);
				otg_state_string(musb), devctl, power);
		handled = IRQ_HANDLED;
		handled = IRQ_HANDLED;


		switch (musb->xceiv.state) {
		switch (musb->xceiv->state) {
#ifdef	CONFIG_USB_MUSB_OTG
#ifdef	CONFIG_USB_MUSB_OTG
		case OTG_STATE_A_PERIPHERAL:
		case OTG_STATE_A_PERIPHERAL:
			/*
			/*
@@ -817,10 +817,10 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
		case OTG_STATE_B_PERIPHERAL:
		case OTG_STATE_B_PERIPHERAL:
			musb_g_suspend(musb);
			musb_g_suspend(musb);
			musb->is_active = is_otg_enabled(musb)
			musb->is_active = is_otg_enabled(musb)
					&& musb->xceiv.gadget->b_hnp_enable;
					&& musb->xceiv->gadget->b_hnp_enable;
			if (musb->is_active) {
			if (musb->is_active) {
#ifdef	CONFIG_USB_MUSB_OTG
#ifdef	CONFIG_USB_MUSB_OTG
				musb->xceiv.state = OTG_STATE_B_WAIT_ACON;
				musb->xceiv->state = OTG_STATE_B_WAIT_ACON;
				DBG(1, "HNP: Setting timer for b_ase0_brst\n");
				DBG(1, "HNP: Setting timer for b_ase0_brst\n");
				musb_otg_timer.data = (unsigned long)musb;
				musb_otg_timer.data = (unsigned long)musb;
				mod_timer(&musb_otg_timer, jiffies
				mod_timer(&musb_otg_timer, jiffies
@@ -834,9 +834,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
					+ msecs_to_jiffies(musb->a_wait_bcon));
					+ msecs_to_jiffies(musb->a_wait_bcon));
			break;
			break;
		case OTG_STATE_A_HOST:
		case OTG_STATE_A_HOST:
			musb->xceiv.state = OTG_STATE_A_SUSPEND;
			musb->xceiv->state = OTG_STATE_A_SUSPEND;
			musb->is_active = is_otg_enabled(musb)
			musb->is_active = is_otg_enabled(musb)
					&& musb->xceiv.host->b_hnp_enable;
					&& musb->xceiv->host->b_hnp_enable;
			break;
			break;
		case OTG_STATE_B_HOST:
		case OTG_STATE_B_HOST:
			/* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
			/* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
@@ -1682,7 +1682,7 @@ musb_vbus_store(struct device *dev, struct device_attribute *attr,


	spin_lock_irqsave(&musb->lock, flags);
	spin_lock_irqsave(&musb->lock, flags);
	musb->a_wait_bcon = val;
	musb->a_wait_bcon = val;
	if (musb->xceiv.state == OTG_STATE_A_WAIT_BCON)
	if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON)
		musb->is_active = 0;
		musb->is_active = 0;
	musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val));
	musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val));
	spin_unlock_irqrestore(&musb->lock, flags);
	spin_unlock_irqrestore(&musb->lock, flags);
@@ -1743,8 +1743,8 @@ static void musb_irq_work(struct work_struct *data)
	struct musb *musb = container_of(data, struct musb, irq_work);
	struct musb *musb = container_of(data, struct musb, irq_work);
	static int old_state;
	static int old_state;


	if (musb->xceiv.state != old_state) {
	if (musb->xceiv->state != old_state) {
		old_state = musb->xceiv.state;
		old_state = musb->xceiv->state;
		sysfs_notify(&musb->controller->kobj, NULL, "mode");
		sysfs_notify(&musb->controller->kobj, NULL, "mode");
	}
	}
}
}
@@ -1841,7 +1841,7 @@ static void musb_free(struct musb *musb)
	}
	}


#ifdef CONFIG_USB_MUSB_OTG
#ifdef CONFIG_USB_MUSB_OTG
	put_device(musb->xceiv.dev);
	put_device(musb->xceiv->dev);
#endif
#endif


#ifdef CONFIG_USB_MUSB_HDRC_HCD
#ifdef CONFIG_USB_MUSB_HDRC_HCD
@@ -1922,10 +1922,18 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
		}
		}
	}
	}


	/* assume vbus is off */
	/* The musb_platform_init() call:

	 *   - adjusts musb->mregs and musb->isr if needed,
	/* platform adjusts musb->mregs and musb->isr if needed,
	 *   - may initialize an integrated tranceiver
	 * and activates clocks
	 *   - initializes musb->xceiv, usually by otg_get_transceiver()
	 *   - activates clocks.
	 *   - stops powering VBUS
	 *   - assigns musb->board_set_vbus if host mode is enabled
	 *
	 * There are various transciever configurations.  Blackfin,
	 * DaVinci, TUSB60x0, and others integrate them.  OMAP3 uses
	 * external/discrete ones in various flavors (twl4030 family,
	 * isp1504, non-OTG, etc) mostly hooking up through ULPI.
	 */
	 */
	musb->isr = generic_interrupt;
	musb->isr = generic_interrupt;
	status = musb_platform_init(musb);
	status = musb_platform_init(musb);
@@ -1993,17 +2001,17 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
				? "DMA" : "PIO",
				? "DMA" : "PIO",
			musb->nIrq);
			musb->nIrq);


#ifdef CONFIG_USB_MUSB_HDRC_HCD
	/* host side needs more setup */
	/* host side needs more setup, except for no-host modes */
	if (is_host_enabled(musb)) {
	if (musb->board_mode != MUSB_PERIPHERAL) {
		struct usb_hcd	*hcd = musb_to_hcd(musb);
		struct usb_hcd	*hcd = musb_to_hcd(musb);


		if (musb->board_mode == MUSB_OTG)
		otg_set_host(musb->xceiv, &hcd->self);

		if (is_otg_enabled(musb))
			hcd->self.otg_port = 1;
			hcd->self.otg_port = 1;
		musb->xceiv.host = &hcd->self;
		musb->xceiv->host = &hcd->self;
		hcd->power_budget = 2 * (plat->power ? : 250);
		hcd->power_budget = 2 * (plat->power ? : 250);
	}
	}
#endif				/* CONFIG_USB_MUSB_HDRC_HCD */


	/* For the host-only role, we can activate right away.
	/* For the host-only role, we can activate right away.
	 * (We expect the ID pin to be forcibly grounded!!)
	 * (We expect the ID pin to be forcibly grounded!!)
@@ -2011,8 +2019,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
	 */
	 */
	if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
	if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
		MUSB_HST_MODE(musb);
		MUSB_HST_MODE(musb);
		musb->xceiv.default_a = 1;
		musb->xceiv->default_a = 1;
		musb->xceiv.state = OTG_STATE_A_IDLE;
		musb->xceiv->state = OTG_STATE_A_IDLE;


		status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
		status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
		if (status)
		if (status)
@@ -2027,8 +2035,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)


	} else /* peripheral is enabled */ {
	} else /* peripheral is enabled */ {
		MUSB_DEV_MODE(musb);
		MUSB_DEV_MODE(musb);
		musb->xceiv.default_a = 0;
		musb->xceiv->default_a = 0;
		musb->xceiv.state = OTG_STATE_B_IDLE;
		musb->xceiv->state = OTG_STATE_B_IDLE;


		status = musb_gadget_setup(musb);
		status = musb_gadget_setup(musb);
		if (status)
		if (status)
+1 −1
Original line number Original line Diff line number Diff line
@@ -356,7 +356,7 @@ struct musb {
	u16			int_rx;
	u16			int_rx;
	u16			int_tx;
	u16			int_tx;


	struct otg_transceiver	xceiv;
	struct otg_transceiver	*xceiv;


	int nIrq;
	int nIrq;
	unsigned		irq_wake:1;
	unsigned		irq_wake:1;
Loading