[RFC/PATCH] usb: musb: split out hw glue layer

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

 



split hw glue layer to its own platform_device,
which is a parent of musb-hdrc platform_device.

we can now handle suspend/resume, PM, clocks
and context save/restore in a better and local
fashion which won't touch other archs.

NYET-Signed-off-by: Felipe Balbi <balbi@xxxxxx>
---
 arch/arm/mach-omap2/usb-musb.c        |    2 +-
 arch/arm/plat-omap/include/plat/usb.h |    1 +
 drivers/usb/musb/Makefile             |   41 ++----
 drivers/usb/musb/musb_core.c          |  239 +-------------------------------
 drivers/usb/musb/musb_core.h          |   46 ++++--
 drivers/usb/musb/omap2430.c           |  252 ++++++++++++++++++++++-----------
 6 files changed, 210 insertions(+), 371 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 33a5cde..2ce9b71 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -74,7 +74,7 @@ static struct musb_hdrc_platform_data musb_plat = {
 static u64 musb_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device musb_device = {
-	.name		= "musb_hdrc",
+	.name		= "omap-musb-hdrc",
 	.id		= -1,
 	.dev = {
 		.dma_mask		= &musb_dmamask,
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index 2a9427c..ba622a8 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -69,6 +69,7 @@ struct omap_musb_board_data {
 	u8	mode;
 	u16	power;
 	unsigned extvbus:1;
+	struct musb_hdrc_platform_data *musb;
 };
 
 enum musb_interface    {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 9705f71..99d5a7f 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -2,37 +2,7 @@
 # for USB OTG silicon based on Mentor Graphics INVENTRA designs
 #
 
-musb_hdrc-objs := musb_core.o
-
-obj-$(CONFIG_USB_MUSB_HDRC)	+= musb_hdrc.o
-
-ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
-	musb_hdrc-objs	+= davinci.o
-endif
-
-ifeq ($(CONFIG_USB_TUSB6010),y)
-	musb_hdrc-objs	+= tusb6010.o
-endif
-
-ifeq ($(CONFIG_ARCH_OMAP2430),y)
-	musb_hdrc-objs	+= omap2430.o
-endif
-
-ifeq ($(CONFIG_ARCH_OMAP3430),y)
-	musb_hdrc-objs	+= omap2430.o
-endif
-
-ifeq ($(CONFIG_ARCH_OMAP4),y)
-	musb_hdrc-objs  += omap2430.o
-endif
-
-ifeq ($(CONFIG_BF54x),y)
-	musb_hdrc-objs	+= blackfin.o
-endif
-
-ifeq ($(CONFIG_BF52x),y)
-	musb_hdrc-objs	+= blackfin.o
-endif
+musb_hdrc-objs			= musb_core.o
 
 ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y)
 	musb_hdrc-objs		+= musb_gadget_ep0.o musb_gadget.o
@@ -46,6 +16,15 @@ ifeq ($(CONFIG_DEBUG_FS),y)
 	musb_hdrc-objs		+= musb_debugfs.o
 endif
 
+obj-$(CONFIG_USB_MUSB_HDRC)	+= musb_hdrc.o
+obj-$(CONFIG_ARCH_DAVINCI_DMx)	+= davinci.o
+obj-$(CONFIG_USB_TUSB6010)	+= tusb6010.o
+obj-$(CONFIG_ARCH_OMAP2430)	+= omap2430.o
+obj-$(CONFIG_ARCH_OMAP3430)	+= omap2430.o
+obj-$(CONFIG_ARCH_OMAP4)	+= omap2430.o
+obj-$(CONFIG_BF54x)		+= blackfin.o
+obj-$(CONFIG_BF52x)		+= blackfin.o
+
 # the kconfig must guarantee that only one of the
 # possible I/O schemes will be enabled at a time ...
 # PIO only, or DMA (several potential schemes).
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 540c766..976345c5 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -984,7 +984,6 @@ void musb_start(struct musb *musb)
 		if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
 			musb->is_active = 1;
 	}
-	musb_platform_enable(musb);
 	musb_writeb(regs, MUSB_DEVCTL, devctl);
 }
 
@@ -1019,7 +1018,6 @@ static void musb_generic_disable(struct musb *musb)
 void musb_stop(struct musb *musb)
 {
 	/* stop IRQs, timers, ... */
-	musb_platform_disable(musb);
 	musb_generic_disable(musb);
 	DBG(3, "HDRC disabled\n");
 
@@ -1033,22 +1031,6 @@ void musb_stop(struct musb *musb)
 	musb_platform_try_idle(musb, 0);
 }
 
-static void musb_shutdown(struct platform_device *pdev)
-{
-	struct musb	*musb = dev_to_musb(&pdev->dev);
-	unsigned long	flags;
-
-	spin_lock_irqsave(&musb->lock, flags);
-	musb_platform_disable(musb);
-	musb_generic_disable(musb);
-	if (musb->clock)
-		clk_put(musb->clock);
-	spin_unlock_irqrestore(&musb->lock, flags);
-
-	/* FIXME power down */
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -2022,13 +2004,9 @@ bad_config:
 	 * isp1504, non-OTG, etc) mostly hooking up through ULPI.
 	 */
 	musb->isr = generic_interrupt;
-	status = musb_platform_init(musb, plat->board_data);
-	if (status < 0)
-		goto fail2;
-
 	if (!musb->isr) {
 		status = -ENODEV;
-		goto fail3;
+		goto fail2;
 	}
 
 	if (!musb->xceiv->io_ops) {
@@ -2051,7 +2029,6 @@ bad_config:
 		dev->dma_mask = NULL;
 
 	/* be sure interrupts are disabled before connecting ISR */
-	musb_platform_disable(musb);
 	musb_generic_disable(musb);
 
 	/* setup musb parts of the core (especially endpoints) */
@@ -2172,7 +2149,6 @@ fail4:
 fail3:
 	if (musb->irq_wake)
 		device_init_wakeup(dev, 0);
-	musb_platform_exit(musb);
 
 fail2:
 	if (musb->clock)
@@ -2240,13 +2216,11 @@ static int __exit musb_remove(struct platform_device *pdev)
 	 *  - OTG mode: both roles are deactivated (or never-activated)
 	 */
 	musb_exit_debugfs(musb);
-	musb_shutdown(pdev);
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
 	if (musb->board_mode == MUSB_HOST)
 		usb_remove_hcd(musb_to_hcd(musb));
 #endif
 	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-	musb_platform_exit(musb);
 	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
 
 	musb_free(musb);
@@ -2258,224 +2232,13 @@ static int __exit musb_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef	CONFIG_PM
-
-static struct musb_context_registers musb_context;
-
-void musb_save_context(struct musb *musb)
-{
-	int i;
-	void __iomem *musb_base = musb->mregs;
-
-	if (is_host_enabled(musb)) {
-		musb_context.frame = musb_readw(musb_base, MUSB_FRAME);
-		musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
-		musb_context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
-	}
-	musb_context.power = musb_readb(musb_base, MUSB_POWER);
-	musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
-	musb_context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE);
-	musb_context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE);
-	musb_context.index = musb_readb(musb_base, MUSB_INDEX);
-	musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL);
-
-	for (i = 0; i < MUSB_C_NUM_EPS; ++i) {
-		musb_writeb(musb_base, MUSB_INDEX, i);
-		musb_context.index_regs[i].txmaxp =
-			musb_readw(musb_base, 0x10 + MUSB_TXMAXP);
-		musb_context.index_regs[i].txcsr =
-			musb_readw(musb_base, 0x10 + MUSB_TXCSR);
-		musb_context.index_regs[i].rxmaxp =
-			musb_readw(musb_base, 0x10 + MUSB_RXMAXP);
-		musb_context.index_regs[i].rxcsr =
-			musb_readw(musb_base, 0x10 + MUSB_RXCSR);
-
-		if (musb->dyn_fifo) {
-			musb_context.index_regs[i].txfifoadd =
-					musb_read_txfifoadd(musb_base);
-			musb_context.index_regs[i].rxfifoadd =
-					musb_read_rxfifoadd(musb_base);
-			musb_context.index_regs[i].txfifosz =
-					musb_read_txfifosz(musb_base);
-			musb_context.index_regs[i].rxfifosz =
-					musb_read_rxfifosz(musb_base);
-		}
-		if (is_host_enabled(musb)) {
-			musb_context.index_regs[i].txtype =
-				musb_readb(musb_base, 0x10 + MUSB_TXTYPE);
-			musb_context.index_regs[i].txinterval =
-				musb_readb(musb_base, 0x10 + MUSB_TXINTERVAL);
-			musb_context.index_regs[i].rxtype =
-				musb_readb(musb_base, 0x10 + MUSB_RXTYPE);
-			musb_context.index_regs[i].rxinterval =
-				musb_readb(musb_base, 0x10 + MUSB_RXINTERVAL);
-
-			musb_context.index_regs[i].txfunaddr =
-				musb_read_txfunaddr(musb_base, i);
-			musb_context.index_regs[i].txhubaddr =
-				musb_read_txhubaddr(musb_base, i);
-			musb_context.index_regs[i].txhubport =
-				musb_read_txhubport(musb_base, i);
-
-			musb_context.index_regs[i].rxfunaddr =
-				musb_read_rxfunaddr(musb_base, i);
-			musb_context.index_regs[i].rxhubaddr =
-				musb_read_rxhubaddr(musb_base, i);
-			musb_context.index_regs[i].rxhubport =
-				musb_read_rxhubport(musb_base, i);
-		}
-	}
-
-	musb_writeb(musb_base, MUSB_INDEX, musb_context.index);
-
-	musb_platform_save_context(musb, &musb_context);
-}
-
-void musb_restore_context(struct musb *musb)
-{
-	int i;
-	void __iomem *musb_base = musb->mregs;
-	void __iomem *ep_target_regs;
-
-	musb_platform_restore_context(musb, &musb_context);
-
-	if (is_host_enabled(musb)) {
-		musb_writew(musb_base, MUSB_FRAME, musb_context.frame);
-		musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode);
-		musb_write_ulpi_buscontrol(musb->mregs, musb_context.busctl);
-	}
-	musb_writeb(musb_base, MUSB_POWER, musb_context.power);
-	musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe);
-	musb_writew(musb_base, MUSB_INTRRXE, musb_context.intrrxe);
-	musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe);
-	musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl);
-
-	for (i = 0; i < MUSB_C_NUM_EPS; ++i) {
-		musb_writeb(musb_base, MUSB_INDEX, i);
-		musb_writew(musb_base, 0x10 + MUSB_TXMAXP,
-			musb_context.index_regs[i].txmaxp);
-		musb_writew(musb_base, 0x10 + MUSB_TXCSR,
-			musb_context.index_regs[i].txcsr);
-		musb_writew(musb_base, 0x10 + MUSB_RXMAXP,
-			musb_context.index_regs[i].rxmaxp);
-		musb_writew(musb_base, 0x10 + MUSB_RXCSR,
-			musb_context.index_regs[i].rxcsr);
-
-		if (musb->dyn_fifo) {
-			musb_write_txfifosz(musb_base,
-				musb_context.index_regs[i].txfifosz);
-			musb_write_rxfifosz(musb_base,
-				musb_context.index_regs[i].rxfifosz);
-			musb_write_txfifoadd(musb_base,
-				musb_context.index_regs[i].txfifoadd);
-			musb_write_rxfifoadd(musb_base,
-				musb_context.index_regs[i].rxfifoadd);
-		}
-
-		if (is_host_enabled(musb)) {
-			musb_writeb(musb_base, 0x10 + MUSB_TXTYPE,
-				musb_context.index_regs[i].txtype);
-			musb_writeb(musb_base, 0x10 + MUSB_TXINTERVAL,
-				musb_context.index_regs[i].txinterval);
-			musb_writeb(musb_base, 0x10 + MUSB_RXTYPE,
-				musb_context.index_regs[i].rxtype);
-			musb_writeb(musb_base, 0x10 + MUSB_RXINTERVAL,
-
-			musb_context.index_regs[i].rxinterval);
-			musb_write_txfunaddr(musb_base, i,
-				musb_context.index_regs[i].txfunaddr);
-			musb_write_txhubaddr(musb_base, i,
-				musb_context.index_regs[i].txhubaddr);
-			musb_write_txhubport(musb_base, i,
-				musb_context.index_regs[i].txhubport);
-
-			ep_target_regs =
-				musb_read_target_reg_base(i, musb_base);
-
-			musb_write_rxfunaddr(ep_target_regs,
-				musb_context.index_regs[i].rxfunaddr);
-			musb_write_rxhubaddr(ep_target_regs,
-				musb_context.index_regs[i].rxhubaddr);
-			musb_write_rxhubport(ep_target_regs,
-				musb_context.index_regs[i].rxhubport);
-		}
-	}
-
-	musb_writeb(musb_base, MUSB_INDEX, musb_context.index);
-}
-
-static int musb_suspend(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	unsigned long	flags;
-	struct musb	*musb = dev_to_musb(&pdev->dev);
-
-	if (!musb->clock)
-		return 0;
-
-	spin_lock_irqsave(&musb->lock, flags);
-
-	if (is_peripheral_active(musb)) {
-		/* FIXME force disconnect unless we know USB will wake
-		 * the system up quickly enough to respond ...
-		 */
-	} else if (is_host_active(musb)) {
-		/* we know all the children are suspended; sometimes
-		 * they will even be wakeup-enabled.
-		 */
-	}
-
-	musb_save_context(musb);
-
-	if (musb->set_clock)
-		musb->set_clock(musb->clock, 0);
-	else
-		clk_disable(musb->clock);
-	spin_unlock_irqrestore(&musb->lock, flags);
-	return 0;
-}
-
-static int musb_resume_noirq(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct musb	*musb = dev_to_musb(&pdev->dev);
-
-	if (!musb->clock)
-		return 0;
-
-	if (musb->set_clock)
-		musb->set_clock(musb->clock, 1);
-	else
-		clk_enable(musb->clock);
-
-	musb_restore_context(musb);
-
-	/* for static cmos like DaVinci, register values were preserved
-	 * unless for some reason the whole soc powered down or the USB
-	 * module got reset through the PSC (vs just being disabled).
-	 */
-	return 0;
-}
-
-static const struct dev_pm_ops musb_dev_pm_ops = {
-	.suspend	= musb_suspend,
-	.resume_noirq	= musb_resume_noirq,
-};
-
-#define MUSB_DEV_PM_OPS (&musb_dev_pm_ops)
-#else
-#define	MUSB_DEV_PM_OPS	NULL
-#endif
-
 static struct platform_driver musb_driver = {
 	.driver = {
 		.name		= (char *)musb_driver_name,
 		.bus		= &platform_bus_type,
 		.owner		= THIS_MODULE,
-		.pm		= MUSB_DEV_PM_OPS,
 	},
 	.remove		= __exit_p(musb_remove),
-	.shutdown	= musb_shutdown,
 };
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 91d6779..0918eb2 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -323,6 +323,14 @@ static inline struct usb_request *next_out_request(struct musb_hw_ep *hw_ep)
 #endif
 }
 
