diff mbox

[RFC] Move SoC and board specific code from USB DaVinci driver to the corresponding files

Message ID 1253116510-9523-1-git-send-email-miguel.aguilar@ridgerun.com (mailing list archive)
State RFC
Headers show

Commit Message

miguel.aguilar@ridgerun.com Sept. 16, 2009, 3:55 p.m. UTC
From: Miguel Aguilar <miguel.aguilar@ridgerun.com>

Swami,

I would like to share this patch with you, it could be useful for you.

This patch moves al the SoC and board specific stuff from the USB DaVinci Driver
to the corresponding SoC and board files.

The idea is that each board file provides a set_vbus function depending on
how each board handles it by using the musb platform data.

This patch was tested on DM355 EVM and Leopard Board, and DM365 EVM. On
the DM6446 this is not tested yet.

Signed-off-by: Miguel Aguilar <miguel.aguilar@ridgerun.com>
---
 arch/arm/mach-davinci/board-dm355-evm.c     |   35 +++++++-
 arch/arm/mach-davinci/board-dm355-leopard.c |   23 +++++-
 arch/arm/mach-davinci/board-dm365-evm.c     |   38 +++++++++-
 arch/arm/mach-davinci/board-dm644x-evm.c    |   61 ++++++++++++++-
 arch/arm/mach-davinci/board-sffsdr.c        |    4 +-
 arch/arm/mach-davinci/dm355.c               |   20 +++++
 arch/arm/mach-davinci/dm365.c               |    2 +-
 arch/arm/mach-davinci/include/mach/common.h |   23 +++++-
 arch/arm/mach-davinci/include/mach/dm355.h  |    1 +
 arch/arm/mach-davinci/usb.c                 |   11 ++-
 drivers/usb/musb/Kconfig                    |    4 +-
 drivers/usb/musb/davinci.c                  |  110 ++-------------------------
 drivers/usb/musb/davinci.h                  |    5 +-
 drivers/usb/musb/musb_core.c                |    1 +
 include/linux/usb/musb.h                    |    9 ++-
 15 files changed, 212 insertions(+), 135 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 9f25fd8..a06fcdb 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -229,6 +229,34 @@  static struct davinci_mmc_config dm355evm_mmc_config = {
 #define USB_ID_VALUE	1	/* ID pulled low */
 #endif
 
+struct musb_hdrc_platform_data dm355evm_usb_data;
+
+static void dm355evm_usb_configure(void)
+{
+	/*
+	 * DM355 EVM swaps D+/D- for signal integrity, and
+	 * is clocked from the main 24 MHz crystal.
+	 */
+	u32	phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+	phy_ctrl &= ~(3 << 9);
+	phy_ctrl |= USBPHY_DATAPOL;
+	__raw_writel(phy_ctrl, USB_PHY_CTRL);
+
+	/* DM355 SoC configuration */
+	dm355_init_usb();
+
+	/* 
+	 * Set the gpio 2 as output to toggle the USB ID
+	 * according the USB mode host or gadget
+	 */
+	gpio_request(2, "usb_id_toggle");
+	gpio_direction_output(2, USB_ID_VALUE);
+
+	/* irlml6401 switches over 1A in under 8 msec */
+	setup_usb(500, 8, &dm355evm_usb_data);
+}
+
 static struct spi_eeprom at25640a = {
 	.byte_len	= SZ_64K / 8,
 	.name		= "at25640a",
@@ -271,14 +299,11 @@  static __init void dm355_evm_init(void)
 	 * but could be 0x0400008c for about 25% faster page reads.
 	 */
 
-	gpio_request(2, "usb_id_toggle");
-	gpio_direction_output(2, USB_ID_VALUE);
-	/* irlml6401 switches over 1A in under 8 msec */
-	setup_usb(500, 8);
-
 	davinci_setup_mmc(0, &dm355evm_mmc_config);
 	davinci_setup_mmc(1, &dm355evm_mmc_config);
 
+	dm355evm_usb_configure();
+
 	dm355_init_spi0(BIT(0), dm355_evm_spi_info,
 			ARRAY_SIZE(dm355_evm_spi_info));
 
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index 84ad5d1..4b3042f 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -225,6 +225,24 @@  static struct davinci_mmc_config dm355leopard_mmc_config = {
 #define USB_ID_VALUE	1	/* ID pulled low */
 #endif
 
+struct musb_hdrc_platform_data dm355leopard_usb_data;
+
+static void dm355leopard_usb_configure(void)
+{
+	/* DM355 SoC configuration */
+	dm355_init_usb();
+
+	/* 
+	 * Set the gpio 2 as output to toggle the USB ID
+	 * according the USB mode host or gadget
+	 */
+	gpio_request(2, "usb_id_toggle");
+	gpio_direction_output(2, USB_ID_VALUE);
+
+	/* irlml6401 switches over 1A in under 8 msec */
+	setup_usb(500, 8, &dm355leopard_usb_data);
+}
+
 static struct spi_eeprom at25640a = {
 	.byte_len	= SZ_64K / 8,
 	.name		= "at25640a",
@@ -267,10 +285,7 @@  static __init void dm355_leopard_init(void)
 	 * but could be 0x0400008c for about 25% faster page reads.
 	 */
 
-	gpio_request(2, "usb_id_toggle");
-	gpio_direction_output(2, USB_ID_VALUE);
-	/* irlml6401 switches over 1A in under 8 msec */
-	setup_usb(500, 8);
+	dm355leopard_usb_configure();
 
 	davinci_setup_mmc(0, &dm355leopard_mmc_config);
 	davinci_setup_mmc(1, &dm355leopard_mmc_config);
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index f6adf79..327b681 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -24,6 +24,7 @@ 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
+#include <linux/usb/musb.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -38,7 +39,7 @@ 
 #include <mach/common.h>
 #include <mach/mmc.h>
 #include <mach/nand.h>
-
+#include <mach/gpio.h>
 
 static inline int have_imager(void)
 {
@@ -52,7 +53,6 @@  static inline int have_tvp7002(void)
 	return 0;
 }
 
-
 #define DM365_ASYNC_EMIF_CONTROL_BASE	0x01d10000
 #define DM365_ASYNC_EMIF_DATA_CE0_BASE	0x02000000
 #define DM365_ASYNC_EMIF_DATA_CE1_BASE	0x04000000
@@ -270,6 +270,39 @@  static void dm365evm_mmc_configure(void)
 	davinci_cfg_reg(DM365_SD1_DATA0);
 }
 
+static void dm365evm_set_vbus(struct musb * musb, int is_on)
+{
+	u32 state;
+
+	if((is_on == VBUS_ON) || (is_on == VBUS_ON_INMEDIATE))
+		state = 1;
+	else
+		state = 0;
+
+	gpio_set_value(33, state);
+}
+
+struct musb_hdrc_platform_data dm365evm_usb_data = {
+	.set_vbus	= &dm365evm_set_vbus,
+};
+
+static void dm365evm_usb_configure(void)
+{
+	/* DM365 EVM uses the main clock of 24MHz */
+	u32 phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+	phy_ctrl &= ~(3 << 12);
+	phy_ctrl |= USBPHY_CLKFREQ_24MHZ;
+	__raw_writel(phy_ctrl, USB_PHY_CTRL);
+
+	/* Setup the gpio used to turn on/off the VBUS */
+	davinci_cfg_reg(DM365_GPIO33);
+	gpio_request(33, "usb");
+	gpio_direction_output(33, 1);
+
+	setup_usb(500, 8, &dm365evm_usb_data);
+}
+
 static void __init evm_init_i2c(void)
 {
 	davinci_init_i2c(&i2c_pdata);
@@ -471,6 +504,7 @@  static __init void dm365_evm_init(void)
 
 	dm365evm_emac_configure();
 	dm365evm_mmc_configure();
+	dm365evm_usb_configure();
 
 	davinci_setup_mmc(0, &dm365evm_mmc_config);
 
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 31cf84f..61ccf20 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -28,6 +28,7 @@ 
 #include <linux/io.h>
 #include <linux/phy.h>
 #include <linux/clk.h>
+#include <linux/usb/musb.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -49,6 +50,8 @@ 
 #define DM644X_EVM_PHY_MASK		(0x2)
 #define DM644X_EVM_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
 
+#define GPIO_nVBUS_DRV		144
+
 #define DAVINCI_CFC_ATA_BASE		  0x01C66000
 
 #define DAVINCI_ASYNC_EMIF_CONTROL_BASE   0x01e00000
@@ -369,7 +372,6 @@  static struct pcf857x_platform_data pcf_data_u18 = {
 	.teardown	= evm_u18_teardown,
 };
 
-
 /* U35 - various I/O signals used to manage USB, CF, ATA, etc */
 
 static int
@@ -405,12 +407,59 @@  evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
 	gpio_request(gpio + 7, "nCF_SEL");
 	gpio_direction_output(gpio + 7, 1);
 
-	/* irlml6401 switches over 1A, in under 8 msec;
+	return 0;
+}
+
+static int vbus_state = -1;
+
+/* I2C operations are always synchronous, and require a task context.
+ * With unloaded systems, using the shared workqueue seems to suffice
+ * to satisfy the 100msec A_WAIT_VRISE timeout...
+ */
+static void evm_deferred_drvvbus(struct work_struct *ignored)
+{
+	gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
+	vbus_state = !vbus_state;
+}
+
+static void dm6446evm_set_vbus(struct musb *musb, int is_on)
+{
+	int inmediate;
+	static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
+
+	if ((is_on == VBUS_ON_INMEDIATE) || (is_on == VBUS_OFF_INMEDIATE))
+		inmediate = 1;
+
+	if ((is_on == VBUS_OFF) || (is_on == VBUS_OFF_INMEDIATE))
+		is_on = 0;
+	else
+		is_on = 1;
+
+	if (vbus_state == is_on)
+		return;
+
+	vbus_state = !is_on;		/* 0/1 vs "-1 == unknown/init" */
+
+	if (inmediate)
+		gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
+	else
+		schedule_work(&evm_vbus_work);
+
+	if (inmediate)
+		vbus_state = is_on;
+}
+
+static struct musb_hdrc_platform_data dm6446evm_usb_data = {
+	.set_vbus	= &dm6446evm_set_vbus,
+};
+
+static void dm6446evm_usb_configure(void)
+{
+	/*
+	 * irlml6401 switches over 1A, in under 8 msec;
 	 * now it can be managed by nDRV_VBUS ...
 	 */
-	setup_usb(500, 8);
-
-	return 0;
+	setup_usb(500, 8, &dm6446evm_usb_data);
 }
 
 static int
@@ -669,6 +718,8 @@  static __init void davinci_evm_init(void)
 
 	davinci_setup_mmc(0, &dm6446evm_mmc_config);
 
+	dm6446evm_usb_configure();
+
 	davinci_serial_init(&uart_config);
 	dm644x_init_asp(&dm644x_evm_snd_data);
 
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 7acdfd8..71dd26b 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -154,6 +154,8 @@  static void __init davinci_sffsdr_map_io(void)
 	dm644x_init();
 }
 
+struct musb_hdrc_platform_data davinci_sffsdr_usb_data;
+
 static __init void davinci_sffsdr_init(void)
 {
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
@@ -164,7 +166,7 @@  static __init void davinci_sffsdr_init(void)
 	davinci_serial_init(&uart_config);
 	soc_info->emac_pdata->phy_mask = SFFSDR_PHY_MASK;
 	soc_info->emac_pdata->mdio_max_freq = SFFSDR_MDIO_FREQUENCY;
-	setup_usb(0, 0); /* We support only peripheral mode. */
+	setup_usb(0, 0, &davinci_sffsdr_usb_data); /* We support only peripheral mode. */
 
 	/* mux VLYNQ pins */
 	davinci_cfg_reg(DM644X_VLYNQEN);
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 4f42169..fceab24 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -37,6 +37,10 @@ 
 
 #define DM355_UART2_BASE	(IO_PHYS + 0x206000)
 
+#define DM355_DEEPSLEEP		IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x48)
+#define DRVVBUS_FORCE		BIT(2)
+#define DRVVBUS_OVERRIDE	BIT(1)
+
 /*
  * Device specific clocks
  */
@@ -767,6 +771,22 @@  static struct davinci_soc_info davinci_soc_info_dm355 = {
 	.sram_len		= SZ_32K,
 };
 
+void __init dm355_init_usb(void)
+{
+	/* On dm355, the default-A state machine needs DRVVBUS control.
+	 * If we won't be a host, there's no need to turn it on.
+	 */
+	u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
+
+#if defined(CONFIG_USB_MUSB_HOST)
+	deepsleep &= ~DRVVBUS_OVERRIDE;
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+	deepsleep &= ~DRVVBUS_FORCE;
+	deepsleep |= DRVVBUS_OVERRIDE;
+#endif
+	__raw_writel(deepsleep, DM355_DEEPSLEEP);
+}
+
 void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata)
 {
 	/* we don't use ASP1 IRQs, or we'd need to mux them ... */
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index e815174..6c948b1 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -369,7 +369,7 @@  static struct clk timer3_clk = {
 
 static struct clk usb_clk = {
 	.name		= "usb",
-	.parent		= &pll2_sysclk1,
+	.parent		= &pll1_aux_clk,
 	.lpsc		= DAVINCI_LPSC_USB,
 };
 
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 1fd3917..65aad5c 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -12,6 +12,8 @@ 
 #ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
 #define __ARCH_ARM_MACH_DAVINCI_COMMON_H
 
+#include <linux/usb/musb.h>
+
 struct sys_timer;
 
 extern struct sys_timer davinci_timer;
@@ -21,10 +23,23 @@  extern void __iomem *davinci_intc_base;
 extern int davinci_intc_type;
 
 /* parameters describe VBUS sourcing for host mode */
-extern void setup_usb(unsigned mA, unsigned potpgt_msec);
+extern void setup_usb(unsigned mA, unsigned potpgt_msec,
+			struct musb_hdrc_platform_data * board_usb_data);
 
-/* parameters describe VBUS sourcing for host mode */
-extern void setup_usb(unsigned mA, unsigned potpgt_msec);
+/* Integrated highspeed/otg PHY */
+#define USBPHY_CTL_PADDR	(DAVINCI_SYSTEM_MODULE_BASE + 0x34)
+#define USB_PHY_CTRL		IO_ADDRESS(USBPHY_CTL_PADDR)
+#define USBPHY_CLKFREQ_24MHZ	BIT(13)
+#define USBPHY_DATAPOL		BIT(11)	/* (dm355) switch D+/D- */
+#define USBPHY_PHYCLKGD		BIT(8)
+#define USBPHY_SESNDEN		BIT(7)	/* v(sess_end) comparator */
+#define USBPHY_VBDTCTEN		BIT(6)	/* v(bus) comparator */
+#define USBPHY_VBUSSENS		BIT(5)	/* (dm355,ro) is vbus > 0.5V */
+#define USBPHY_PHYPLLON		BIT(4)	/* override pll suspend */
+#define USBPHY_CLKO1SEL		BIT(3)
+#define USBPHY_OSCPDWN		BIT(2)
+#define USBPHY_OTGPDWN		BIT(1)
+#define USBPHY_PHYPDWN		BIT(0)
 
 struct davinci_timer_instance {
 	void __iomem	*base;
diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h
index 03faaef..0959d3d 100644
--- a/arch/arm/mach-davinci/include/mach/dm355.h
+++ b/arch/arm/mach-davinci/include/mach/dm355.h
@@ -23,5 +23,6 @@  void __init dm355_init(void);
 void dm355_init_spi0(unsigned chipselect_mask,
 		struct spi_board_info *info, unsigned len);
 void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
+void __init dm355_init_usb(void);
 
 #endif /* __ASM_ARCH_DM355_H */
diff --git a/arch/arm/mach-davinci/usb.c b/arch/arm/mach-davinci/usb.c
index 06f5593..480653e 100644
--- a/arch/arm/mach-davinci/usb.c
+++ b/arch/arm/mach-davinci/usb.c
@@ -14,6 +14,9 @@ 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 #include <mach/cputype.h>
+#include <mach/gpio.h>
+
+#include <asm/mach-types.h>
 
 #define DAVINCI_USB_OTG_BASE 0x01C64000
 
@@ -77,7 +80,6 @@  static struct platform_device usb_dev = {
 	.name           = "musb_hdrc",
 	.id             = -1,
 	.dev = {
-		.platform_data		= &usb_data,
 		.dma_mask		= &usb_dmamask,
 		.coherent_dma_mask      = DMA_BIT_MASK(32),
 	},
@@ -85,7 +87,8 @@  static struct platform_device usb_dev = {
 	.num_resources  = ARRAY_SIZE(usb_resources),
 };
 
-void __init setup_usb(unsigned mA, unsigned potpgt_msec)
+void __init setup_usb(unsigned mA, unsigned potpgt_msec,
+			struct musb_hdrc_platform_data * board_usb_data)
 {
 	usb_data.power = mA / 2;
 	usb_data.potpgt = potpgt_msec / 2;
@@ -97,6 +100,10 @@  void __init setup_usb(unsigned mA, unsigned potpgt_msec)
 	} else	/* other devices don't have dedicated CPPI IRQ */
 		usb_dev.num_resources = 2;
 
+	/* Setup the plaform data including the board specific structures */
+	usb_data.set_vbus = board_usb_data->set_vbus;
+	usb_dev.dev.platform_data = &usb_data;
+
 	platform_device_register(&usb_dev);
 }
 
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 803adcb..9878a64 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -23,7 +23,7 @@  config USB_MUSB_HDRC
 	  or the USB host role, or both.
 
 	  Texas Instruments familiies using this IP include DaVinci
-	  (35x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010.
+	  (35x, 36x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010.
 
 	  Analog Devices parts using this IP include Blackfin BF54x,
 	  BF525 and BF527.
@@ -42,7 +42,7 @@  config USB_MUSB_SOC
 	default y if (BF54x && !BF544)
 	default y if (BF52x && !BF522 && !BF523)
 
-comment "DaVinci 35x and 644x USB support"
+comment "DaVinci 35x, 36x, 644x USB support"
 	depends on USB_MUSB_HDRC && ARCH_DAVINCI
 
 comment "OMAP 243x high speed USB support"
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index e16ff60..a2b1bbd 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -37,20 +37,12 @@ 
 #include <mach/gpio.h>
 #include <mach/cputype.h>
 
-#include <asm/mach-types.h>
-
 #include "musb_core.h"
 
-#ifdef CONFIG_MACH_DAVINCI_EVM
-#define GPIO_nVBUS_DRV		144
-#endif
-
 #include "davinci.h"
 #include "cppi_dma.h"
 
-
 #define USB_PHY_CTRL	IO_ADDRESS(USBPHY_CTL_PADDR)
-#define DM355_DEEPSLEEP	IO_ADDRESS(DM355_DEEPSLEEP_PADDR)
 
 /* REVISIT (PM) we should be able to keep the PHY in low power mode most
  * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0
@@ -135,69 +127,12 @@  void musb_platform_disable(struct musb *musb)
 		WARNING("dma still active\n");
 }
 
-
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
 #define	portstate(stmt)		stmt
 #else
 #define	portstate(stmt)
 #endif
 
-
-/*
- * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM,
- * which doesn't wire DRVVBUS to the FET that switches it.  Unclear
- * if that's a problem with the DM6446 chip or just with that board.
- *
- * In either case, the DM355 EVM automates DRVVBUS the normal way,
- * when J10 is out, and TI documents it as handling OTG.
- */
-
-#ifdef CONFIG_MACH_DAVINCI_EVM
-
-static int vbus_state = -1;
-
-/* I2C operations are always synchronous, and require a task context.
- * With unloaded systems, using the shared workqueue seems to suffice
- * to satisfy the 100msec A_WAIT_VRISE timeout...
- */
-static void evm_deferred_drvvbus(struct work_struct *ignored)
-{
-	gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
-	vbus_state = !vbus_state;
-}
-
-#endif	/* EVM */
-
-static void davinci_source_power(struct musb *musb, int is_on, int immediate)
-{
-#ifdef CONFIG_MACH_DAVINCI_EVM
-	if (is_on)
-		is_on = 1;
-
-	if (vbus_state == is_on)
-		return;
-	vbus_state = !is_on;		/* 0/1 vs "-1 == unknown/init" */
-
-	if (machine_is_davinci_evm()) {
-		static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
-
-		if (immediate)
-			gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
-		else
-			schedule_work(&evm_vbus_work);
-	}
-	if (immediate)
-		vbus_state = is_on;
-#endif
-}
-
-static void davinci_set_vbus(struct musb *musb, int is_on)
-{
-	WARN_ON(is_on && is_peripheral_active(musb));
-	davinci_source_power(musb, is_on, 0);
-}
-
-
 #define	POLL_SECONDS	2
 
 static struct timer_list otg_workaround;
@@ -346,7 +281,8 @@  static irqreturn_t davinci_interrupt(int irq, void *__hci)
 		/* NOTE:  this must complete poweron within 100 msec
 		 * (OTG_TIME_A_WAIT_VRISE) but we don't check for that.
 		 */
-		davinci_source_power(musb, drvvbus, 0);
+		if(musb->board_set_vbus && !is_peripheral_enabled(musb))
+			musb->board_set_vbus(musb, drvvbus);
 		DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
 				drvvbus ? "on" : "off",
 				otg_state_string(musb),
@@ -399,34 +335,8 @@  int __init musb_platform_init(struct musb *musb)
 	if (is_host_enabled(musb))
 		setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
 
-	musb->board_set_vbus = davinci_set_vbus;
-	davinci_source_power(musb, 0, 1);
-
-	/* dm355 EVM swaps D+/D- for signal integrity, and
-	 * is clocked from the main 24 MHz crystal.
-	 */
-	if (machine_is_davinci_dm355_evm()) {
-		u32	phy_ctrl = __raw_readl(USB_PHY_CTRL);
-
-		phy_ctrl &= ~(3 << 9);
-		phy_ctrl |= USBPHY_DATAPOL;
-		__raw_writel(phy_ctrl, USB_PHY_CTRL);
-	}
-
-	/* On dm355, the default-A state machine needs DRVVBUS control.
-	 * If we won't be a host, there's no need to turn it on.
-	 */
-	if (cpu_is_davinci_dm355()) {
-		u32	deepsleep = __raw_readl(DM355_DEEPSLEEP);
-
-		if (is_host_enabled(musb)) {
-			deepsleep &= ~DRVVBUS_OVERRIDE;
-		} else {
-			deepsleep &= ~DRVVBUS_FORCE;
-			deepsleep |= DRVVBUS_OVERRIDE;
-		}
-		__raw_writel(deepsleep, DM355_DEEPSLEEP);
-	}
+	if(musb->board_set_vbus && !is_peripheral_enabled(musb))
+		musb->board_set_vbus(musb,VBUS_OFF_INMEDIATE);
 
 	/* reset the controller */
 	musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
@@ -454,16 +364,8 @@  int musb_platform_exit(struct musb *musb)
 	if (is_host_enabled(musb))
 		del_timer_sync(&otg_workaround);
 
-	/* force VBUS off */
-	if (cpu_is_davinci_dm355()) {
-		u32	deepsleep = __raw_readl(DM355_DEEPSLEEP);
-
-		deepsleep &= ~DRVVBUS_FORCE;
-		deepsleep |= DRVVBUS_OVERRIDE;
-		__raw_writel(deepsleep, DM355_DEEPSLEEP);
-	}
-
-	davinci_source_power(musb, 0 /*off*/, 1);
+	if(musb->board_set_vbus && !is_peripheral_enabled(musb))
+		musb->board_set_vbus(musb, VBUS_OFF_INMEDIATE);
 
 	/* delay, to avoid problems with module reload */
 	if (is_host_enabled(musb) && musb->xceiv->default_a) {
diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h
index 046c844..0df133d 100644
--- a/drivers/usb/musb/davinci.h
+++ b/drivers/usb/musb/davinci.h
@@ -16,6 +16,7 @@ 
 
 /* Integrated highspeed/otg PHY */
 #define USBPHY_CTL_PADDR	(DAVINCI_SYSTEM_MODULE_BASE + 0x34)
+#define USBPHY_CLKFREQ_24MHZ	BIT(13)
 #define USBPHY_DATAPOL		BIT(11)	/* (dm355) switch D+/D- */
 #define USBPHY_PHYCLKGD		BIT(8)
 #define USBPHY_SESNDEN		BIT(7)	/* v(sess_end) comparator */
@@ -27,10 +28,6 @@ 
 #define USBPHY_OTGPDWN		BIT(1)
 #define USBPHY_PHYPDWN		BIT(0)
 
-#define DM355_DEEPSLEEP_PADDR	(DAVINCI_SYSTEM_MODULE_BASE + 0x48)
-#define DRVVBUS_FORCE		BIT(2)
-#define DRVVBUS_OVERRIDE	BIT(1)
-
 /* For now include usb OTG module registers here */
 #define DAVINCI_USB_VERSION_REG		0x00
 #define DAVINCI_USB_CTRL_REG		0x04
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index c7c1ca0..deb3458 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1926,6 +1926,7 @@  bad_config:
 	musb->board_set_power = plat->set_power;
 	musb->set_clock = plat->set_clock;
 	musb->min_power = plat->min_power;
+	musb->board_set_vbus = plat->set_vbus;
 
 	/* Clock usage is chip-specific ... functional clock (DaVinci,
 	 * OMAP2430), or PHY ref (some TUSB6010 boards).  All this core
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index d437556..cd4139b 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -57,6 +57,8 @@  struct musb_hdrc_config {
 
 };
 
+extern struct musb dev;
+
 struct musb_hdrc_platform_data {
 	/* MUSB_HOST, MUSB_PERIPHERAL, or MUSB_OTG */
 	u8		mode;
@@ -65,7 +67,7 @@  struct musb_hdrc_platform_data {
 	const char	*clock;
 
 	/* (HOST or OTG) switch VBUS on/off */
-	int		(*set_vbus)(struct device *dev, int is_on);
+	void		(*set_vbus)(struct musb * dev, int is_on);
 
 	/* (HOST or OTG) mA/2 power supplied on (default = 8mA) */
 	u8		power;
@@ -86,6 +88,11 @@  struct musb_hdrc_platform_data {
 	struct musb_hdrc_config	*config;
 };
 
+/* VBUS states */
+#define VBUS_OFF		0
+#define VBUS_ON			1
+#define VBUS_OFF_INMEDIATE	2
+#define VBUS_ON_INMEDIATE	3
 
 /* TUSB 6010 support */