diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index f5ed3d7..6a868bc 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_USB_ATM)		+= atm/
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= atm/
 
 obj-$(CONFIG_USB_MUSB_HDRC)	+= musb/
+obj-$(CONFIG_USB_MUSB_OMAP2PLUS_MBOX_HELPER)	+= musb/
 obj-$(CONFIG_USB_CHIPIDEA)	+= chipidea/
 obj-$(CONFIG_USB_RENESAS_USBHS)	+= renesas_usbhs/
 obj-$(CONFIG_USB_GADGET)	+= gadget/
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 6259f0d..9201c3e 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -50,6 +50,7 @@ config USB_MUSB_TUSB6010
 config USB_MUSB_OMAP2PLUS
 	tristate "OMAP2430 and onwards"
 	depends on ARCH_OMAP2PLUS
+	select USB_MUSB_OMAP2PLUS_MBOX_HELPER
 
 config USB_MUSB_AM35X
 	tristate "AM35x"
@@ -69,6 +70,9 @@ config USB_MUSB_UX500
 
 endchoice
 
+config USB_MUSB_OMAP2PLUS_MBOX_HELPER
+	bool
+
 choice
 	prompt 'MUSB DMA mode'
 	default USB_UX500_DMA if USB_MUSB_UX500
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 3b85871..9126fa2 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -12,6 +12,7 @@ musb_hdrc-$(CONFIG_DEBUG_FS)			+= musb_debugfs.o
 
 # Hardware Glue Layer
 obj-$(CONFIG_USB_MUSB_OMAP2PLUS)		+= omap2430.o
+obj-$(CONFIG_USB_MUSB_OMAP2PLUS_MBOX_HELPER)	+= omap2430_mboxhelper.o
 obj-$(CONFIG_USB_MUSB_AM35X)			+= am35x.o
 obj-$(CONFIG_USB_MUSB_DSPS)			+= musb_dsps.o
 obj-$(CONFIG_USB_MUSB_TUSB6010)			+= tusb6010.o
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index d8c6aeb..920db04 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -228,7 +228,7 @@ static inline void omap2430_low_level_init(struct musb *musb)
 	musb_writel(musb->mregs, OTG_FORCESTDBY, l);
 }
 
-void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
+static void omap_musb_mailbox_actual(enum omap_musb_vbus_id_status status)
 {
 	struct omap2430_glue	*glue = _glue;
 	struct musb		*musb = glue_to_musb(glue);
@@ -241,7 +241,6 @@ void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
 
 	schedule_work(&glue->omap_musb_mailbox_work);
 }
-EXPORT_SYMBOL_GPL(omap_musb_mailbox);
 
 static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 {
@@ -441,6 +440,7 @@ static int omap2430_probe(struct platform_device *pdev)
 	struct platform_device		*musb;
 	struct omap2430_glue		*glue;
 	int				ret = -ENOMEM;
+	enum omap_musb_vbus_id_status	status;
 
 	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
 	if (!glue) {
@@ -495,6 +495,11 @@ static int omap2430_probe(struct platform_device *pdev)
 		goto err1;
 	}
 
+	/* set callback and process last status */
+	status = omap_musb_mailbox_set_callback(omap_musb_mailbox_actual);
+	if (status != OMAP_MUSB_UNKNOWN)
+		omap_musb_mailbox_actual(status);
+
 	return 0;
 
 err1:
@@ -508,6 +513,7 @@ static int __devexit omap2430_remove(struct platform_device *pdev)
 {
 	struct omap2430_glue		*glue = platform_get_drvdata(pdev);
 
+	omap_musb_mailbox_set_callback(NULL);
 	cancel_work_sync(&glue->omap_musb_mailbox_work);
 	platform_device_del(glue->musb);
 	platform_device_put(glue->musb);
diff --git a/drivers/usb/musb/omap2430_mboxhelper.c b/drivers/usb/musb/omap2430_mboxhelper.c
new file mode 100644
index 0000000..0eb95a5
--- /dev/null
+++ b/drivers/usb/musb/omap2430_mboxhelper.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * Helper file to make sure the musb mailbox helper callback
+ * works with any combination of modules/built-in configuration.
+ *
+ * This file is part of the Inventra Controller Driver for Linux.
+ *
+ * The Inventra Controller Driver for Linux is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU
+ * General Public License version 2 as published by the Free Software
+ * Foundation.
+ *
+ * The Inventra Controller Driver for Linux is distributed in
+ * the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with The Inventra Controller Driver for Linux ; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/usb/musb-omap.h>
+
+static DEFINE_SPINLOCK(omap_musb_callback_lock);
+static void (*omap_musb_callback)(enum omap_musb_vbus_id_status status) = NULL;
+static enum omap_musb_vbus_id_status omap_musb_last_status = OMAP_MUSB_UNKNOWN;
+
+void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&omap_musb_callback_lock, flags);
+	if (omap_musb_callback != NULL)
+		(*omap_musb_callback)(status);
+	omap_musb_last_status = status;
+	spin_unlock_irqrestore(&omap_musb_callback_lock, flags);
+
+}
+EXPORT_SYMBOL_GPL(omap_musb_mailbox);
+
+/* returns last status */
+enum omap_musb_vbus_id_status omap_musb_mailbox_set_callback(
+		void (*func)(enum omap_musb_vbus_id_status))
+{
+	unsigned long flags;
+	enum omap_musb_vbus_id_status status;
+
+	spin_lock_irqsave(&omap_musb_callback_lock, flags);
+	omap_musb_callback = func;
+	status = omap_musb_last_status;
+	spin_unlock_irqrestore(&omap_musb_callback_lock, flags);
+
+	return status;
+}
+EXPORT_SYMBOL_GPL(omap_musb_mailbox_set_callback);
diff --git a/include/linux/usb/musb-omap.h b/include/linux/usb/musb-omap.h
index 7774c59..33cb28f 100644
--- a/include/linux/usb/musb-omap.h
+++ b/include/linux/usb/musb-omap.h
@@ -18,12 +18,22 @@ enum omap_musb_vbus_id_status {
 	OMAP_MUSB_VBUS_OFF,
 };
 
-#if (defined(CONFIG_USB_MUSB_OMAP2PLUS) || \
-				defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE))
+#ifdef CONFIG_USB_MUSB_OMAP2PLUS_MBOX_HELPER
 void omap_musb_mailbox(enum omap_musb_vbus_id_status status);
+enum omap_musb_vbus_id_status omap_musb_mailbox_set_callback(
+		void (*func)(enum omap_musb_vbus_id_status));
 #else
-static inline void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
+static inline void
+omap_musb_mailbox(enum omap_musb_vbus_id_status status)
 {
+	/* nothing */
+}
+
+static inline enum omap_musb_vbus_id_status
+omap_musb_mailbox_set_callback(void (*func)(enum omap_musb_vbus_id_status))
+{
+	/* always return unknown */
+	return OMAP_MUSB_UNKNOWN;
 }
 #endif
 