+struct musb_hdrc_ops {
+	int (*get_vbus_status)(struct musb *);
+	int (*set_mode)(struct musb *, u8);
+
+	void (*try_idle)(struct musb *, unsigned long);
+	void (*set_vbus)(struct musb *, int);
+};
+
 /*
  * struct musb - Driver instance data.
  */
@@ -334,6 +342,8 @@ struct musb {
 	struct work_struct	irq_work;
 	u16			hwvers;
 
+	struct musb_hdrc_ops	*ops;
+
 /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
 #define MUSB_PORT_STAT_RESUME	(1 << 31)
 
@@ -596,23 +606,29 @@ extern void musb_platform_disable(struct musb *musb);
 
 extern void musb_hnp_stop(struct musb *musb);
 
-extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
+static inline int musb_platform_set_mode(struct musb *musb, u8 mode)
+{
+	if (!musb->ops || !musb->ops->set_mode)
+		return 0;
 
-#if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \
-	defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
-	defined(CONFIG_ARCH_OMAP4)
-extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout);
-#else
-#define musb_platform_try_idle(x, y)		do {} while (0)
-#endif
+	return musb->ops->set_mode(musb, mode);
+}
 
-#if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN)
-extern int musb_platform_get_vbus_status(struct musb *musb);
-#else
-#define musb_platform_get_vbus_status(x)	0
-#endif
+static inline int musb_platform_get_vbus_status(struct musb *musb)
+{
+	if (!musb->ops || !musb->ops->get_vbus_status)
+		return 0;
 
-extern int __init musb_platform_init(struct musb *musb, void *board_data);
-extern int musb_platform_exit(struct musb *musb);
+	return musb->ops->get_vbus_status(musb);
+}
+
+static inline void musb_platform_try_idle(struct musb *musb,
+		unsigned long timeout)
+{
+	if (!musb->ops || !musb->ops->try_idle)
+		return;
+
+	musb->ops->try_idle(musb, timeout);
+}
 
 #endif	/* __MUSB_CORE_H__ */
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 2111a24..23c9a1f 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2007 by Texas Instruments
+ * Copyright (C) 2005-2010 by Texas Instruments
  * Some code has been taken from tusb6010.c
  * Copyrights for that are attributable to:
  * Copyright (C) 2006 Nokia Corporation
