index b63ab1570103f2219afc5b44bdea08acd0531054..88e661ef4e69b6df56e902a8e8d032eb0f75eda4 100644 (file)
#include "musb_core.h"
-#define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON)
#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" MUSB_DRIVER_NAME);
+u8 (*musb_readb)(const void __iomem *addr, unsigned offset);
+EXPORT_SYMBOL_GPL(musb_readb);
+void (*musb_writeb)(void __iomem *addr, unsigned offset, u8 data);
+EXPORT_SYMBOL_GPL(musb_writeb);
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
#ifndef CONFIG_BLACKFIN
+
+/*
+ * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum.
+ */
+static inline u8 __tusb_musb_readb(const void __iomem *addr, unsigned offset)
+{
+ u16 tmp;
+ u8 val;
+
+ tmp = __raw_readw(addr + (offset & ~1));
+ if (offset & 1)
+ val = (tmp >> 8);
+ else
+ val = tmp & 0xff;
+
+ return val;
+}
+
+static inline void __tusb_musb_writeb(void __iomem *addr, unsigned offset,
+ u8 data)
+{
+ u16 tmp;
+
+ tmp = __raw_readw(addr + (offset & ~1));
+ if (offset & 1)
+ tmp = (data << 8) | (tmp & 0xff);
+ else
+ tmp = (tmp & 0xff00) | data;
+
+ __raw_writew(tmp, addr + (offset & ~1));
+}
+
+static inline u8 __musb_readb(const void __iomem *addr, unsigned offset)
+ { return __raw_readb(addr + offset); }
+
+static inline void __musb_writeb(void __iomem *addr, unsigned offset, u8 data)
+ { __raw_writeb(data, addr + offset); }
+
static int musb_ulpi_read(struct otg_transceiver *otg, u32 offset)
{
void __iomem *addr = otg->io_priv;
return 0;
}
#else
+static inline u8 __musb_readb(const void __iomem *addr, unsigned offset)
+ { return (u8) (bfin_read16(addr + offset)); }
+
+static inline void __musb_writeb(void __iomem *addr, unsigned offset, u8 data)
+ { bfin_write16(addr + offset, (u16) data); }
+
#define musb_ulpi_read NULL
#define musb_ulpi_write NULL
#endif
.write = musb_ulpi_write,
};
-/*-------------------------------------------------------------------------*/
-
-#if !defined(CONFIG_USB_MUSB_TUSB6010) && !defined(CONFIG_USB_MUSB_BLACKFIN)
-
/*
* Load an endpoint's FIFO
*/
writesb(fifo, src, len);
}
}
+EXPORT_SYMBOL_GPL(musb_write_fifo);
-#if !defined(CONFIG_USB_MUSB_AM35X)
/*
* Unload an endpoint's FIFO
*/
readsb(fifo, dst, len);
}
}
-#endif
-
-#endif /* normal PIO */
-
+EXPORT_SYMBOL_GPL(musb_read_fifo);
/*-------------------------------------------------------------------------*/
{
void __iomem *regs = musb->endpoints[0].regs;
- musb_ep_select(musb->mregs, 0);
- musb_write_fifo(musb->control_ep,
+ musb_ep_select(musb, musb->mregs, 0);
+ musb->ops->write_fifo(musb->control_ep,
sizeof(musb_test_packet), musb_test_packet);
musb_writew(regs, MUSB_CSR0, MUSB_CSR0_TXPKTRDY);
}
/*-------------------------------------------------------------------------*/
+/*
+ * See also USB_OTG_1-3.pdf 6.6.5 Timers
+ * REVISIT: Are the other timers done in the hardware?
+ */
+#define TB_ASE0_BRST 100 /* Min 3.125 ms */
+
/*
* Handles OTG hnp timeouts, such as b_ase0_brst
*/
musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
musb->is_active = 0;
break;
- case OTG_STATE_A_SUSPEND:
case OTG_STATE_A_WAIT_BCON:
- dev_dbg(musb->controller, "HNP: %s timeout\n",
- otg_state_string(musb->xceiv->state));
- musb_platform_set_vbus(musb, 0);
- musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
+ dev_dbg(musb->controller, "HNP: a_wait_bcon timeout; back to a_host\n");
+ musb_hnp_stop(musb);
break;
default:
dev_dbg(musb->controller, "HNP: Unhandled mode %s\n",
spin_unlock_irqrestore(&musb->lock, flags);
}
+static DEFINE_TIMER(musb_otg_timer, musb_otg_timer_func, 0, 0);
+
/*
- * Stops the HNP transition. Caller must take care of locking.
+ * Stops the B-device HNP state. Caller must take care of locking.
*/
void musb_hnp_stop(struct musb *musb)
{
void __iomem *mbase = musb->mregs;
u8 reg;
- dev_dbg(musb->controller, "HNP: stop from %s\n", otg_state_string(musb->xceiv->state));
-
switch (musb->xceiv->state) {
case OTG_STATE_A_PERIPHERAL:
+ case OTG_STATE_A_WAIT_VFALL:
+ case OTG_STATE_A_WAIT_BCON:
+ dev_dbg(musb->controller, "HNP: Switching back to A-host\n");
musb_g_disconnect(musb);
- dev_dbg(musb->controller, "HNP: back to %s\n",
- otg_state_string(musb->xceiv->state));
+ musb->xceiv->state = OTG_STATE_A_IDLE;
+ MUSB_HST_MODE(musb);
+ musb->is_active = 0;
break;
case OTG_STATE_B_HOST:
dev_dbg(musb->controller, "HNP: Disabling HR\n");
switch (musb->xceiv->state) {
case OTG_STATE_A_PERIPHERAL:
- /* We also come here if the cable is removed, since
- * this silicon doesn't report ID-no-longer-grounded.
- *
- * We depend on T(a_wait_bcon) to shut us down, and
- * hope users don't do anything dicey during this
- * undesired detour through A_WAIT_BCON.
+ /*
+ * We cannot stop HNP here, devctl BDEVICE might be
+ * still set.
*/
- musb_hnp_stop(musb);
- usb_hcd_resume_root_hub(musb_to_hcd(musb));
- musb_root_disconnect(musb);
- musb_platform_try_idle(musb, jiffies
- + msecs_to_jiffies(musb->a_wait_bcon
- ? : OTG_TIME_A_WAIT_BCON));
-
break;
case OTG_STATE_B_IDLE:
if (!musb->is_active)
if (musb->is_active) {
musb->xceiv->state = OTG_STATE_B_WAIT_ACON;
dev_dbg(musb->controller, "HNP: Setting timer for b_ase0_brst\n");
- mod_timer(&musb->otg_timer, jiffies
- + msecs_to_jiffies(
- OTG_TIME_B_ASE0_BRST));
+ musb_otg_timer.data = (unsigned long)musb;
+ mod_timer(&musb_otg_timer, jiffies
+ + msecs_to_jiffies(TB_ASE0_BRST));
}
break;
case OTG_STATE_A_WAIT_BCON:
if (devctl & MUSB_DEVCTL_LSDEV)
musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
+ if (hcd->status_urb)
+ usb_hcd_poll_rh_status(hcd);
+ else
+ usb_hcd_resume_root_hub(hcd);
+
+ MUSB_HST_MODE(musb);
+
/* indicate new connection to OTG machine */
switch (musb->xceiv->state) {
case OTG_STATE_B_PERIPHERAL:
if (int_usb & MUSB_INTR_SUSPEND) {
dev_dbg(musb->controller, "HNP: SUSPEND+CONNECT, now b_host\n");
+ musb->xceiv->state = OTG_STATE_B_HOST;
+ hcd->self.is_b_host = 1;
int_usb &= ~MUSB_INTR_SUSPEND;
- goto b_host;
} else
dev_dbg(musb->controller, "CONNECT as b_peripheral???\n");
break;
case OTG_STATE_B_WAIT_ACON:
- dev_dbg(musb->controller, "HNP: CONNECT, now b_host\n");
-b_host:
+ dev_dbg(musb->controller, "HNP: Waiting to switch to b_host state\n");
musb->xceiv->state = OTG_STATE_B_HOST;
hcd->self.is_b_host = 1;
- musb->ignore_disconnect = 0;
- del_timer(&musb->otg_timer);
break;
default:
if ((devctl & MUSB_DEVCTL_VBUS)
break;
}
- /* poke the root hub */
- MUSB_HST_MODE(musb);
- if (hcd->status_urb)
- usb_hcd_poll_rh_status(hcd);
- else
- usb_hcd_resume_root_hub(hcd);
-
dev_dbg(musb->controller, "CONNECT (%s) devctl %02x\n",
otg_state_string(musb->xceiv->state), devctl);
}
+ msecs_to_jiffies(musb->a_wait_bcon));
break;
case OTG_STATE_B_HOST:
- /* REVISIT this behaves for "real disconnect"
- * cases; make sure the other transitions from
- * from B_HOST act right too. The B_HOST code
- * in hnp_stop() is currently not used...
- */
- musb_root_disconnect(musb);
- musb_to_hcd(musb)->self.is_b_host = 0;
- musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
- MUSB_DEV_MODE(musb);
- musb_g_disconnect(musb);
+ musb_hnp_stop(musb);
break;
case OTG_STATE_A_PERIPHERAL:
musb_hnp_stop(musb);
/* FALLTHROUGH */
case OTG_STATE_B_PERIPHERAL:
case OTG_STATE_B_IDLE:
+ printk(KERN_INFO "musb %s gadget disconnected.\n",
+ musb->gadget_driver
+ ? musb->gadget_driver->driver.name
+ : "");
musb_g_disconnect(musb);
break;
default:
musb_g_reset(musb);
/* FALLTHROUGH */
case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */
- /* never use invalid T(a_wait_bcon) */
- dev_dbg(musb->controller, "HNP: in %s, %d msec timeout\n",
- otg_state_string(musb->xceiv->state),
- TA_WAIT_BCON(musb));
- mod_timer(&musb->otg_timer, jiffies
- + msecs_to_jiffies(TA_WAIT_BCON(musb)));
+ dev_dbg(musb->controller, "HNP: Setting timer as %s\n",
+ otg_state_string(musb->xceiv->state));
+ musb_otg_timer.data = (unsigned long)musb;
+ mod_timer(&musb_otg_timer, jiffies
+ + msecs_to_jiffies(100));
break;
case OTG_STATE_A_PERIPHERAL:
- musb->ignore_disconnect = 0;
- del_timer(&musb->otg_timer);
- musb_g_reset(musb);
+ musb_hnp_stop(musb);
break;
case OTG_STATE_B_WAIT_ACON:
dev_dbg(musb->controller, "HNP: RESET (%s), to b_peripheral\n",
* We don't currently use dynamic fifo setup capability to do anything
* more than selecting one of a bunch of predefined configurations.
*/
-#if defined(CONFIG_USB_MUSB_TUSB6010) \
- || defined(CONFIG_USB_MUSB_TUSB6010_MODULE) \
- || defined(CONFIG_USB_MUSB_OMAP2PLUS) \
- || defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE) \
- || defined(CONFIG_USB_MUSB_AM35X) \
- || defined(CONFIG_USB_MUSB_AM35X_MODULE)
-static ushort __initdata fifo_mode = 4;
-#elif defined(CONFIG_USB_MUSB_UX500) \
- || defined(CONFIG_USB_MUSB_UX500_MODULE)
-static ushort __initdata fifo_mode = 5;
-#else
-static ushort __initdata fifo_mode = 2;
-#endif
+static short __devinitdata fifo_mode = -1;
/* "modprobe ... fifo_mode=1" etc */
-module_param(fifo_mode, ushort, 0);
+module_param(fifo_mode, short, 0);
MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration");
/*
*/
/* mode 0 - fits in 2KB */
-static struct musb_fifo_cfg __initdata mode_0_cfg[] = {
+static struct musb_fifo_cfg __devinitdata mode_0_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, },
};
/* mode 1 - fits in 4KB */
-static struct musb_fifo_cfg __initdata mode_1_cfg[] = {
+static struct musb_fifo_cfg __devinitdata mode_1_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, },
};
/* mode 2 - fits in 4KB */
-static struct musb_fifo_cfg __initdata mode_2_cfg[] = {
+static struct musb_fifo_cfg __devinitdata mode_2_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
};
/* mode 3 - fits in 4KB */
-static struct musb_fifo_cfg __initdata mode_3_cfg[] = {
+static struct musb_fifo_cfg __devinitdata mode_3_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
};
/* mode 4 - fits in 16KB */
-static struct musb_fifo_cfg __initdata mode_4_cfg[] = {
+static struct musb_fifo_cfg __devinitdata mode_4_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
};
/* mode 5 - fits in 8KB */
-static struct musb_fifo_cfg __initdata mode_5_cfg[] = {
+static struct musb_fifo_cfg __devinitdata mode_5_cfg[] = {
{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
*
* returns negative errno or offset for next fifo.
*/
-static int __init
+static int __devinit
fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep,
const struct musb_fifo_cfg *cfg, u16 offset)
{
return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0));
}
-static struct musb_fifo_cfg __initdata ep0_cfg = {
+static struct musb_fifo_cfg __devinitdata ep0_cfg = {
.style = FIFO_RXTX, .maxpacket = 64,
};
-static int __init ep_config_from_table(struct musb *musb)
+static int __devinit ep_config_from_table(struct musb *musb)
{
const struct musb_fifo_cfg *cfg;
unsigned i, n;
int offset;
struct musb_hw_ep *hw_ep = musb->endpoints;
- if (musb->config->fifo_cfg) {
+ if (musb->config->fifo_mode) {
+ fifo_mode = musb->config->fifo_mode;
+ } else if (musb->config->fifo_cfg) {
cfg = musb->config->fifo_cfg;
n = musb->config->fifo_cfg_size;
goto done;
return 0;
}
-
/*
* ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false
* @param musb the controller
*/
-static int __init ep_config_from_hw(struct musb *musb)
+static int __devinit ep_config_from_hw(struct musb *musb)
{
u8 epnum = 0;
struct musb_hw_ep *hw_ep;
/* FIXME pick up ep0 maxpacket size */
for (epnum = 1; epnum < musb->config->num_eps; epnum++) {
- musb_ep_select(mbase, epnum);
+ musb_ep_select(musb, mbase, epnum);
hw_ep = musb->endpoints + epnum;
ret = musb_read_fifosize(musb, hw_ep, epnum);
/* Initialize MUSB (M)HDRC part of the USB hardware subsystem;
* configure endpoints, or take their config from silicon
*/
-static int __init musb_core_init(u16 musb_type, struct musb *musb)
+static int __devinit musb_core_init(u16 musb_type, struct musb *musb)
{
u8 reg;
char *type;
for (i = 0; i < musb->nr_endpoints; i++) {
struct musb_hw_ep *hw_ep = musb->endpoints + i;
- hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase;
-#ifdef CONFIG_USB_MUSB_TUSB6010
- hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i);
- hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i);
- hw_ep->fifo_sync_va =
- musb->sync_va + 0x400 + MUSB_FIFO_OFFSET(i);
-
- if (i == 0)
- hw_ep->conf = mbase - 0x400 + TUSB_EP0_CONF;
- else
- hw_ep->conf = mbase + 0x400 + (((i - 1) & 0xf) << 2);
-#endif
+ if (musb->ops->flags & MUSB_GLUE_TUSB_STYLE) {
+ hw_ep->fifo = MUSB_TUSB_FIFO_OFFSET(i) + mbase;
+ hw_ep->fifo_async = musb->async +
+ 0x400 + MUSB_TUSB_FIFO_OFFSET(i);
+ hw_ep->fifo_sync = musb->sync +
+ 0x400 + MUSB_TUSB_FIFO_OFFSET(i);
+ hw_ep->fifo_sync_va = musb->sync_va + 0x400 +
+ MUSB_TUSB_FIFO_OFFSET(i);
+
+ if (i == 0)
+ hw_ep->conf = mbase - 0x400 + TUSB_EP0_CONF;
+ else
+ hw_ep->conf = mbase + 0x400 +
+ (((i - 1) & 0xf) << 2);
+ } else {
+ hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase;
+ }
- hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase;
+ hw_ep->regs = MUSB_EP_OFFSET(musb, i, 0) + mbase;
hw_ep->target_regs = musb_read_target_reg_base(i, mbase);
hw_ep->rx_reinit = 1;
hw_ep->tx_reinit = 1;
ep_num = 1;
while (reg) {
if (reg & 1) {
- /* musb_ep_select(musb->mregs, ep_num); */
+ /* musb_ep_select(musb, musb->mregs, ep_num); */
/* REVISIT just retval = ep->rx_irq(...) */
retval = IRQ_HANDLED;
if (devctl & MUSB_DEVCTL_HM) {
ep_num = 1;
while (reg) {
if (reg & 1) {
- /* musb_ep_select(musb->mregs, ep_num); */
+ /* musb_ep_select(musb, musb->mregs, ep_num); */
/* REVISIT just retval |= ep->tx_irq(...) */
retval = IRQ_HANDLED;
if (devctl & MUSB_DEVCTL_HM) {
EXPORT_SYMBOL_GPL(musb_interrupt);
#ifndef CONFIG_MUSB_PIO_ONLY
-static int __initdata use_dma = 1;
+static int __devinitdata use_dma = 1;
/* "modprobe ... use_dma=0" etc */
module_param(use_dma, bool, 0);
/* called with controller lock already held */
if (!epnum) {
-#ifndef CONFIG_USB_TUSB_OMAP_DMA
- if (!is_cppi_enabled()) {
+ if (!tusb_dma_omap(musb) && !is_cppi_enabled(musb)) {
/* endpoint 0 */
if (devctl & MUSB_DEVCTL_HM)
musb_h_ep0_irq(musb);
else
musb_g_ep0_irq(musb);
}
-#endif
} else {
/* endpoints 1..15 */
if (transmit) {
}
}
}
+EXPORT_SYMBOL_GPL(musb_dma_completion);
#else
#define use_dma 0
}
spin_lock_irqsave(&musb->lock, flags);
- /* force T(a_wait_bcon) to be zero/unlimited *OR* valid */
- musb->a_wait_bcon = val ? max_t(int, val, OTG_TIME_A_WAIT_BCON) : 0 ;
+ musb->a_wait_bcon = val;
if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON)
musb->is_active = 0;
musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val));
@@ -1711,13 +1730,10 @@ musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf)
spin_lock_irqsave(&musb->lock, flags);
val = musb->a_wait_bcon;
- /* FIXME get_vbus_status() is normally #defined as false...
- * and is effectively TUSB-specific.
- */
vbus = musb_platform_get_vbus_status(musb);
spin_unlock_irqrestore(&musb->lock, flags);
- return sprintf(buf, "Vbus %s, timeout %lu msec\n",
+ return sprintf(buf, "Vbus %s, timeout %lu\n",
vbus ? "on" : "off", val);
}
static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store);
* Init support
*/
-static struct musb *__init
+static struct musb *__devinit
allocate_instance(struct device *dev,
struct musb_hdrc_config *config, void __iomem *mbase)
{
hcd->has_tt = 1;
musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
- musb->a_wait_bcon = OTG_TIME_A_WAIT_BCON;
dev_set_drvdata(dev, musb);
musb->mregs = mbase;
musb->ctrl_base = mbase;
struct dma_controller *c = musb->dma_controller;
(void) c->stop(c);
- dma_controller_destroy(c);
+ musb->ops->dma_controller_destroy(c);
}
kfree(musb);
* @mregs: virtual address of controller registers,
* not yet corrected for platform-specific offsets
*/
-static int __init
+static int __devinit
musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
{
int status;
musb->board_set_power = plat->set_power;
musb->min_power = plat->min_power;
musb->ops = plat->platform_ops;
+ if (fifo_mode == -1)
+ fifo_mode = musb->ops->fifo_mode;
+
+ if (musb->ops->flags & MUSB_GLUE_TUSB_STYLE) {
+ musb_readb = __tusb_musb_readb;
+ musb_writeb = __tusb_musb_writeb;
+ } else {
+ musb_readb = __musb_readb;
+ musb_writeb = __musb_writeb;
+ }
+
+ dev_info(dev, "dma type: %s\n", get_dma_name(musb));
/* The musb_platform_init() call:
* - adjusts musb->mregs and musb->isr if needed,
if (use_dma && dev->dma_mask) {
struct dma_controller *c;
- c = dma_controller_create(musb, musb->mregs);
+ if (!musb->ops->dma_controller_create) {
+ dev_err(dev, "no dma_controller_create for non-PIO mode!\n");
+ status = -ENODEV;
+ goto fail3;
+ }
+ c = musb->ops->dma_controller_create(musb, musb->mregs);
musb->dma_controller = c;
if (c)
(void) c->start(c);
if (status < 0)
goto fail3;
- setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
-
/* Init IRQ workqueue before request_irq */
INIT_WORK(&musb->irq_work, musb_irq_work);
if (status < 0)
goto fail3;
- pm_runtime_put(musb->controller);
-
status = musb_init_debugfs(musb);
if (status < 0)
goto fail4;
? "DMA" : "PIO",
musb->nIrq);
+ if (status == 0)
+ musb_debug_create("driver/musb_hdrc", musb);
+
return 0;
fail5:
static u64 *orig_dma_mask;
#endif
-static int __init musb_probe(struct platform_device *pdev)
+static int __devinit musb_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int irq = platform_get_irq_byname(pdev, "mc");
pm_runtime_get_sync(musb->controller);
musb_exit_debugfs(musb);
musb_shutdown(pdev);
+ musb_debug_delete("driver/musb_hdrc", musb);
pm_runtime_put(musb->controller);
musb_free(musb);
if (!epio)
continue;
+ musb_writeb(musb_base, MUSB_INDEX, i);
musb->context.index_regs[i].txmaxp =
musb_readw(epio, MUSB_TXMAXP);
musb->context.index_regs[i].txcsr =
if (!epio)
continue;
+ musb_writeb(musb_base, MUSB_INDEX, i);
musb_writew(epio, MUSB_TXMAXP,
musb->context.index_regs[i].txmaxp);
musb_writew(epio, MUSB_TXCSR,
.owner = THIS_MODULE,
.pm = MUSB_DEV_PM_OPS,
},
+ .probe = musb_probe,
.remove = __exit_p(musb_remove),
.shutdown = musb_shutdown,
};
", "
"otg (peripheral+host)",
musb_driver_name);
- return platform_driver_probe(&musb_driver, musb_probe);
+ return platform_driver_register(&musb_driver);
}
/* make us init after usbcore and i2c (transceivers, regulators, etc)