@@ -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/
@@ -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
@@ -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
@@ -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);
new file mode 100644
@@ -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);
@@ -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