@@ -29,13 +29,14 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <plat/usb.h>
 
 #include "musb_core.h"
 #include "omap2430.h"
 
-
 static struct timer_list musb_idle_timer;
 
 static void musb_do_idle(unsigned long _musb)
@@ -98,7 +99,7 @@ static void musb_do_idle(unsigned long _musb)
 }
 
 
-void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
+static void omap_musb_try_idle(struct musb *musb, unsigned long timeout)
 {
 	unsigned long		default_timeout = jiffies + msecs_to_jiffies(3);
 	static unsigned long	last_timer;
@@ -131,12 +132,6 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
 	mod_timer(&musb_idle_timer, timeout);
 }
 
-void musb_platform_enable(struct musb *musb)
-{
-}
-void musb_platform_disable(struct musb *musb)
-{
-}
 static void omap_set_vbus(struct musb *musb, int is_on)
 {
 	u8		devctl;
@@ -175,36 +170,60 @@ static void omap_set_vbus(struct musb *musb, int is_on)
 		musb_readb(musb->mregs, MUSB_DEVCTL));
 }
 
-static int musb_platform_resume(struct musb *musb);
+#ifdef CONFIG_PM
+void musb_platform_save_context(struct musb *musb,
+		struct musb_context_registers *musb_context)
+{
+	musb_context->otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
+	musb_context->otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
+}
 
-int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
+void musb_platform_restore_context(struct musb *musb,
+		struct musb_context_registers *musb_context)
 {
-	u8	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+	musb_writel(musb->mregs, OTG_SYSCONFIG, musb_context->otg_sysconfig);
+	musb_writel(musb->mregs, OTG_FORCESTDBY, musb_context->otg_forcestandby);
+}
+#endif
 
-	devctl |= MUSB_DEVCTL_SESSION;
-	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+static struct musb_hdrc_ops omap_musb_ops = {
+	.try_idle	= omap_musb_try_idle,
+	.set_vbus	= omap_set_vbus,
+};
 
-	return 0;
-}
+struct omap_musb {
+	spinlock_t	lock;
+	struct clk	*clk;
+	void __iomem	*base;
+};
 
-int __init musb_platform_init(struct musb *musb, void *board_data)
+static int __init omap_musb_probe(struct platform_device *pdev)
 {
-	u32 l;
-	struct omap_musb_board_data *data = board_data;
+	struct omap_musb		*omap;
+	struct omap_musb_board_data	*pdata = pdev->dev.platform_data;
+	struct musb_hdrc_platform_data	*musb_data = pdata->musb;
+	struct platform_device		*musb;
+	struct clk			*clk;
+	long				l;
+	int				ret = -ENOMEM;
+
+	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
+	if (!omap) {
+		dev_err(&pdev->dev, "not enough memory\n");
+		goto err0;
+	}
 
-	/* We require some kind of external transceiver, hooked
-	 * up through ULPI.  TWL4030-family PMICs include one,
-	 * which needs a driver, drivers aren't always needed.
-	 */
-	musb->xceiv = otg_get_transceiver();
-	if (!musb->xceiv) {
-		pr_err("HS USB OTG: no transceiver configured\n");
-		return -ENODEV;
+	clk = clk_get(&pdev->dev, "ick");
+	if (IS_ERR(clk)) {
+		dev_err(&pdev->dev, "can't get clock\n");
+		ret = PTR_ERR(clk);
+		goto err1;
 	}
 
-	musb_platform_resume(musb);
+	omap->clk = clk;
+	spin_lock_init(&omap->lock);
 
-	l = musb_readl(musb->mregs, OTG_SYSCONFIG);
+	l = musb_readl(omap->base, OTG_SYSCONFIG);
 	l &= ~ENABLEWAKEUP;	/* disable wakeup */
 	l &= ~NOSTDBY;		/* remove possible nostdby */
 	l |= SMARTSTDBY;	/* enable smart standby */
@@ -217,11 +236,11 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
 	 */
 	if (!cpu_is_omap3430())
 		l |= AUTOIDLE;		/* enable auto idle */
-	musb_writel(musb->mregs, OTG_SYSCONFIG, l);
+	musb_writel(omap->base, OTG_SYSCONFIG, l);
 
-	l = musb_readl(musb->mregs, OTG_INTERFSEL);
+	l = musb_readl(omap->base, OTG_INTERFSEL);
 
-	if (data->interface_type == MUSB_INTERFACE_UTMI) {
+	if (pdata->interface_type == MUSB_INTERFACE_UTMI) {
 		/* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
 		l &= ~ULPI_12PIN;       /* Disable ULPI */
 		l |= UTMI_8BIT;         /* Enable UTMI  */
@@ -229,96 +248,157 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
 		l |= ULPI_12PIN;
 	}
 
-	musb_writel(musb->mregs, OTG_INTERFSEL, l);
+	musb_writel(omap->base, OTG_INTERFSEL, l);
 
-	pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
-			"sysstatus 0x%x, intrfsel 0x%x, simenable  0x%x\n",
-			musb_readl(musb->mregs, OTG_REVISION),
-			musb_readl(musb->mregs, OTG_SYSCONFIG),
-			musb_readl(musb->mregs, OTG_SYSSTATUS),
-			musb_readl(musb->mregs, OTG_INTERFSEL),
-			musb_readl(musb->mregs, OTG_SIMENABLE));
+	ret = clk_enable(clk);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to enabled clock\n");
+		goto err2;
+	}
 
-	if (is_host_enabled(musb))
-		musb->board_set_vbus = omap_set_vbus;
+	musb = platform_device_alloc("musb-hdrc", -1);
+	if (!musb) {
+		dev_err(&pdev->dev, "can't allocate musb-hdrc pdev\n");
+		goto err3;
+	}
+
+	musb->dev.parent = &pdev->dev;
+	platform_set_drvdata(pdev, omap);
+
+	ret = platform_device_add_data(musb, musb_data, sizeof(*musb_data));
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add pdata\n");
+		goto err4;
+	}
+
+	ret = platform_device_register(musb);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register musb-hdrc pdev\n");
+		goto err4;
+	}
 
 	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
 
+	dev_dbg(&pdev->dev, "Rev: 0x%x, SYSCONFIG 0x%02x, "
+			"SYSSTATUS 0x%x, INTRSEL 0x%x, SIMENABLE 0x%x\n",
+			musb_readl(omap->base, OTG_REVISION),
+			musb_readl(omap->base, OTG_SYSCONFIG),
+			musb_readl(omap->base, OTG_SYSSTATUS),
+			musb_readl(omap->base, OTG_INTERFSEL),
+			musb_readl(omap->base, OTG_SIMENABLE));
+
 	return 0;
-}
 
-#ifdef CONFIG_PM
-void musb_platform_save_context(struct musb *musb,
-		struct musb_context_registers *musb_context)
-{
-	musb_context->otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
-	musb_context->otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
+err4:
+	platform_device_put(musb);
+
+err3:
+	clk_disable(clk);
+
+err2:
+	clk_put(clk);
+
+err1:
+	kfree(omap);
+
+err0:
+	return ret;
 }
 
-void musb_platform_restore_context(struct musb *musb,
-		struct musb_context_registers *musb_context)
+static int __exit omap_musb_remove(struct platform_device *pdev)
 {
-	musb_writel(musb->mregs, OTG_SYSCONFIG, musb_context->otg_sysconfig);
-	musb_writel(musb->mregs, OTG_FORCESTDBY, musb_context->otg_forcestandby);
+	struct omap_musb	*omap = platform_get_drvdata(pdev);
+
+	clk_disable(omap->clk);
+	clk_put(omap->clk);
+	kfree(omap);
+
+	return 0;
 }
-#endif
 
-static int musb_platform_suspend(struct musb *musb)
+#ifdef CONFIG_PM
+static int omap_musb_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	u32 l;
+	struct omap_musb	*omap = platform_get_drvdata(pdev);
+	unsigned long		flags;
+	unsigned long		l;
 
-	if (!musb->clock)
-		return 0;
+	spin_lock_irqsave(&omap->lock, flags);
 
-	/* in any role */
-	l = musb_readl(musb->mregs, OTG_FORCESTDBY);
+	l = musb_readl(omap->base, OTG_FORCESTDBY);
 	l |= ENABLEFORCE;	/* enable MSTANDBY */
-	musb_writel(musb->mregs, OTG_FORCESTDBY, l);
+	musb_writel(omap->base, OTG_FORCESTDBY, l);
 
-	l = musb_readl(musb->mregs, OTG_SYSCONFIG);
+	l = musb_readl(omap->base, OTG_SYSCONFIG);
 	l |= ENABLEWAKEUP;	/* enable wakeup */
-	musb_writel(musb->mregs, OTG_SYSCONFIG, l);
+	musb_writel(omap->base, OTG_SYSCONFIG, l);
 
-	otg_set_suspend(musb->xceiv, 1);
+	/* save context here */
 
-	if (musb->set_clock)
-		musb->set_clock(musb->clock, 0);
-	else
-		clk_disable(musb->clock);
+	clk_disable(omap->clk);
+
+	spin_unlock_irqrestore(&omap->lock, flags);
 
 	return 0;
 }
 
-static int musb_platform_resume(struct musb *musb)
+static int omap_musb_resume(struct platform_device *pdev)
 {
-	u32 l;
+	struct omap_musb	*omap = platform_get_drvdata(pdev);
+	unsigned long		flags;
+	unsigned long		l;
+	int			ret;
 
-	if (!musb->clock)
-		return 0;
+	spin_lock_irqsave(&omap->lock, flags);
 
-	otg_set_suspend(musb->xceiv, 0);
+	ret = clk_enable(omap->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "could not enable clk\n");
+		goto out;
+	}
 
-	if (musb->set_clock)
-		musb->set_clock(musb->clock, 1);
-	else
-		clk_enable(musb->clock);
+	/* restore context here */
 
-	l = musb_readl(musb->mregs, OTG_SYSCONFIG);
+	l = musb_readl(omap->base, OTG_SYSCONFIG);
 	l &= ~ENABLEWAKEUP;	/* disable wakeup */
-	musb_writel(musb->mregs, OTG_SYSCONFIG, l);
+	musb_writel(omap->base, OTG_SYSCONFIG, l);
 
-	l = musb_readl(musb->mregs, OTG_FORCESTDBY);
+	l = musb_readl(omap->base, OTG_FORCESTDBY);
 	l &= ~ENABLEFORCE;	/* disable MSTANDBY */
-	musb_writel(musb->mregs, OTG_FORCESTDBY, l);
+	musb_writel(omap->base, OTG_FORCESTDBY, l);
 
-	return 0;
+out:
+	spin_unlock_irqrestore(&omap->lock, flags);
+
+	return ret;
 }
+#else
+#define omap_musb_suspend	NULL
+#define omap_musb_resume	NULL
+#endif
 
+static struct platform_driver omap_musb_driver = {
+	.remove		= __exit_p(omap_musb_remove),
+	.suspend	= omap_musb_suspend,
+	.resume		= omap_musb_resume,
+	.driver		= {
+		.name	= "omap-musb-hdrc",
+	},
+};
 
-int musb_platform_exit(struct musb *musb)
-{
+MODULE_DESCRIPTION("OMAP MUSB Glue Layer");
+MODULE_AUTHOR("Felipe Balbi <balbi@xxxxxx>");
+MODULE_LICENSE("GPL v2");
 
-	musb_platform_suspend(musb);
+static int __init omap_musb_init(void)
+{
+	return platform_driver_probe(&omap_musb_driver, omap_musb_probe);
+}
+module_init(omap_musb_init);
 
-	return 0;
+static void __exit omap_musb_exit(void)
+{
+	platform_driver_unregister(&omap_musb_driver);
 }
+module_exit(omap_musb_exit);
+
-- 
1.7.3.rc0.35.g8ac8c

--
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