diff options
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/Makefile | 5 | ||||
-rw-r--r-- | drivers/usb/musb/cppi_dma.c | 51 | ||||
-rw-r--r-- | drivers/usb/musb/cppi_dma.h | 31 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.c | 172 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 3 | ||||
-rw-r--r-- | drivers/usb/musb/musb_cppi41.c | 47 | ||||
-rw-r--r-- | drivers/usb/musb/musb_debug.h | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_dsps.c | 112 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 156 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget_ep0.c | 22 | ||||
-rw-r--r-- | drivers/usb/musb/musb_host.c | 201 | ||||
-rw-r--r-- | drivers/usb/musb/musb_trace.c | 33 | ||||
-rw-r--r-- | drivers/usb/musb/musb_trace.h | 371 | ||||
-rw-r--r-- | drivers/usb/musb/musb_virthub.c | 24 | ||||
-rw-r--r-- | drivers/usb/musb/musbhsdma.c | 10 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 257 | ||||
-rw-r--r-- | drivers/usb/musb/sunxi.c | 88 |
17 files changed, 931 insertions, 654 deletions
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index f95befe18cc1..689d42aba8a9 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile @@ -2,9 +2,12 @@ # for USB OTG silicon based on Mentor Graphics INVENTRA designs # +# define_trace.h needs to know how to find our header +CFLAGS_musb_trace.o := -I$(src) + obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o -musb_hdrc-y := musb_core.o +musb_hdrc-y := musb_core.o musb_trace.o musb_hdrc-$(CONFIG_USB_MUSB_HOST)$(CONFIG_USB_MUSB_DUAL_ROLE) += musb_virthub.o musb_host.o musb_hdrc-$(CONFIG_USB_MUSB_GADGET)$(CONFIG_USB_MUSB_DUAL_ROLE) += musb_gadget_ep0.o musb_gadget.o diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index cc134109b056..1ae48e64e975 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -14,6 +14,7 @@ #include "musb_core.h" #include "musb_debug.h" #include "cppi_dma.h" +#include "davinci.h" /* CPPI DMA status 7-mar-2006: @@ -232,7 +233,7 @@ static void cppi_controller_stop(struct cppi *controller) musb_writel(tibase, DAVINCI_RXCPPI_INTCLR_REG, DAVINCI_DMA_ALL_CHANNELS_ENABLE); - dev_dbg(musb->controller, "Tearing down RX and TX Channels\n"); + musb_dbg(musb, "Tearing down RX and TX Channels"); for (i = 0; i < ARRAY_SIZE(controller->tx); i++) { /* FIXME restructure of txdma to use bds like rxdma */ controller->tx[i].last_processed = NULL; @@ -297,13 +298,13 @@ cppi_channel_allocate(struct dma_controller *c, */ if (transmit) { if (index >= ARRAY_SIZE(controller->tx)) { - dev_dbg(musb->controller, "no %cX%d CPPI channel\n", 'T', index); + musb_dbg(musb, "no %cX%d CPPI channel", 'T', index); return NULL; } cppi_ch = controller->tx + index; } else { if (index >= ARRAY_SIZE(controller->rx)) { - dev_dbg(musb->controller, "no %cX%d CPPI channel\n", 'R', index); + musb_dbg(musb, "no %cX%d CPPI channel", 'R', index); return NULL; } cppi_ch = controller->rx + index; @@ -314,13 +315,13 @@ cppi_channel_allocate(struct dma_controller *c, * with the other DMA engine too */ if (cppi_ch->hw_ep) - dev_dbg(musb->controller, "re-allocating DMA%d %cX channel %p\n", + musb_dbg(musb, "re-allocating DMA%d %cX channel %p", index, transmit ? 'T' : 'R', cppi_ch); cppi_ch->hw_ep = ep; cppi_ch->channel.status = MUSB_DMA_STATUS_FREE; cppi_ch->channel.max_len = 0x7fffffff; - dev_dbg(musb->controller, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R'); + musb_dbg(musb, "Allocate CPPI%d %cX", index, transmit ? 'T' : 'R'); return &cppi_ch->channel; } @@ -335,8 +336,8 @@ static void cppi_channel_release(struct dma_channel *channel) c = container_of(channel, struct cppi_channel, channel); tibase = c->controller->tibase; if (!c->hw_ep) - dev_dbg(c->controller->musb->controller, - "releasing idle DMA channel %p\n", c); + musb_dbg(c->controller->musb, + "releasing idle DMA channel %p", c); else if (!c->transmit) core_rxirq_enable(tibase, c->index + 1); @@ -354,11 +355,10 @@ cppi_dump_rx(int level, struct cppi_channel *c, const char *tag) musb_ep_select(base, c->index + 1); - dev_dbg(c->controller->musb->controller, + musb_dbg(c->controller->musb, "RX DMA%d%s: %d left, csr %04x, " "%08x H%08x S%08x C%08x, " - "B%08x L%08x %08x .. %08x" - "\n", + "B%08x L%08x %08x .. %08x", c->index, tag, musb_readl(c->controller->tibase, DAVINCI_RXCPPI_BUFCNT0_REG + 4 * c->index), @@ -385,11 +385,10 @@ cppi_dump_tx(int level, struct cppi_channel *c, const char *tag) musb_ep_select(base, c->index + 1); - dev_dbg(c->controller->musb->controller, + musb_dbg(c->controller->musb, "TX DMA%d%s: csr %04x, " "H%08x S%08x C%08x %08x, " - "F%08x L%08x .. %08x" - "\n", + "F%08x L%08x .. %08x", c->index, tag, musb_readw(c->hw_ep->regs, MUSB_TXCSR), @@ -590,7 +589,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx) length = min(n_bds * maxpacket, length); } - dev_dbg(musb->controller, "TX DMA%d, pktSz %d %s bds %d dma 0x%llx len %u\n", + musb_dbg(musb, "TX DMA%d, pktSz %d %s bds %d dma 0x%llx len %u", tx->index, maxpacket, rndis ? "rndis" : "transparent", @@ -647,7 +646,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx) bd->hw_options |= CPPI_ZERO_SET; } - dev_dbg(musb->controller, "TXBD %p: nxt %08x buf %08x len %04x opt %08x\n", + musb_dbg(musb, "TXBD %p: nxt %08x buf %08x len %04x opt %08x", bd, bd->hw_next, bd->hw_bufp, bd->hw_off_len, bd->hw_options); @@ -813,8 +812,8 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket) length = min(n_bds * maxpacket, length); - dev_dbg(musb->controller, "RX DMA%d seg, maxp %d %s bds %d (cnt %d) " - "dma 0x%llx len %u %u/%u\n", + musb_dbg(musb, "RX DMA%d seg, maxp %d %s bds %d (cnt %d) " + "dma 0x%llx len %u %u/%u", rx->index, maxpacket, onepacket ? (is_rndis ? "rndis" : "onepacket") @@ -924,7 +923,7 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket) DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4)) & 0xffff; if (i < (2 + n_bds)) { - dev_dbg(musb->controller, "bufcnt%d underrun - %d (for %d)\n", + musb_dbg(musb, "bufcnt%d underrun - %d (for %d)", rx->index, i, n_bds); musb_writel(tibase, DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4), @@ -973,7 +972,7 @@ static int cppi_channel_program(struct dma_channel *ch, /* WARN_ON(1); */ break; case MUSB_DMA_STATUS_UNKNOWN: - dev_dbg(musb->controller, "%cX DMA%d not allocated!\n", + musb_dbg(musb, "%cX DMA%d not allocated!", cppi_ch->transmit ? 'T' : 'R', cppi_ch->index); /* FALLTHROUGH */ @@ -1029,8 +1028,8 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) if (!completed && (bd->hw_options & CPPI_OWN_SET)) break; - dev_dbg(musb->controller, "C/RXBD %llx: nxt %08x buf %08x " - "off.len %08x opt.len %08x (%d)\n", + musb_dbg(musb, "C/RXBD %llx: nxt %08x buf %08x " + "off.len %08x opt.len %08x (%d)", (unsigned long long)bd->dma, bd->hw_next, bd->hw_bufp, bd->hw_off_len, bd->hw_options, rx->channel.actual_len); @@ -1051,7 +1050,7 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) * CPPI ignores those BDs even though OWN is still set. */ completed = true; - dev_dbg(musb->controller, "rx short %d/%d (%d)\n", + musb_dbg(musb, "rx short %d/%d (%d)", len, bd->buflen, rx->channel.actual_len); } @@ -1101,7 +1100,7 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) musb_ep_select(cppi->mregs, rx->index + 1); csr = musb_readw(regs, MUSB_RXCSR); if (csr & MUSB_RXCSR_DMAENAB) { - dev_dbg(musb->controller, "list%d %p/%p, last %llx%s, csr %04x\n", + musb_dbg(musb, "list%d %p/%p, last %llx%s, csr %04x", rx->index, rx->head, rx->tail, rx->last_processed @@ -1164,7 +1163,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) return IRQ_NONE; } - dev_dbg(musb->controller, "CPPI IRQ Tx%x Rx%x\n", tx, rx); + musb_dbg(musb, "CPPI IRQ Tx%x Rx%x", tx, rx); /* process TX channels */ for (index = 0; tx; tx = tx >> 1, index++) { @@ -1192,7 +1191,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) * that needs to be acknowledged. */ if (NULL == bd) { - dev_dbg(musb->controller, "null BD\n"); + musb_dbg(musb, "null BD"); musb_writel(&tx_ram->tx_complete, 0, 0); continue; } @@ -1207,7 +1206,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) if (bd->hw_options & CPPI_OWN_SET) break; - dev_dbg(musb->controller, "C/TXBD %p n %x b %x off %x opt %x\n", + musb_dbg(musb, "C/TXBD %p n %x b %x off %x opt %x", bd, bd->hw_next, bd->hw_bufp, bd->hw_off_len, bd->hw_options); diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h index 59bf949e589b..7fdfb71a8f09 100644 --- a/drivers/usb/musb/cppi_dma.h +++ b/drivers/usb/musb/cppi_dma.h @@ -7,17 +7,10 @@ #include <linux/list.h> #include <linux/errno.h> #include <linux/dmapool.h> +#include <linux/dmaengine.h> -#include "musb_dma.h" #include "musb_core.h" - - -/* FIXME fully isolate CPPI from DaVinci ... the "CPPI generic" registers - * would seem to be shared with the TUSB6020 (over VLYNQ). - */ - -#include "davinci.h" - +#include "musb_dma.h" /* CPPI RX/TX state RAM */ @@ -131,4 +124,24 @@ struct cppi { /* CPPI IRQ handler */ extern irqreturn_t cppi_interrupt(int, void *); +struct cppi41_dma_channel { + struct dma_channel channel; + struct cppi41_dma_controller *controller; + struct musb_hw_ep *hw_ep; + struct dma_chan *dc; + dma_cookie_t cookie; + u8 port_num; + u8 is_tx; + u8 is_allocated; + u8 usb_toggle; + + dma_addr_t buf_addr; + u32 total_len; + u32 prog_len; + u32 transferred; + u32 packet_sz; + struct list_head tx_check; + int tx_zlp; +}; + #endif /* end of ifndef _CPPI_DMA_H_ */ diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 39fd95833eb8..74fc3069cb42 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -102,6 +102,7 @@ #include <linux/usb.h> #include "musb_core.h" +#include "musb_trace.h" #define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON) @@ -258,31 +259,43 @@ static u32 musb_default_busctl_offset(u8 epnum, u16 offset) static u8 musb_default_readb(const void __iomem *addr, unsigned offset) { - return __raw_readb(addr + offset); + u8 data = __raw_readb(addr + offset); + + trace_musb_readb(__builtin_return_address(0), addr, offset, data); + return data; } static void musb_default_writeb(void __iomem *addr, unsigned offset, u8 data) { + trace_musb_writeb(__builtin_return_address(0), addr, offset, data); __raw_writeb(data, addr + offset); } static u16 musb_default_readw(const void __iomem *addr, unsigned offset) { - return __raw_readw(addr + offset); + u16 data = __raw_readw(addr + offset); + + trace_musb_readw(__builtin_return_address(0), addr, offset, data); + return data; } static void musb_default_writew(void __iomem *addr, unsigned offset, u16 data) { + trace_musb_writew(__builtin_return_address(0), addr, offset, data); __raw_writew(data, addr + offset); } static u32 musb_default_readl(const void __iomem *addr, unsigned offset) { - return __raw_readl(addr + offset); + u32 data = __raw_readl(addr + offset); + + trace_musb_readl(__builtin_return_address(0), addr, offset, data); + return data; } static void musb_default_writel(void __iomem *addr, unsigned offset, u32 data) { + trace_musb_writel(__builtin_return_address(0), addr, offset, data); __raw_writel(data, addr + offset); } @@ -461,20 +474,21 @@ static void musb_otg_timer_func(unsigned long data) spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->otg->state) { case OTG_STATE_B_WAIT_ACON: - dev_dbg(musb->controller, "HNP: b_wait_acon timeout; back to b_peripheral\n"); + musb_dbg(musb, + "HNP: b_wait_acon timeout; back to b_peripheral"); musb_g_disconnect(musb); musb->xceiv->otg->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", + musb_dbg(musb, "HNP: %s timeout", usb_otg_state_string(musb->xceiv->otg->state)); musb_platform_set_vbus(musb, 0); musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; break; default: - dev_dbg(musb->controller, "HNP: Unhandled mode %s\n", + musb_dbg(musb, "HNP: Unhandled mode %s", usb_otg_state_string(musb->xceiv->otg->state)); } spin_unlock_irqrestore(&musb->lock, flags); @@ -489,17 +503,17 @@ void musb_hnp_stop(struct musb *musb) void __iomem *mbase = musb->mregs; u8 reg; - dev_dbg(musb->controller, "HNP: stop from %s\n", + musb_dbg(musb, "HNP: stop from %s", usb_otg_state_string(musb->xceiv->otg->state)); switch (musb->xceiv->otg->state) { case OTG_STATE_A_PERIPHERAL: musb_g_disconnect(musb); - dev_dbg(musb->controller, "HNP: back to %s\n", + musb_dbg(musb, "HNP: back to %s", usb_otg_state_string(musb->xceiv->otg->state)); break; case OTG_STATE_B_HOST: - dev_dbg(musb->controller, "HNP: Disabling HR\n"); + musb_dbg(musb, "HNP: Disabling HR"); if (hcd) hcd->self.is_b_host = 0; musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; @@ -510,7 +524,7 @@ void musb_hnp_stop(struct musb *musb) /* REVISIT: Start SESSION_REQUEST here? */ break; default: - dev_dbg(musb->controller, "HNP: Stopping in unknown state %s\n", + musb_dbg(musb, "HNP: Stopping in unknown state %s", usb_otg_state_string(musb->xceiv->otg->state)); } @@ -541,8 +555,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, { irqreturn_t handled = IRQ_NONE; - dev_dbg(musb->controller, "<== DevCtl=%02x, int_usb=0x%x\n", devctl, - int_usb); + musb_dbg(musb, "<== DevCtl=%02x, int_usb=0x%x", devctl, int_usb); /* in host mode, the peripheral may issue remote wakeup. * in peripheral mode, the host may resume the link. @@ -550,7 +563,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, */ if (int_usb & MUSB_INTR_RESUME) { handled = IRQ_HANDLED; - dev_dbg(musb->controller, "RESUME (%s)\n", + musb_dbg(musb, "RESUME (%s)", usb_otg_state_string(musb->xceiv->otg->state)); if (devctl & MUSB_DEVCTL_HM) { @@ -619,11 +632,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS && (devctl & MUSB_DEVCTL_BDEVICE)) { - dev_dbg(musb->controller, "SessReq while on B state\n"); + musb_dbg(musb, "SessReq while on B state"); return IRQ_HANDLED; } - dev_dbg(musb->controller, "SESSION_REQUEST (%s)\n", + musb_dbg(musb, "SESSION_REQUEST (%s)", usb_otg_state_string(musb->xceiv->otg->state)); /* IRQ arrives from ID pin sense or (later, if VBUS power @@ -714,7 +727,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } if (int_usb & MUSB_INTR_SUSPEND) { - dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x\n", + musb_dbg(musb, "SUSPEND (%s) devctl %02x", usb_otg_state_string(musb->xceiv->otg->state), devctl); handled = IRQ_HANDLED; @@ -743,7 +756,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb->is_active = musb->g.b_hnp_enable; if (musb->is_active) { musb->xceiv->otg->state = OTG_STATE_B_WAIT_ACON; - dev_dbg(musb->controller, "HNP: Setting timer for b_ase0_brst\n"); + musb_dbg(musb, "HNP: Setting timer for b_ase0_brst"); mod_timer(&musb->otg_timer, jiffies + msecs_to_jiffies( OTG_TIME_B_ASE0_BRST)); @@ -760,7 +773,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, break; case OTG_STATE_B_HOST: /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ - dev_dbg(musb->controller, "REVISIT: SUSPEND as B_HOST\n"); + musb_dbg(musb, "REVISIT: SUSPEND as B_HOST"); break; default: /* "should not happen" */ @@ -797,14 +810,14 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, switch (musb->xceiv->otg->state) { case OTG_STATE_B_PERIPHERAL: if (int_usb & MUSB_INTR_SUSPEND) { - dev_dbg(musb->controller, "HNP: SUSPEND+CONNECT, now b_host\n"); + musb_dbg(musb, "HNP: SUSPEND+CONNECT, now b_host"); int_usb &= ~MUSB_INTR_SUSPEND; goto b_host; } else - dev_dbg(musb->controller, "CONNECT as b_peripheral???\n"); + musb_dbg(musb, "CONNECT as b_peripheral???"); break; case OTG_STATE_B_WAIT_ACON: - dev_dbg(musb->controller, "HNP: CONNECT, now b_host\n"); + musb_dbg(musb, "HNP: CONNECT, now b_host"); b_host: musb->xceiv->otg->state = OTG_STATE_B_HOST; if (musb->hcd) @@ -823,12 +836,12 @@ b_host: musb_host_poke_root_hub(musb); - dev_dbg(musb->controller, "CONNECT (%s) devctl %02x\n", + musb_dbg(musb, "CONNECT (%s) devctl %02x", usb_otg_state_string(musb->xceiv->otg->state), devctl); } if (int_usb & MUSB_INTR_DISCONNECT) { - dev_dbg(musb->controller, "DISCONNECT (%s) as %s, devctl %02x\n", + musb_dbg(musb, "DISCONNECT (%s) as %s, devctl %02x", usb_otg_state_string(musb->xceiv->otg->state), MUSB_MODE(musb), devctl); handled = IRQ_HANDLED; @@ -891,7 +904,7 @@ b_host: if (is_host_active(musb)) musb_recover_from_babble(musb); } else { - dev_dbg(musb->controller, "BUS RESET as %s\n", + musb_dbg(musb, "BUS RESET as %s", usb_otg_state_string(musb->xceiv->otg->state)); switch (musb->xceiv->otg->state) { case OTG_STATE_A_SUSPEND: @@ -899,7 +912,7 @@ b_host: /* 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", + musb_dbg(musb, "HNP: in %s, %d msec timeout", usb_otg_state_string(musb->xceiv->otg->state), TA_WAIT_BCON(musb)); mod_timer(&musb->otg_timer, jiffies @@ -910,7 +923,7 @@ b_host: musb_g_reset(musb); break; case OTG_STATE_B_WAIT_ACON: - dev_dbg(musb->controller, "HNP: RESET (%s), to b_peripheral\n", + musb_dbg(musb, "HNP: RESET (%s), to b_peripheral", usb_otg_state_string(musb->xceiv->otg->state)); musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; musb_g_reset(musb); @@ -922,7 +935,7 @@ b_host: musb_g_reset(musb); break; default: - dev_dbg(musb->controller, "Unhandled BUS RESET as %s\n", + musb_dbg(musb, "Unhandled BUS RESET as %s", usb_otg_state_string(musb->xceiv->otg->state)); } } @@ -1030,7 +1043,7 @@ void musb_start(struct musb *musb) u8 devctl = musb_readb(regs, MUSB_DEVCTL); u8 power; - dev_dbg(musb->controller, "<== devctl %02x\n", devctl); + musb_dbg(musb, "<== devctl %02x", devctl); musb_enable_interrupts(musb); musb_writeb(regs, MUSB_TESTMODE, 0); @@ -1078,7 +1091,7 @@ void musb_stop(struct musb *musb) /* stop IRQs, timers, ... */ musb_platform_disable(musb); musb_generic_disable(musb); - dev_dbg(musb->controller, "HDRC disabled\n"); + musb_dbg(musb, "HDRC disabled"); /* FIXME * - mark host and/or peripheral drivers unusable/inactive @@ -1090,29 +1103,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; - - pm_runtime_get_sync(musb->controller); - - musb_host_cleanup(musb); - musb_gadget_cleanup(musb); - - spin_lock_irqsave(&musb->lock, flags); - musb_platform_disable(musb); - musb_generic_disable(musb); - spin_unlock_irqrestore(&musb->lock, flags); - - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); - musb_platform_exit(musb); - - pm_runtime_put(musb->controller); - /* FIXME power down */ -} - - /*-------------------------------------------------------------------------*/ /* @@ -1414,7 +1404,7 @@ static int ep_config_from_hw(struct musb *musb) void __iomem *mbase = musb->mregs; int ret = 0; - dev_dbg(musb->controller, "<== static silicon ep config\n"); + musb_dbg(musb, "<== static silicon ep config"); /* FIXME pick up ep0 maxpacket size */ @@ -1555,8 +1545,7 @@ static int musb_core_init(u16 musb_type, struct musb *musb) hw_ep->tx_reinit = 1; if (hw_ep->max_packet_sz_tx) { - dev_dbg(musb->controller, - "%s: hw_ep %d%s, %smax %d\n", + musb_dbg(musb, "%s: hw_ep %d%s, %smax %d", musb_driver_name, i, hw_ep->is_shared_fifo ? "shared" : "tx", hw_ep->tx_double_buffered @@ -1564,8 +1553,7 @@ static int musb_core_init(u16 musb_type, struct musb *musb) hw_ep->max_packet_sz_tx); } if (hw_ep->max_packet_sz_rx && !hw_ep->is_shared_fifo) { - dev_dbg(musb->controller, - "%s: hw_ep %d%s, %smax %d\n", + musb_dbg(musb, "%s: hw_ep %d%s, %smax %d", musb_driver_name, i, "rx", hw_ep->rx_double_buffered @@ -1573,7 +1561,7 @@ static int musb_core_init(u16 musb_type, struct musb *musb) hw_ep->max_packet_sz_rx); } if (!(hw_ep->max_packet_sz_tx || hw_ep->max_packet_sz_rx)) - dev_dbg(musb->controller, "hw_ep %d not configured\n", i); + musb_dbg(musb, "hw_ep %d not configured", i); } return 0; @@ -1600,9 +1588,7 @@ irqreturn_t musb_interrupt(struct musb *musb) devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n", - is_host_active(musb) ? "host" : "peripheral", - musb->int_usb, musb->int_tx, musb->int_rx); + trace_musb_isr(musb); /** * According to Mentor Graphics' documentation, flowchart on page 98, @@ -1702,7 +1688,7 @@ EXPORT_SYMBOL_GPL(musb_dma_completion); #define use_dma 0 #endif -static void (*musb_phy_callback)(enum musb_vbus_id_status status); +static int (*musb_phy_callback)(enum musb_vbus_id_status status); /* * musb_mailbox - optional phy notifier function @@ -1711,11 +1697,12 @@ static void (*musb_phy_callback)(enum musb_vbus_id_status status); * Optionally gets called from the USB PHY. Note that the USB PHY must be * disabled at the point the phy_callback is registered or unregistered. */ -void musb_mailbox(enum musb_vbus_id_status status) +int musb_mailbox(enum musb_vbus_id_status status) { if (musb_phy_callback) - musb_phy_callback(status); + return musb_phy_callback(status); + return -ENODEV; }; EXPORT_SYMBOL_GPL(musb_mailbox); @@ -1998,7 +1985,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) * Fail when the board needs a feature that's not enabled. */ if (!plat) { - dev_dbg(dev, "no platform_data?\n"); + dev_err(dev, "no platform_data?\n"); status = -ENODEV; goto fail0; } @@ -2028,11 +2015,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb_readl = musb_default_readl; musb_writel = musb_default_writel; - /* We need musb_read/write functions initialized for PM */ - pm_runtime_use_autosuspend(musb->controller); - pm_runtime_set_autosuspend_delay(musb->controller, 200); - pm_runtime_enable(musb->controller); - /* The musb_platform_init() call: * - adjusts musb->mregs * - sets the musb->isr @@ -2134,6 +2116,16 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (musb->ops->phy_callback) musb_phy_callback = musb->ops->phy_callback; + /* + * We need musb_read/write functions initialized for PM. + * Note that at least 2430 glue needs autosuspend delay + * somewhere above 300 ms for the hardware to idle properly + * after disconnecting the cable in host mode. Let's use + * 500 ms for some margin. + */ + pm_runtime_use_autosuspend(musb->controller); + pm_runtime_set_autosuspend_delay(musb->controller, 500); + pm_runtime_enable(musb->controller); pm_runtime_get_sync(musb->controller); status = usb_phy_init(musb->xceiv); @@ -2237,13 +2229,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (status) goto fail5; - pm_runtime_put(musb->controller); - - /* - * For why this is currently needed, see commit 3e43a0725637 - * ("usb: musb: core: add pm_runtime_irq_safe()") - */ - pm_runtime_irq_safe(musb->controller); + pm_runtime_mark_last_busy(musb->controller); + pm_runtime_put_autosuspend(musb->controller); return 0; @@ -2265,7 +2252,9 @@ fail2_5: usb_phy_shutdown(musb->xceiv); err_usb_phy_init: + pm_runtime_dont_use_autosuspend(musb->controller); pm_runtime_put_sync(musb->controller); + pm_runtime_disable(musb->controller); fail2: if (musb->irq_wake) @@ -2273,7 +2262,6 @@ fail2: musb_platform_exit(musb); fail1: - pm_runtime_disable(musb->controller); dev_err(musb->controller, "musb_init_controller failed with status %d\n", status); @@ -2312,6 +2300,7 @@ static int musb_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct musb *musb = dev_to_musb(dev); + unsigned long flags; /* this gets called on rmmod. * - Host mode: host may still be active @@ -2319,17 +2308,26 @@ static int musb_remove(struct platform_device *pdev) * - OTG mode: both roles are deactivated (or never-activated) */ musb_exit_debugfs(musb); - musb_shutdown(pdev); - musb_phy_callback = NULL; - - if (musb->dma_controller) - musb_dma_controller_destroy(musb->dma_controller); - - usb_phy_shutdown(musb->xceiv); cancel_work_sync(&musb->irq_work); cancel_delayed_work_sync(&musb->finish_resume_work); cancel_delayed_work_sync(&musb->deassert_reset_work); + pm_runtime_get_sync(musb->controller); + musb_host_cleanup(musb); + musb_gadget_cleanup(musb); + spin_lock_irqsave(&musb->lock, flags); + musb_platform_disable(musb); + musb_generic_disable(musb); + spin_unlock_irqrestore(&musb->lock, flags); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + pm_runtime_dont_use_autosuspend(musb->controller); + pm_runtime_put_sync(musb->controller); + pm_runtime_disable(musb->controller); + musb_platform_exit(musb); + musb_phy_callback = NULL; + if (musb->dma_controller) + musb_dma_controller_destroy(musb->dma_controller); + usb_phy_shutdown(musb->xceiv); musb_free(musb); device_init_wakeup(dev, 0); return 0; @@ -2429,7 +2427,8 @@ static void musb_restore_context(struct musb *musb) musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe); musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); - musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); + if (musb->context.devctl & MUSB_DEVCTL_SESSION) + musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); for (i = 0; i < musb->config->num_eps; ++i) { struct musb_hw_ep *hw_ep; @@ -2612,7 +2611,6 @@ static struct platform_driver musb_driver = { }, .probe = musb_probe, .remove = musb_remove, - .shutdown = musb_shutdown, }; module_platform_driver(musb_driver); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index b6afe9e43305..b55a776b03eb 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -215,7 +215,7 @@ struct musb_platform_ops { dma_addr_t *dma_addr, u32 *len); void (*pre_root_reset_end)(struct musb *musb); void (*post_root_reset_end)(struct musb *musb); - void (*phy_callback)(enum musb_vbus_id_status status); + int (*phy_callback)(enum musb_vbus_id_status status); }; /* @@ -312,6 +312,7 @@ struct musb { struct work_struct irq_work; struct delayed_work deassert_reset_work; struct delayed_work finish_resume_work; + struct delayed_work gadget_work; u16 hwvers; u16 intrrxe; diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index e499b862a946..d4d7c56b48c7 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -5,7 +5,9 @@ #include <linux/platform_device.h> #include <linux/of.h> +#include "cppi_dma.h" #include "musb_core.h" +#include "musb_trace.h" #define RNDIS_REG(x) (0x80 + ((x - 1) * 4)) @@ -22,26 +24,6 @@ #define USB_CTRL_AUTOREQ 0xd0 #define USB_TDOWN 0xd8 -struct cppi41_dma_channel { - struct dma_channel channel; - struct cppi41_dma_controller *controller; - struct musb_hw_ep *hw_ep; - struct dma_chan *dc; - dma_cookie_t cookie; - u8 port_num; - u8 is_tx; - u8 is_allocated; - u8 usb_toggle; - - dma_addr_t buf_addr; - u32 total_len; - u32 prog_len; - u32 transferred; - u32 packet_sz; - struct list_head tx_check; - int tx_zlp; -}; - #define MUSB_DMA_NUM_CHANNELS 15 struct cppi41_dma_controller { @@ -96,8 +78,8 @@ static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel) if (!toggle && toggle == cppi41_channel->usb_toggle) { csr |= MUSB_RXCSR_H_DATATOGGLE | MUSB_RXCSR_H_WR_DATATOGGLE; musb_writew(cppi41_channel->hw_ep->regs, MUSB_RXCSR, csr); - dev_dbg(cppi41_channel->controller->musb->controller, - "Restoring DATA1 toggle.\n"); + musb_dbg(cppi41_channel->controller->musb, + "Restoring DATA1 toggle."); } cppi41_channel->usb_toggle = toggle; @@ -145,6 +127,8 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) csr = MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY; musb_writew(epio, MUSB_TXCSR, csr); } + + trace_musb_cppi41_done(cppi41_channel); musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); } else { /* next iteration, reload */ @@ -173,6 +157,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) dma_desc->callback = cppi41_dma_callback; dma_desc->callback_param = &cppi41_channel->channel; cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); + trace_musb_cppi41_cont(cppi41_channel); dma_async_issue_pending(dc); if (!cppi41_channel->is_tx) { @@ -240,10 +225,7 @@ static void cppi41_dma_callback(void *private_data) transferred = cppi41_channel->prog_len - txstate.residue; cppi41_channel->transferred += transferred; - dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n", - hw_ep->epnum, cppi41_channel->transferred, - cppi41_channel->total_len); - + trace_musb_cppi41_gb(cppi41_channel); update_rx_toggle(cppi41_channel); if (cppi41_channel->transferred == cppi41_channel->total_len || @@ -374,12 +356,6 @@ static bool cppi41_configure_channel(struct dma_channel *channel, struct musb *musb = cppi41_channel->controller->musb; unsigned use_gen_rndis = 0; - dev_dbg(musb->controller, - "configure ep%d/%x packet_sz=%d, mode=%d, dma_addr=0x%llx, len=%d is_tx=%d\n", - cppi41_channel->port_num, RNDIS_REG(cppi41_channel->port_num), - packet_sz, mode, (unsigned long long) dma_addr, - len, cppi41_channel->is_tx); - cppi41_channel->buf_addr = dma_addr; cppi41_channel->total_len = len; cppi41_channel->transferred = 0; @@ -431,6 +407,8 @@ static bool cppi41_configure_channel(struct dma_channel *channel, cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); cppi41_channel->channel.rx_packet_done = false; + trace_musb_cppi41_config(cppi41_channel); + save_rx_toggle(cppi41_channel); dma_async_issue_pending(dc); return true; @@ -461,6 +439,7 @@ static struct dma_channel *cppi41_dma_channel_allocate(struct dma_controller *c, cppi41_channel->hw_ep = hw_ep; cppi41_channel->is_allocated = 1; + trace_musb_cppi41_alloc(cppi41_channel); return &cppi41_channel->channel; } @@ -468,6 +447,7 @@ static void cppi41_dma_channel_release(struct dma_channel *channel) { struct cppi41_dma_channel *cppi41_channel = channel->private_data; + trace_musb_cppi41_free(cppi41_channel); if (cppi41_channel->is_allocated) { cppi41_channel->is_allocated = 0; channel->status = MUSB_DMA_STATUS_FREE; @@ -537,8 +517,7 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel) u16 csr; is_tx = cppi41_channel->is_tx; - dev_dbg(musb->controller, "abort channel=%d, is_tx=%d\n", - cppi41_channel->port_num, is_tx); + trace_musb_cppi41_abort(cppi41_channel); if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE) return 0; diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h index 27ba8f799462..9a78877a8afe 100644 --- a/drivers/usb/musb/musb_debug.h +++ b/drivers/usb/musb/musb_debug.h @@ -42,6 +42,8 @@ #define INFO(fmt, args...) yprintk(KERN_INFO, fmt, ## args) #define ERR(fmt, args...) yprintk(KERN_ERR, fmt, ## args) +void musb_dbg(struct musb *musb, const char *fmt, ...); + #ifdef CONFIG_DEBUG_FS int musb_init_debugfs(struct musb *musb); void musb_exit_debugfs(struct musb *musb); diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index eeb7d9ecf7df..2537179636db 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -52,30 +52,6 @@ static const struct of_device_id musb_dsps_of_match[]; /** - * avoid using musb_readx()/musb_writex() as glue layer should not be - * dependent on musb core layer symbols. - */ -static inline u8 dsps_readb(const void __iomem *addr, unsigned offset) -{ - return __raw_readb(addr + offset); -} - -static inline u32 dsps_readl(const void __iomem *addr, unsigned offset) -{ - return __raw_readl(addr + offset); -} - -static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data) -{ - __raw_writeb(data, addr + offset); -} - -static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data) -{ - __raw_writel(data, addr + offset); -} - -/** * DSPS musb wrapper register offset. * FIXME: This should be expanded to have all the wrapper registers from TI DSPS * musb ips. @@ -223,8 +199,8 @@ static void dsps_musb_enable(struct musb *musb) ((musb->epmask & wrp->rxep_mask) << wrp->rxep_shift); coremask = (wrp->usb_bitmap & ~MUSB_INTR_SOF); - dsps_writel(reg_base, wrp->epintr_set, epmask); - dsps_writel(reg_base, wrp->coreintr_set, coremask); + musb_writel(reg_base, wrp->epintr_set, epmask); + musb_writel(reg_base, wrp->coreintr_set, coremask); /* start polling for ID change in dual-role idle mode */ if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) @@ -244,10 +220,10 @@ static void dsps_musb_disable(struct musb *musb) const struct dsps_musb_wrapper *wrp = glue->wrp; void __iomem *reg_base = musb->ctrl_base; - dsps_writel(reg_base, wrp->coreintr_clear, wrp->usb_bitmap); - dsps_writel(reg_base, wrp->epintr_clear, + musb_writel(reg_base, wrp->coreintr_clear, wrp->usb_bitmap); + musb_writel(reg_base, wrp->epintr_clear, wrp->txep_bitmap | wrp->rxep_bitmap); - dsps_writeb(musb->mregs, MUSB_DEVCTL, 0); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); } static void otg_timer(unsigned long _musb) @@ -265,14 +241,14 @@ static void otg_timer(unsigned long _musb) * We poll because DSPS IP's won't expose several OTG-critical * status change events (from the transceiver) otherwise. */ - devctl = dsps_readb(mregs, MUSB_DEVCTL); + devctl = musb_readb(mregs, MUSB_DEVCTL); dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl, usb_otg_state_string(musb->xceiv->otg->state)); spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_BCON: - dsps_writeb(musb->mregs, MUSB_DEVCTL, 0); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); skip_session = 1; /* fall */ @@ -286,13 +262,13 @@ static void otg_timer(unsigned long _musb) MUSB_HST_MODE(musb); } if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) - dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); + musb_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); mod_timer(&glue->timer, jiffies + msecs_to_jiffies(wrp->poll_timeout)); break; case OTG_STATE_A_WAIT_VFALL: musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; - dsps_writel(musb->ctrl_base, wrp->coreintr_set, + musb_writel(musb->ctrl_base, wrp->coreintr_set, MUSB_INTR_VBUSERROR << wrp->usb_shift); break; default: @@ -315,29 +291,29 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) spin_lock_irqsave(&musb->lock, flags); /* Get endpoint interrupts */ - epintr = dsps_readl(reg_base, wrp->epintr_status); + epintr = musb_readl(reg_base, wrp->epintr_status); musb->int_rx = (epintr & wrp->rxep_bitmap) >> wrp->rxep_shift; musb->int_tx = (epintr & wrp->txep_bitmap) >> wrp->txep_shift; if (epintr) - dsps_writel(reg_base, wrp->epintr_status, epintr); + musb_writel(reg_base, wrp->epintr_status, epintr); /* Get usb core interrupts */ - usbintr = dsps_readl(reg_base, wrp->coreintr_status); + usbintr = musb_readl(reg_base, wrp->coreintr_status); if (!usbintr && !epintr) goto out; musb->int_usb = (usbintr & wrp->usb_bitmap) >> wrp->usb_shift; if (usbintr) - dsps_writel(reg_base, wrp->coreintr_status, usbintr); + musb_writel(reg_base, wrp->coreintr_status, usbintr); dev_dbg(musb->controller, "usbintr (%x) epintr(%x)\n", usbintr, epintr); if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) { - int drvvbus = dsps_readl(reg_base, wrp->status); + int drvvbus = musb_readl(reg_base, wrp->status); void __iomem *mregs = musb->mregs; - u8 devctl = dsps_readb(mregs, MUSB_DEVCTL); + u8 devctl = musb_readb(mregs, MUSB_DEVCTL); int err; err = musb->int_usb & MUSB_INTR_VBUSERROR; @@ -442,7 +418,7 @@ static int dsps_musb_init(struct musb *musb) musb->phy = devm_phy_get(dev->parent, "usb2-phy"); /* Returns zero if e.g. not clocked */ - rev = dsps_readl(reg_base, wrp->revision); + rev = musb_readl(reg_base, wrp->revision); if (!rev) return -ENODEV; @@ -463,14 +439,14 @@ static int dsps_musb_init(struct musb *musb) setup_timer(&glue->timer, otg_timer, (unsigned long) musb); /* Reset the musb */ - dsps_writel(reg_base, wrp->control, (1 << wrp->reset)); + musb_writel(reg_base, wrp->control, (1 << wrp->reset)); musb->isr = dsps_interrupt; /* reset the otgdisable bit, needed for host mode to work */ - val = dsps_readl(reg_base, wrp->phy_utmi); + val = musb_readl(reg_base, wrp->phy_utmi); val &= ~(1 << wrp->otg_disable); - dsps_writel(musb->ctrl_base, wrp->phy_utmi, val); + musb_writel(musb->ctrl_base, wrp->phy_utmi, val); /* * Check whether the dsps version has babble control enabled. @@ -478,11 +454,11 @@ static int dsps_musb_init(struct musb *musb) * If MUSB_BABBLE_CTL returns 0x4 then we have the babble control * logic enabled. */ - val = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); + val = musb_readb(musb->mregs, MUSB_BABBLE_CTL); if (val & MUSB_BABBLE_RCV_DISABLE) { glue->sw_babble_enabled = true; val |= MUSB_BABBLE_SW_SESSION_CTRL; - dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val); + musb_writeb(musb->mregs, MUSB_BABBLE_CTL, val); } return dsps_musb_dbg_init(musb, glue); @@ -510,7 +486,7 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) void __iomem *ctrl_base = musb->ctrl_base; u32 reg; - reg = dsps_readl(ctrl_base, wrp->mode); + reg = musb_readl(ctrl_base, wrp->mode); switch (mode) { case MUSB_HOST: @@ -523,8 +499,8 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) */ reg |= (1 << wrp->iddig_mux); - dsps_writel(ctrl_base, wrp->mode, reg); - dsps_writel(ctrl_base, wrp->phy_utmi, 0x02); + musb_writel(ctrl_base, wrp->mode, reg); + musb_writel(ctrl_base, wrp->phy_utmi, 0x02); break; case MUSB_PERIPHERAL: reg |= (1 << wrp->iddig); @@ -536,10 +512,10 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode) */ reg |= (1 << wrp->iddig_mux); - dsps_writel(ctrl_base, wrp->mode, reg); + musb_writel(ctrl_base, wrp->mode, reg); break; case MUSB_OTG: - dsps_writel(ctrl_base, wrp->phy_utmi, 0x02); + musb_writel(ctrl_base, wrp->phy_utmi, 0x02); break; default: dev_err(glue->dev, "unsupported mode %d\n", mode); @@ -554,7 +530,7 @@ static bool dsps_sw_babble_control(struct musb *musb) u8 babble_ctl; bool session_restart = false; - babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); + babble_ctl = musb_readb(musb->mregs, MUSB_BABBLE_CTL); dev_dbg(musb->controller, "babble: MUSB_BABBLE_CTL value %x\n", babble_ctl); /* @@ -571,14 +547,14 @@ static bool dsps_sw_babble_control(struct musb *musb) * babble is due to noise, then set transmit idle (d7 bit) * to resume normal operation */ - babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); + babble_ctl = musb_readb(musb->mregs, MUSB_BABBLE_CTL); babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE; - dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, babble_ctl); + musb_writeb(musb->mregs, MUSB_BABBLE_CTL, babble_ctl); /* wait till line monitor flag cleared */ dev_dbg(musb->controller, "Set TXIDLE, wait J to clear\n"); do { - babble_ctl = dsps_readb(musb->mregs, MUSB_BABBLE_CTL); + babble_ctl = musb_readb(musb->mregs, MUSB_BABBLE_CTL); udelay(1); } while ((babble_ctl & MUSB_BABBLE_STUCK_J) && timeout--); @@ -896,13 +872,13 @@ static int dsps_suspend(struct device *dev) return 0; mbase = musb->ctrl_base; - glue->context.control = dsps_readl(mbase, wrp->control); - glue->context.epintr = dsps_readl(mbase, wrp->epintr_set); - glue->context.coreintr = dsps_readl(mbase, wrp->coreintr_set); - glue->context.phy_utmi = dsps_readl(mbase, wrp->phy_utmi); - glue->context.mode = dsps_readl(mbase, wrp->mode); - glue->context.tx_mode = dsps_readl(mbase, wrp->tx_mode); - glue->context.rx_mode = dsps_readl(mbase, wrp->rx_mode); + glue->context.control = musb_readl(mbase, wrp->control); + glue->context.epintr = musb_readl(mbase, wrp->epintr_set); + glue->context.coreintr = musb_readl(mbase, wrp->coreintr_set); + glue->context.phy_utmi = musb_readl(mbase, wrp->phy_utmi); + glue->context.mode = musb_readl(mbase, wrp->mode); + glue->context.tx_mode = musb_readl(mbase, wrp->tx_mode); + glue->context.rx_mode = musb_readl(mbase, wrp->rx_mode); return 0; } @@ -918,13 +894,13 @@ static int dsps_resume(struct device *dev) return 0; mbase = musb->ctrl_base; - dsps_writel(mbase, wrp->control, glue->context.control); - dsps_writel(mbase, wrp->epintr_set, glue->context.epintr); - dsps_writel(mbase, wrp->coreintr_set, glue->context.coreintr); - dsps_writel(mbase, wrp->phy_utmi, glue->context.phy_utmi); - dsps_writel(mbase, wrp->mode, glue->context.mode); - dsps_writel(mbase, wrp->tx_mode, glue->context.tx_mode); - dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode); + musb_writel(mbase, wrp->control, glue->context.control); + musb_writel(mbase, wrp->epintr_set, glue->context.epintr); + musb_writel(mbase, wrp->coreintr_set, glue->context.coreintr); + musb_writel(mbase, wrp->phy_utmi, glue->context.phy_utmi); + musb_writel(mbase, wrp->mode, glue->context.mode); + musb_writel(mbase, wrp->tx_mode, glue->context.tx_mode); + musb_writel(mbase, wrp->rx_mode, glue->context.rx_mode); if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) mod_timer(&glue->timer, jiffies + diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 152865b36522..6d1e975e9605 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -44,6 +44,7 @@ #include <linux/slab.h> #include "musb_core.h" +#include "musb_trace.h" /* ----------------------------------------------------------------------- */ @@ -167,15 +168,7 @@ __acquires(ep->musb->lock) if (!dma_mapping_error(&musb->g.dev, request->dma)) unmap_dma_buffer(req, musb); - if (request->status == 0) - dev_dbg(musb->controller, "%s done request %p, %d/%d\n", - ep->end_point.name, request, - req->request.actual, req->request.length); - else - dev_dbg(musb->controller, "%s request %p, %d/%d fault %d\n", - ep->end_point.name, request, - req->request.actual, req->request.length, - request->status); + trace_musb_req_gb(req); usb_gadget_giveback_request(&req->ep->end_point, &req->request); spin_lock(&musb->lock); ep->busy = busy; @@ -217,8 +210,7 @@ static void nuke(struct musb_ep *ep, const int status) } value = c->channel_abort(ep->dma); - dev_dbg(musb->controller, "%s: abort DMA --> %d\n", - ep->name, value); + musb_dbg(musb, "%s: abort DMA --> %d", ep->name, value); c->channel_release(ep->dma); ep->dma = NULL; } @@ -266,14 +258,14 @@ static void txstate(struct musb *musb, struct musb_request *req) /* Check if EP is disabled */ if (!musb_ep->desc) { - dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", + musb_dbg(musb, "ep:%s disabled - ignore request", musb_ep->end_point.name); return; } /* we shouldn't get here while DMA is active ... but we do ... */ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { - dev_dbg(musb->controller, "dma pending...\n"); + musb_dbg(musb, "dma pending..."); return; } @@ -285,18 +277,18 @@ static void txstate(struct musb *musb, struct musb_request *req) (int)(request->length - request->actual)); if (csr & MUSB_TXCSR_TXPKTRDY) { - dev_dbg(musb->controller, "%s old packet still ready , txcsr %03x\n", + musb_dbg(musb, "%s old packet still ready , txcsr %03x", musb_ep->end_point.name, csr); return; } if (csr & MUSB_TXCSR_P_SENDSTALL) { - dev_dbg(musb->controller, "%s stalling, txcsr %03x\n", + musb_dbg(musb, "%s stalling, txcsr %03x", musb_ep->end_point.name, csr); return; } - dev_dbg(musb->controller, "hw_ep%d, maxpacket %d, fifo count %d, txcsr %03x\n", + musb_dbg(musb, "hw_ep%d, maxpacket %d, fifo count %d, txcsr %03x", epnum, musb_ep->packet_sz, fifo_count, csr); @@ -424,7 +416,7 @@ static void txstate(struct musb *musb, struct musb_request *req) } /* host may already have the data when this message shows... */ - dev_dbg(musb->controller, "%s TX/IN %s len %d/%d, txcsr %04x, fifo %d/%d\n", + musb_dbg(musb, "%s TX/IN %s len %d/%d, txcsr %04x, fifo %d/%d", musb_ep->end_point.name, use_dma ? "dma" : "pio", request->actual, request->length, musb_readw(epio, MUSB_TXCSR), @@ -450,8 +442,9 @@ void musb_g_tx(struct musb *musb, u8 epnum) req = next_request(musb_ep); request = &req->request; + trace_musb_req_tx(req); csr = musb_readw(epio, MUSB_TXCSR); - dev_dbg(musb->controller, "<== %s, txcsr %04x\n", musb_ep->end_point.name, csr); + musb_dbg(musb, "<== %s, txcsr %04x", musb_ep->end_point.name, csr); dma = is_dma_capable() ? musb_ep->dma : NULL; @@ -480,7 +473,7 @@ void musb_g_tx(struct musb *musb, u8 epnum) * SHOULD NOT HAPPEN... has with CPPI though, after * changing SENDSTALL (and other cases); harmless? */ - dev_dbg(musb->controller, "%s dma still busy?\n", musb_ep->end_point.name); + musb_dbg(musb, "%s dma still busy?", musb_ep->end_point.name); return; } @@ -497,7 +490,7 @@ void musb_g_tx(struct musb *musb, u8 epnum) /* Ensure writebuffer is empty. */ csr = musb_readw(epio, MUSB_TXCSR); request->actual += musb_ep->dma->actual_len; - dev_dbg(musb->controller, "TXCSR%d %04x, DMA off, len %zu, req %p\n", + musb_dbg(musb, "TXCSR%d %04x, DMA off, len %zu, req %p", epnum, csr, musb_ep->dma->actual_len, request); } @@ -524,7 +517,6 @@ void musb_g_tx(struct musb *musb, u8 epnum) if (csr & MUSB_TXCSR_TXPKTRDY) return; - dev_dbg(musb->controller, "sending zero pkt\n"); musb_writew(epio, MUSB_TXCSR, MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY); request->zero = 0; @@ -543,7 +535,7 @@ void musb_g_tx(struct musb *musb, u8 epnum) musb_ep_select(mbase, epnum); req = musb_ep->desc ? next_request(musb_ep) : NULL; if (!req) { - dev_dbg(musb->controller, "%s idle now\n", + musb_dbg(musb, "%s idle now", musb_ep->end_point.name); return; } @@ -579,19 +571,19 @@ static void rxstate(struct musb *musb, struct musb_request *req) /* Check if EP is disabled */ if (!musb_ep->desc) { - dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", + musb_dbg(musb, "ep:%s disabled - ignore request", musb_ep->end_point.name); return; } /* We shouldn't get here while DMA is active, but we do... */ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { - dev_dbg(musb->controller, "DMA pending...\n"); + musb_dbg(musb, "DMA pending..."); return; } if (csr & MUSB_RXCSR_P_SENDSTALL) { - dev_dbg(musb->controller, "%s stalling, RXCSR %04x\n", + musb_dbg(musb, "%s stalling, RXCSR %04x", musb_ep->end_point.name, csr); return; } @@ -766,7 +758,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) } len = request->length - request->actual; - dev_dbg(musb->controller, "%s OUT/RX pio fifo %d/%d, maxpacket %d\n", + musb_dbg(musb, "%s OUT/RX pio fifo %d/%d, maxpacket %d", musb_ep->end_point.name, fifo_count, len, musb_ep->packet_sz); @@ -849,12 +841,13 @@ void musb_g_rx(struct musb *musb, u8 epnum) if (!req) return; + trace_musb_req_rx(req); request = &req->request; csr = musb_readw(epio, MUSB_RXCSR); dma = is_dma_capable() ? musb_ep->dma : NULL; - dev_dbg(musb->controller, "<== %s, rxcsr %04x%s %p\n", musb_ep->end_point.name, + musb_dbg(musb, "<== %s, rxcsr %04x%s %p", musb_ep->end_point.name, csr, dma ? " (dma)" : "", request); if (csr & MUSB_RXCSR_P_SENTSTALL) { @@ -869,18 +862,18 @@ void musb_g_rx(struct musb *musb, u8 epnum) csr &= ~MUSB_RXCSR_P_OVERRUN; musb_writew(epio, MUSB_RXCSR, csr); - dev_dbg(musb->controller, "%s iso overrun on %p\n", musb_ep->name, request); + musb_dbg(musb, "%s iso overrun on %p", musb_ep->name, request); if (request->status == -EINPROGRESS) request->status = -EOVERFLOW; } if (csr & MUSB_RXCSR_INCOMPRX) { /* REVISIT not necessarily an error */ - dev_dbg(musb->controller, "%s, incomprx\n", musb_ep->end_point.name); + musb_dbg(musb, "%s, incomprx", musb_ep->end_point.name); } if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { /* "should not happen"; likely RXPKTRDY pending for DMA */ - dev_dbg(musb->controller, "%s busy, csr %04x\n", + musb_dbg(musb, "%s busy, csr %04x", musb_ep->end_point.name, csr); return; } @@ -894,11 +887,6 @@ void musb_g_rx(struct musb *musb, u8 epnum) request->actual += musb_ep->dma->actual_len; - dev_dbg(musb->controller, "RXCSR%d %04x, dma off, %04x, len %zu, req %p\n", - epnum, csr, - musb_readw(epio, MUSB_RXCSR), - musb_ep->dma->actual_len, request); - #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) || \ defined(CONFIG_USB_UX500_DMA) /* Autoclear doesn't clear RxPktRdy for short packets */ @@ -996,7 +984,7 @@ static int musb_gadget_enable(struct usb_ep *ep, ok = musb->hb_iso_rx; if (!ok) { - dev_dbg(musb->controller, "no support for high bandwidth ISO\n"); + musb_dbg(musb, "no support for high bandwidth ISO"); goto fail; } musb_ep->hb_mult = (tmp >> 11) & 3; @@ -1019,7 +1007,7 @@ static int musb_gadget_enable(struct usb_ep *ep, goto fail; if (tmp > hw_ep->max_packet_sz_tx) { - dev_dbg(musb->controller, "packet size beyond hardware FIFO size\n"); + musb_dbg(musb, "packet size beyond hardware FIFO size"); goto fail; } @@ -1062,7 +1050,7 @@ static int musb_gadget_enable(struct usb_ep *ep, goto fail; if (tmp > hw_ep->max_packet_sz_rx) { - dev_dbg(musb->controller, "packet size beyond hardware FIFO size\n"); + musb_dbg(musb, "packet size beyond hardware FIFO size"); goto fail; } @@ -1174,7 +1162,7 @@ static int musb_gadget_disable(struct usb_ep *ep) spin_unlock_irqrestore(&(musb->lock), flags); - dev_dbg(musb->controller, "%s\n", musb_ep->end_point.name); + musb_dbg(musb, "%s", musb_ep->end_point.name); return status; } @@ -1186,19 +1174,17 @@ static int musb_gadget_disable(struct usb_ep *ep) struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) { struct musb_ep *musb_ep = to_musb_ep(ep); - struct musb *musb = musb_ep->musb; struct musb_request *request = NULL; request = kzalloc(sizeof *request, gfp_flags); - if (!request) { - dev_dbg(musb->controller, "not enough memory\n"); + if (!request) return NULL; - } request->request.dma = DMA_ADDR_INVALID; request->epnum = musb_ep->current_epnum; request->ep = musb_ep; + trace_musb_req_alloc(request); return &request->request; } @@ -1208,7 +1194,10 @@ struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) */ void musb_free_request(struct usb_ep *ep, struct usb_request *req) { - kfree(to_musb_request(req)); + struct musb_request *request = to_musb_request(req); + + trace_musb_req_free(request); + kfree(request); } static LIST_HEAD(buffers); @@ -1225,10 +1214,7 @@ struct free_record { */ void musb_ep_restart(struct musb *musb, struct musb_request *req) { - dev_dbg(musb->controller, "<== %s request %p len %u on hw_ep%d\n", - req->tx ? "TX/IN" : "RX/OUT", - &req->request, req->request.length, req->epnum); - + trace_musb_req_start(req); musb_ep_select(musb->mregs, req->epnum); if (req->tx) txstate(musb, req); @@ -1259,7 +1245,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, if (request->ep != musb_ep) return -EINVAL; - dev_dbg(musb->controller, "<== to %s request=%p\n", ep->name, req); + trace_musb_req_enq(request); /* request is mine now... */ request->request.actual = 0; @@ -1273,7 +1259,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, /* don't queue if the ep is down */ if (!musb_ep->desc) { - dev_dbg(musb->controller, "req %p queued to %s while ep %s\n", + musb_dbg(musb, "req %p queued to %s while ep %s", req, ep->name, "disabled"); status = -ESHUTDOWN; unmap_dma_buffer(request, musb); @@ -1301,9 +1287,11 @@ static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request) int status = 0; struct musb *musb = musb_ep->musb; - if (!ep || !request || to_musb_request(request)->ep != musb_ep) + if (!ep || !request || req->ep != musb_ep) return -EINVAL; + trace_musb_req_deq(req); + spin_lock_irqsave(&musb->lock, flags); list_for_each_entry(r, &musb_ep->req_list, list) { @@ -1311,7 +1299,8 @@ static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request) break; } if (r != req) { - dev_dbg(musb->controller, "request %p not queued to %s\n", request, ep->name); + dev_err(musb->controller, "request %p not queued to %s\n", + request, ep->name); status = -EINVAL; goto done; } @@ -1377,7 +1366,7 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value) request = next_request(musb_ep); if (value) { if (request) { - dev_dbg(musb->controller, "request in progress, cannot halt %s\n", + musb_dbg(musb, "request in progress, cannot halt %s", ep->name); status = -EAGAIN; goto done; @@ -1386,7 +1375,8 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value) if (musb_ep->is_in) { csr = musb_readw(epio, MUSB_TXCSR); if (csr & MUSB_TXCSR_FIFONOTEMPTY) { - dev_dbg(musb->controller, "FIFO busy, cannot halt %s\n", ep->name); + musb_dbg(musb, "FIFO busy, cannot halt %s", + ep->name); status = -EAGAIN; goto done; } @@ -1395,7 +1385,7 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value) musb_ep->wedged = 0; /* set/clear the stall and toggle bits */ - dev_dbg(musb->controller, "%s: %s stall\n", ep->name, value ? "set" : "clear"); + musb_dbg(musb, "%s: %s stall", ep->name, value ? "set" : "clear"); if (musb_ep->is_in) { csr = musb_readw(epio, MUSB_TXCSR); csr |= MUSB_TXCSR_P_WZC_BITS @@ -1422,7 +1412,7 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value) /* maybe start the first request in the queue */ if (!musb_ep->busy && !value && request) { - dev_dbg(musb->controller, "restarting the request\n"); + musb_dbg(musb, "restarting the request"); musb_ep_restart(musb, request); } @@ -1558,7 +1548,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) case OTG_STATE_B_IDLE: /* Start SRP ... OTG not required. */ devctl = musb_readb(mregs, MUSB_DEVCTL); - dev_dbg(musb->controller, "Sending SRP: devctl: %02x\n", devctl); + musb_dbg(musb, "Sending SRP: devctl: %02x", devctl); devctl |= MUSB_DEVCTL_SESSION; musb_writeb(mregs, MUSB_DEVCTL, devctl); devctl = musb_readb(mregs, MUSB_DEVCTL); @@ -1586,7 +1576,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) status = 0; goto done; default: - dev_dbg(musb->controller, "Unhandled wake: %s\n", + musb_dbg(musb, "Unhandled wake: %s", usb_otg_state_string(musb->xceiv->otg->state)); goto done; } @@ -1596,7 +1586,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) power = musb_readb(mregs, MUSB_POWER); power |= MUSB_POWER_RESUME; musb_writeb(mregs, MUSB_POWER, power); - dev_dbg(musb->controller, "issue wakeup\n"); + musb_dbg(musb, "issue wakeup"); /* FIXME do this next chunk in a timer callback, no udelay */ mdelay(2); @@ -1628,7 +1618,7 @@ static void musb_pullup(struct musb *musb, int is_on) /* FIXME if on, HdrcStart; if off, HdrcStop */ - dev_dbg(musb->controller, "gadget D+ pullup %s\n", + musb_dbg(musb, "gadget D+ pullup %s", is_on ? "on" : "off"); musb_writeb(musb->mregs, MUSB_POWER, power); } @@ -1636,7 +1626,7 @@ static void musb_pullup(struct musb *musb, int is_on) #if 0 static int musb_gadget_vbus_session(struct usb_gadget *gadget, int is_active) { - dev_dbg(musb->controller, "<= %s =>\n", __func__); + musb_dbg(musb, "<= %s =>\n", __func__); /* * FIXME iff driver's softconnect flag is set (as it is during probe, @@ -1656,6 +1646,20 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) return usb_phy_set_power(musb->xceiv, mA); } +static void musb_gadget_work(struct work_struct *work) +{ + struct musb *musb; + unsigned long flags; + + musb = container_of(work, struct musb, gadget_work.work); + pm_runtime_get_sync(musb->controller); + spin_lock_irqsave(&musb->lock, flags); + musb_pullup(musb, musb->softconnect); + spin_unlock_irqrestore(&musb->lock, flags); + pm_runtime_mark_last_busy(musb->controller); + pm_runtime_put_autosuspend(musb->controller); +} + static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) { struct musb *musb = gadget_to_musb(gadget); @@ -1663,20 +1667,16 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) is_on = !!is_on; - pm_runtime_get_sync(musb->controller); - /* NOTE: this assumes we are sensing vbus; we'd rather * not pullup unless the B-session is active. */ spin_lock_irqsave(&musb->lock, flags); if (is_on != musb->softconnect) { musb->softconnect = is_on; - musb_pullup(musb, is_on); + schedule_delayed_work(&musb->gadget_work, 0); } spin_unlock_irqrestore(&musb->lock, flags); - pm_runtime_put(musb->controller); - return 0; } @@ -1845,7 +1845,7 @@ int musb_gadget_setup(struct musb *musb) #elif IS_ENABLED(CONFIG_USB_MUSB_GADGET) musb->g.is_otg = 0; #endif - + INIT_DELAYED_WORK(&musb->gadget_work, musb_gadget_work); musb_g_init_endpoints(musb); musb->is_active = 0; @@ -1866,6 +1866,8 @@ void musb_gadget_cleanup(struct musb *musb) { if (musb->port_mode == MUSB_PORT_MODE_HOST) return; + + cancel_delayed_work_sync(&musb->gadget_work); usb_del_gadget_udc(&musb->g); } @@ -1914,8 +1916,8 @@ static int musb_gadget_start(struct usb_gadget *g, if (musb->xceiv->last_event == USB_EVENT_ID) musb_platform_set_vbus(musb, 1); - if (musb->xceiv->last_event == USB_EVENT_NONE) - pm_runtime_put(musb->controller); + pm_runtime_mark_last_busy(musb->controller); + pm_runtime_put_autosuspend(musb->controller); return 0; @@ -1934,8 +1936,7 @@ static int musb_gadget_stop(struct usb_gadget *g) struct musb *musb = gadget_to_musb(g); unsigned long flags; - if (musb->xceiv->last_event == USB_EVENT_NONE) - pm_runtime_get_sync(musb->controller); + pm_runtime_get_sync(musb->controller); /* * REVISIT always use otg_set_peripheral() here too; @@ -1963,7 +1964,8 @@ static int musb_gadget_stop(struct usb_gadget *g) * that currently misbehaves. */ - pm_runtime_put(musb->controller); + pm_runtime_mark_last_busy(musb->controller); + pm_runtime_put_autosuspend(musb->controller); return 0; } @@ -1999,7 +2001,7 @@ void musb_g_suspend(struct musb *musb) u8 devctl; devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - dev_dbg(musb->controller, "devctl %02x\n", devctl); + musb_dbg(musb, "musb_g_suspend: devctl %02x", devctl); switch (musb->xceiv->otg->state) { case OTG_STATE_B_IDLE: @@ -2018,7 +2020,7 @@ void musb_g_suspend(struct musb *musb) /* REVISIT if B_HOST, clear DEVCTL.HOSTREQ; * A_PERIPHERAL may need care too */ - WARNING("unhandled SUSPEND transition (%s)\n", + WARNING("unhandled SUSPEND transition (%s)", usb_otg_state_string(musb->xceiv->otg->state)); } } @@ -2035,7 +2037,7 @@ void musb_g_disconnect(struct musb *musb) void __iomem *mregs = musb->mregs; u8 devctl = musb_readb(mregs, MUSB_DEVCTL); - dev_dbg(musb->controller, "devctl %02x\n", devctl); + musb_dbg(musb, "musb_g_disconnect: devctl %02x", devctl); /* clear HR */ musb_writeb(mregs, MUSB_DEVCTL, devctl & MUSB_DEVCTL_SESSION); @@ -2052,7 +2054,7 @@ void musb_g_disconnect(struct musb *musb) switch (musb->xceiv->otg->state) { default: - dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", + musb_dbg(musb, "Unhandled disconnect %s, setting a_idle", usb_otg_state_string(musb->xceiv->otg->state)); musb->xceiv->otg->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); @@ -2082,7 +2084,7 @@ __acquires(musb->lock) u8 devctl = musb_readb(mbase, MUSB_DEVCTL); u8 power; - dev_dbg(musb->controller, "<== %s driver '%s'\n", + musb_dbg(musb, "<== %s driver '%s'", (devctl & MUSB_DEVCTL_BDEVICE) ? "B-Device" : "A-Device", musb->gadget_driver diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 10d30afe4a3c..844a309fe895 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -206,7 +206,7 @@ static inline void musb_try_b_hnp_enable(struct musb *musb) void __iomem *mbase = musb->mregs; u8 devctl; - dev_dbg(musb->controller, "HNP: Setting HR\n"); + musb_dbg(musb, "HNP: Setting HR"); devctl = musb_readb(mbase, MUSB_DEVCTL); musb_writeb(mbase, MUSB_DEVCTL, devctl | MUSB_DEVCTL_HR); } @@ -303,7 +303,7 @@ __acquires(musb->lock) /* Maybe start the first request in the queue */ request = next_request(musb_ep); if (!musb_ep->busy && request) { - dev_dbg(musb->controller, "restarting the request\n"); + musb_dbg(musb, "restarting the request"); musb_ep_restart(musb, request); } @@ -550,7 +550,7 @@ static void ep0_txstate(struct musb *musb) if (!req) { /* WARN_ON(1); */ - dev_dbg(musb->controller, "odd; csr0 %04x\n", musb_readw(regs, MUSB_CSR0)); + musb_dbg(musb, "odd; csr0 %04x", musb_readw(regs, MUSB_CSR0)); return; } @@ -607,7 +607,7 @@ musb_read_setup(struct musb *musb, struct usb_ctrlrequest *req) /* NOTE: earlier 2.6 versions changed setup packets to host * order, but now USB packets always stay in USB byte order. */ - dev_dbg(musb->controller, "SETUP req%02x.%02x v%04x i%04x l%d\n", + musb_dbg(musb, "SETUP req%02x.%02x v%04x i%04x l%d", req->bRequestType, req->bRequest, le16_to_cpu(req->wValue), @@ -675,7 +675,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) csr = musb_readw(regs, MUSB_CSR0); len = musb_readb(regs, MUSB_COUNT0); - dev_dbg(musb->controller, "csr %04x, count %d, ep0stage %s\n", + musb_dbg(musb, "csr %04x, count %d, ep0stage %s", csr, len, decode_ep0stage(musb->ep0_state)); if (csr & MUSB_CSR0_P_DATAEND) { @@ -752,7 +752,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) /* enter test mode if needed (exit by reset) */ else if (musb->test_mode) { - dev_dbg(musb->controller, "entering TESTMODE\n"); + musb_dbg(musb, "entering TESTMODE"); if (MUSB_TEST_PACKET == musb->test_mode_nr) musb_load_testpacket(musb); @@ -864,7 +864,7 @@ setup: break; } - dev_dbg(musb->controller, "handled %d, csr %04x, ep0stage %s\n", + musb_dbg(musb, "handled %d, csr %04x, ep0stage %s", handled, csr, decode_ep0stage(musb->ep0_state)); @@ -881,7 +881,7 @@ setup: if (handled < 0) { musb_ep_select(mbase, 0); stall: - dev_dbg(musb->controller, "stall (%d)\n", handled); + musb_dbg(musb, "stall (%d)", handled); musb->ackpend |= MUSB_CSR0_P_SENDSTALL; musb->ep0_state = MUSB_EP0_STAGE_IDLE; finish: @@ -961,7 +961,7 @@ musb_g_ep0_queue(struct usb_ep *e, struct usb_request *r, gfp_t gfp_flags) status = 0; break; default: - dev_dbg(musb->controller, "ep0 request queued in state %d\n", + musb_dbg(musb, "ep0 request queued in state %d", musb->ep0_state); status = -EINVAL; goto cleanup; @@ -970,7 +970,7 @@ musb_g_ep0_queue(struct usb_ep *e, struct usb_request *r, gfp_t gfp_flags) /* add request to the list */ list_add_tail(&req->list, &ep->req_list); - dev_dbg(musb->controller, "queue to %s (%s), length=%d\n", + musb_dbg(musb, "queue to %s (%s), length=%d", ep->name, ep->is_in ? "IN/TX" : "OUT/RX", req->request.length); @@ -1063,7 +1063,7 @@ static int musb_g_ep0_halt(struct usb_ep *e, int value) musb->ackpend = 0; break; default: - dev_dbg(musb->controller, "ep0 can't halt in state %d\n", musb->ep0_state); + musb_dbg(musb, "ep0 can't halt in state %d", musb->ep0_state); status = -EINVAL; } diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 2f8ad7f1f482..53bc4ceefe89 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -44,6 +44,7 @@ #include "musb_core.h" #include "musb_host.h" +#include "musb_trace.h" /* MUSB HOST status 22-mar-2006 * @@ -131,7 +132,7 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) * I found using a usb-ethernet device and running iperf * (client on AM335x) has very high chance to trigger it. * - * Better to turn on dev_dbg() in musb_cleanup_urb() with + * Better to turn on musb_dbg() in musb_cleanup_urb() with * CPPI enabled to see the issue when aborting the tx channel. */ if (dev_WARN_ONCE(musb->controller, retries-- < 1, @@ -225,8 +226,6 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) void *buf = urb->transfer_buffer; u32 offset = 0; struct musb_hw_ep *hw_ep = qh->hw_ep; - unsigned pipe = urb->pipe; - u8 address = usb_pipedevice(pipe); int epnum = hw_ep->epnum; /* initialize software qh state */ @@ -254,16 +253,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) len = urb->transfer_buffer_length - urb->actual_length; } - dev_dbg(musb->controller, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n", - qh, urb, address, qh->epnum, - is_in ? "in" : "out", - ({char *s; switch (qh->type) { - case USB_ENDPOINT_XFER_CONTROL: s = ""; break; - case USB_ENDPOINT_XFER_BULK: s = "-bulk"; break; - case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break; - default: s = "-intr"; break; - } s; }), - epnum, buf + offset, len); + trace_musb_urb_start(musb, urb); /* Configure endpoint */ musb_ep_set_qh(hw_ep, is_in, qh); @@ -277,7 +267,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) switch (qh->type) { case USB_ENDPOINT_XFER_ISOC: case USB_ENDPOINT_XFER_INT: - dev_dbg(musb->controller, "check whether there's still time for periodic Tx\n"); + musb_dbg(musb, "check whether there's still time for periodic Tx"); frame = musb_readw(mbase, MUSB_FRAME); /* FIXME this doesn't implement that scheduling policy ... * or handle framecounter wrapping @@ -291,7 +281,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) } else { qh->frame = urb->start_frame; /* enable SOF interrupt so we can count down */ - dev_dbg(musb->controller, "SOF for %d\n", epnum); + musb_dbg(musb, "SOF for %d", epnum); #if 1 /* ifndef CONFIG_ARCH_DAVINCI */ musb_writeb(mbase, MUSB_INTRUSBE, 0xff); #endif @@ -299,7 +289,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) break; default: start: - dev_dbg(musb->controller, "Start TX%d %s\n", epnum, + musb_dbg(musb, "Start TX%d %s", epnum, hw_ep->tx_channel ? "dma" : "pio"); if (!hw_ep->tx_channel) @@ -314,14 +304,7 @@ static void musb_giveback(struct musb *musb, struct urb *urb, int status) __releases(musb->lock) __acquires(musb->lock) { - dev_dbg(musb->controller, - "complete %p %pF (%d), dev%d ep%d%s, %d/%d\n", - urb, urb->complete, status, - usb_pipedevice(urb->pipe), - usb_pipeendpoint(urb->pipe), - usb_pipein(urb->pipe) ? "in" : "out", - urb->actual_length, urb->transfer_buffer_length - ); + trace_musb_urb_gb(musb, urb); usb_hcd_unlink_urb_from_ep(musb->hcd, urb); spin_unlock(&musb->lock); @@ -434,8 +417,14 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, } } - if (qh != NULL && qh->is_ready) { - dev_dbg(musb->controller, "... next ep%d %cX urb %p\n", + /* + * The pipe must be broken if current urb->status is set, so don't + * start next urb. + * TODO: to minimize the risk of regression, only check urb->status + * for RX, until we have a test case to understand the behavior of TX. + */ + if ((!status || !is_in) && qh && qh->is_ready) { + musb_dbg(musb, "... next ep%d %cX urb %p", hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); musb_start_urb(musb, is_in, qh); } @@ -480,7 +469,7 @@ musb_host_packet_rx(struct musb *musb, struct urb *urb, u8 epnum, u8 iso_err) /* musb_ep_select(mbase, epnum); */ rx_count = musb_readw(epio, MUSB_RXCOUNT); - dev_dbg(musb->controller, "RX%d count %d, buffer %p len %d/%d\n", epnum, rx_count, + musb_dbg(musb, "RX%d count %d, buffer %p len %d/%d", epnum, rx_count, urb->transfer_buffer, qh->offset, urb->transfer_buffer_length); @@ -502,7 +491,7 @@ musb_host_packet_rx(struct musb *musb, struct urb *urb, u8 epnum, u8 iso_err) status = -EOVERFLOW; urb->error_count++; } - dev_dbg(musb->controller, "** OVERFLOW %d into %d\n", rx_count, length); + musb_dbg(musb, "OVERFLOW %d into %d", rx_count, length); do_flush = 1; } else length = rx_count; @@ -520,7 +509,7 @@ musb_host_packet_rx(struct musb *musb, struct urb *urb, u8 epnum, u8 iso_err) if (rx_count > length) { if (urb->status == -EINPROGRESS) urb->status = -EOVERFLOW; - dev_dbg(musb->controller, "** OVERFLOW %d into %d\n", rx_count, length); + musb_dbg(musb, "OVERFLOW %d into %d", rx_count, length); do_flush = 1; } else length = rx_count; @@ -594,14 +583,13 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum) musb_writew(ep->regs, MUSB_TXCSR, 0); /* scrub all previous state, clearing toggle */ - } else { - csr = musb_readw(ep->regs, MUSB_RXCSR); - if (csr & MUSB_RXCSR_RXPKTRDY) - WARNING("rx%d, packet/%d ready?\n", ep->epnum, - musb_readw(ep->regs, MUSB_RXCOUNT)); - - musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG); } + csr = musb_readw(ep->regs, MUSB_RXCSR); + if (csr & MUSB_RXCSR_RXPKTRDY) + WARNING("rx%d, packet/%d ready?\n", ep->epnum, + musb_readw(ep->regs, MUSB_RXCOUNT)); + + musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG); /* target addr and (for multipoint) hub addr/port */ if (musb->is_multipoint) { @@ -627,7 +615,7 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum) ep->rx_reinit = 0; } -static int musb_tx_dma_set_mode_mentor(struct dma_controller *dma, +static void musb_tx_dma_set_mode_mentor(struct dma_controller *dma, struct musb_hw_ep *hw_ep, struct musb_qh *qh, struct urb *urb, u32 offset, u32 *length, u8 *mode) @@ -664,23 +652,18 @@ static int musb_tx_dma_set_mode_mentor(struct dma_controller *dma, } channel->desired_mode = *mode; musb_writew(epio, MUSB_TXCSR, csr); - - return 0; } -static int musb_tx_dma_set_mode_cppi_tusb(struct dma_controller *dma, - struct musb_hw_ep *hw_ep, - struct musb_qh *qh, - struct urb *urb, - u32 offset, - u32 *length, - u8 *mode) +static void musb_tx_dma_set_mode_cppi_tusb(struct dma_controller *dma, + struct musb_hw_ep *hw_ep, + struct musb_qh *qh, + struct urb *urb, + u32 offset, + u32 *length, + u8 *mode) { struct dma_channel *channel = hw_ep->tx_channel; - if (!is_cppi_enabled(hw_ep->musb) && !tusb_dma_omap(hw_ep->musb)) - return -ENODEV; - channel->actual_len = 0; /* @@ -688,8 +671,6 @@ static int musb_tx_dma_set_mode_cppi_tusb(struct dma_controller *dma, * to identify the zero-length-final-packet case. */ *mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0; - - return 0; } static bool musb_tx_dma_program(struct dma_controller *dma, @@ -699,15 +680,14 @@ static bool musb_tx_dma_program(struct dma_controller *dma, struct dma_channel *channel = hw_ep->tx_channel; u16 pkt_size = qh->maxpacket; u8 mode; - int res; if (musb_dma_inventra(hw_ep->musb) || musb_dma_ux500(hw_ep->musb)) - res = musb_tx_dma_set_mode_mentor(dma, hw_ep, qh, urb, - offset, &length, &mode); + musb_tx_dma_set_mode_mentor(dma, hw_ep, qh, urb, offset, + &length, &mode); + else if (is_cppi_enabled(hw_ep->musb) || tusb_dma_omap(hw_ep->musb)) + musb_tx_dma_set_mode_cppi_tusb(dma, hw_ep, qh, urb, offset, + &length, &mode); else - res = musb_tx_dma_set_mode_cppi_tusb(dma, hw_ep, qh, urb, - offset, &length, &mode); - if (res) return false; qh->segsize = length; @@ -753,8 +733,8 @@ static void musb_ep_program(struct musb *musb, u8 epnum, u8 use_dma = 1; u16 csr; - dev_dbg(musb->controller, "%s hw%d urb %p spd%d dev%d ep%d%s " - "h_addr%02x h_port%02x bytes %d\n", + musb_dbg(musb, "%s hw%d urb %p spd%d dev%d ep%d%s " + "h_addr%02x h_port%02x bytes %d", is_out ? "-->" : "<--", epnum, urb, urb->dev->speed, qh->addr_reg, qh->epnum, is_out ? "out" : "in", @@ -972,7 +952,7 @@ finish: } csr |= MUSB_RXCSR_H_REQPKT; - dev_dbg(musb->controller, "RXCSR%d := %04x\n", epnum, csr); + musb_dbg(musb, "RXCSR%d := %04x", epnum, csr); musb_writew(hw_ep->regs, MUSB_RXCSR, csr); csr = musb_readw(hw_ep->regs, MUSB_RXCSR); } @@ -995,9 +975,15 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep, if (is_in) { dma = is_dma_capable() ? ep->rx_channel : NULL; - /* clear nak timeout bit */ + /* + * Need to stop the transaction by clearing REQPKT first + * then the NAK Timeout bit ref MUSBMHDRC USB 2.0 HIGH-SPEED + * DUAL-ROLE CONTROLLER Programmer's Guide, section 9.2.2 + */ rx_csr = musb_readw(epio, MUSB_RXCSR); rx_csr |= MUSB_RXCSR_H_WZC_BITS; + rx_csr &= ~MUSB_RXCSR_H_REQPKT; + musb_writew(epio, MUSB_RXCSR, rx_csr); rx_csr &= ~MUSB_RXCSR_DATAERROR; musb_writew(epio, MUSB_RXCSR, rx_csr); @@ -1082,15 +1068,15 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) request = (struct usb_ctrlrequest *) urb->setup_packet; if (!request->wLength) { - dev_dbg(musb->controller, "start no-DATA\n"); + musb_dbg(musb, "start no-DATA"); break; } else if (request->bRequestType & USB_DIR_IN) { - dev_dbg(musb->controller, "start IN-DATA\n"); + musb_dbg(musb, "start IN-DATA"); musb->ep0_stage = MUSB_EP0_IN; more = true; break; } else { - dev_dbg(musb->controller, "start OUT-DATA\n"); + musb_dbg(musb, "start OUT-DATA"); musb->ep0_stage = MUSB_EP0_OUT; more = true; } @@ -1102,7 +1088,7 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) if (fifo_count) { fifo_dest = (u8 *) (urb->transfer_buffer + urb->actual_length); - dev_dbg(musb->controller, "Sending %d byte%s to ep0 fifo %p\n", + musb_dbg(musb, "Sending %d byte%s to ep0 fifo %p", fifo_count, (fifo_count == 1) ? "" : "s", fifo_dest); @@ -1147,7 +1133,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) ? musb_readb(epio, MUSB_COUNT0) : 0; - dev_dbg(musb->controller, "<== csr0 %04x, qh %p, count %d, urb %p, stage %d\n", + musb_dbg(musb, "<== csr0 %04x, qh %p, count %d, urb %p, stage %d", csr, qh, len, urb, musb->ep0_stage); /* if we just did status stage, we are done */ @@ -1158,15 +1144,15 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) /* prepare status */ if (csr & MUSB_CSR0_H_RXSTALL) { - dev_dbg(musb->controller, "STALLING ENDPOINT\n"); + musb_dbg(musb, "STALLING ENDPOINT"); status = -EPIPE; } else if (csr & MUSB_CSR0_H_ERROR) { - dev_dbg(musb->controller, "no response, csr0 %04x\n", csr); + musb_dbg(musb, "no response, csr0 %04x", csr); status = -EPROTO; } else if (csr & MUSB_CSR0_H_NAKTIMEOUT) { - dev_dbg(musb->controller, "control NAK timeout\n"); + musb_dbg(musb, "control NAK timeout"); /* NOTE: this code path would be a good place to PAUSE a * control transfer, if another one is queued, so that @@ -1181,7 +1167,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) } if (status) { - dev_dbg(musb->controller, "aborting\n"); + musb_dbg(musb, "aborting"); retval = IRQ_HANDLED; if (urb) urb->status = status; @@ -1234,7 +1220,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) /* flag status stage */ musb->ep0_stage = MUSB_EP0_STATUS; - dev_dbg(musb->controller, "ep0 STATUS, csr %04x\n", csr); + musb_dbg(musb, "ep0 STATUS, csr %04x", csr); } musb_writew(epio, MUSB_CSR0, csr); @@ -1288,38 +1274,37 @@ void musb_host_tx(struct musb *musb, u8 epnum) /* with CPPI, DMA sometimes triggers "extra" irqs */ if (!urb) { - dev_dbg(musb->controller, "extra TX%d ready, csr %04x\n", epnum, tx_csr); + musb_dbg(musb, "extra TX%d ready, csr %04x", epnum, tx_csr); return; } pipe = urb->pipe; dma = is_dma_capable() ? hw_ep->tx_channel : NULL; - dev_dbg(musb->controller, "OUT/TX%d end, csr %04x%s\n", epnum, tx_csr, + trace_musb_urb_tx(musb, urb); + musb_dbg(musb, "OUT/TX%d end, csr %04x%s", epnum, tx_csr, dma ? ", dma" : ""); /* check for errors */ if (tx_csr & MUSB_TXCSR_H_RXSTALL) { /* dma was disabled, fifo flushed */ - dev_dbg(musb->controller, "TX end %d stall\n", epnum); + musb_dbg(musb, "TX end %d stall", epnum); /* stall; record URB status */ status = -EPIPE; } else if (tx_csr & MUSB_TXCSR_H_ERROR) { /* (NON-ISO) dma was disabled, fifo flushed */ - dev_dbg(musb->controller, "TX 3strikes on ep=%d\n", epnum); + musb_dbg(musb, "TX 3strikes on ep=%d", epnum); status = -ETIMEDOUT; } else if (tx_csr & MUSB_TXCSR_H_NAKTIMEOUT) { if (USB_ENDPOINT_XFER_BULK == qh->type && qh->mux == 1 && !list_is_singular(&musb->out_bulk)) { - dev_dbg(musb->controller, - "NAK timeout on TX%d ep\n", epnum); + musb_dbg(musb, "NAK timeout on TX%d ep", epnum); musb_bulk_nak_timeout(musb, hw_ep, 0); } else { - dev_dbg(musb->controller, - "TX end=%d device not responding\n", epnum); + musb_dbg(musb, "TX ep%d device not responding", epnum); /* NOTE: this code path would be a good place to PAUSE a * transfer, if there's some other (nonperiodic) tx urb * that could use this fifo. (dma complicates it...) @@ -1365,7 +1350,7 @@ done: /* second cppi case */ if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { - dev_dbg(musb->controller, "extra TX%d ready, csr %04x\n", epnum, tx_csr); + musb_dbg(musb, "extra TX%d ready, csr %04x", epnum, tx_csr); return; } @@ -1424,8 +1409,9 @@ done: * FIFO mode too... */ if (tx_csr & (MUSB_TXCSR_FIFONOTEMPTY | MUSB_TXCSR_TXPKTRDY)) { - dev_dbg(musb->controller, "DMA complete but packet still in FIFO, " - "CSR %04x\n", tx_csr); + musb_dbg(musb, + "DMA complete but FIFO not empty, CSR %04x", + tx_csr); return; } } @@ -1491,7 +1477,7 @@ done: return; } } else if (tx_csr & MUSB_TXCSR_DMAENAB) { - dev_dbg(musb->controller, "not complete, but DMA enabled?\n"); + musb_dbg(musb, "not complete, but DMA enabled?"); return; } @@ -1551,7 +1537,7 @@ static int musb_rx_dma_iso_cppi41(struct dma_controller *dma, struct urb *urb, size_t len) { - struct dma_channel *channel = hw_ep->tx_channel; + struct dma_channel *channel = hw_ep->rx_channel; void __iomem *epio = hw_ep->regs; dma_addr_t *buf; u32 length, res; @@ -1720,7 +1706,7 @@ static int musb_rx_dma_in_inventra_cppi41(struct dma_controller *dma, d_status = -EOVERFLOW; urb->error_count++; } - dev_dbg(musb->controller, "** OVERFLOW %d into %d\n", + musb_dbg(musb, "** OVERFLOW %d into %d", rx_count, d->length); length = d->length; @@ -1844,36 +1830,37 @@ void musb_host_rx(struct musb *musb, u8 epnum) * usbtest #11 (unlinks) triggers it regularly, sometimes * with fifo full. (Only with DMA??) */ - dev_dbg(musb->controller, "BOGUS RX%d ready, csr %04x, count %d\n", epnum, val, - musb_readw(epio, MUSB_RXCOUNT)); + musb_dbg(musb, "BOGUS RX%d ready, csr %04x, count %d", + epnum, val, musb_readw(epio, MUSB_RXCOUNT)); musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG); return; } pipe = urb->pipe; - dev_dbg(musb->controller, "<== hw %d rxcsr %04x, urb actual %d (+dma %zu)\n", - epnum, rx_csr, urb->actual_length, - dma ? dma->actual_len : 0); + trace_musb_urb_rx(musb, urb); /* check for errors, concurrent stall & unlink is not really * handled yet! */ if (rx_csr & MUSB_RXCSR_H_RXSTALL) { - dev_dbg(musb->controller, "RX end %d STALL\n", epnum); + musb_dbg(musb, "RX end %d STALL", epnum); /* stall; record URB status */ status = -EPIPE; } else if (rx_csr & MUSB_RXCSR_H_ERROR) { - dev_dbg(musb->controller, "end %d RX proto error\n", epnum); + musb_dbg(musb, "end %d RX proto error", epnum); status = -EPROTO; musb_writeb(epio, MUSB_RXINTERVAL, 0); + rx_csr &= ~MUSB_RXCSR_H_ERROR; + musb_writew(epio, MUSB_RXCSR, rx_csr); + } else if (rx_csr & MUSB_RXCSR_DATAERROR) { if (USB_ENDPOINT_XFER_ISOC != qh->type) { - dev_dbg(musb->controller, "RX end %d NAK timeout\n", epnum); + musb_dbg(musb, "RX end %d NAK timeout", epnum); /* NOTE: NAKing is *NOT* an error, so we want to * continue. Except ... if there's a request for @@ -1896,12 +1883,12 @@ void musb_host_rx(struct musb *musb, u8 epnum) goto finish; } else { - dev_dbg(musb->controller, "RX end %d ISO data error\n", epnum); + musb_dbg(musb, "RX end %d ISO data error", epnum); /* packet error reported later */ iso_err = true; } } else if (rx_csr & MUSB_RXCSR_INCOMPRX) { - dev_dbg(musb->controller, "end %d high bandwidth incomplete ISO packet RX\n", + musb_dbg(musb, "end %d high bandwidth incomplete ISO packet RX", epnum); status = -EPROTO; } @@ -1946,7 +1933,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) done = true; } - dev_dbg(musb->controller, "RXCSR%d %04x, reqpkt, len %zu%s\n", epnum, rx_csr, + musb_dbg(musb, "RXCSR%d %04x, reqpkt, len %zu%s", epnum, rx_csr, xfer_len, dma ? ", dma" : ""); rx_csr &= ~MUSB_RXCSR_H_REQPKT; @@ -1967,8 +1954,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) if (musb_dma_inventra(musb) || musb_dma_ux500(musb) || musb_dma_cppi41(musb)) { done = musb_rx_dma_inventra_cppi41(c, hw_ep, qh, urb, xfer_len); - dev_dbg(hw_ep->musb->controller, - "ep %d dma %s, rxcsr %04x, rxcount %d\n", + musb_dbg(hw_ep->musb, + "ep %d dma %s, rxcsr %04x, rxcount %d", epnum, done ? "off" : "reset", musb_readw(epio, MUSB_RXCSR), musb_readw(epio, MUSB_RXCOUNT)); @@ -1995,8 +1982,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) /* we are expecting IN packets */ if ((musb_dma_inventra(musb) || musb_dma_ux500(musb) || musb_dma_cppi41(musb)) && dma) { - dev_dbg(hw_ep->musb->controller, - "RX%d count %d, buffer 0x%llx len %d/%d\n", + musb_dbg(hw_ep->musb, + "RX%d count %d, buffer 0x%llx len %d/%d", epnum, musb_readw(epio, MUSB_RXCOUNT), (unsigned long long) urb->transfer_dma + urb->actual_length, @@ -2048,7 +2035,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) done = musb_host_packet_rx(musb, urb, epnum, iso_err); } - dev_dbg(musb->controller, "read %spacket\n", done ? "last " : ""); + musb_dbg(musb, "read %spacket", done ? "last " : ""); } } @@ -2172,7 +2159,7 @@ static int musb_schedule( idle = 1; qh->mux = 0; hw_ep = musb->endpoints + best_end; - dev_dbg(musb->controller, "qh %p periodic slot %d\n", qh, best_end); + musb_dbg(musb, "qh %p periodic slot %d", qh, best_end); success: if (head) { idle = list_empty(head); @@ -2204,6 +2191,8 @@ static int musb_urb_enqueue( if (!is_host_active(musb) || !musb->is_active) return -ENODEV; + trace_musb_urb_enq(musb, urb); + spin_lock_irqsave(&musb->lock, flags); ret = usb_hcd_link_urb_to_ep(hcd, urb); qh = ret ? NULL : hep->hcpriv; @@ -2394,8 +2383,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) dma = is_in ? ep->rx_channel : ep->tx_channel; if (dma) { status = ep->musb->dma_controller->channel_abort(dma); - dev_dbg(musb->controller, - "abort %cX%d DMA for urb %p --> %d\n", + musb_dbg(musb, "abort %cX%d DMA for urb %p --> %d", is_in ? 'R' : 'T', ep->epnum, urb, status); urb->actual_length += dma->actual_len; @@ -2441,10 +2429,7 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) int is_in = usb_pipein(urb->pipe); int ret; - dev_dbg(musb->controller, "urb=%p, dev%d ep%d%s\n", urb, - usb_pipedevice(urb->pipe), - usb_pipeendpoint(urb->pipe), - is_in ? "in" : "out"); + trace_musb_urb_deq(musb, urb); spin_lock_irqsave(&musb->lock, flags); ret = usb_hcd_check_unlink_urb(hcd, urb, status); diff --git a/drivers/usb/musb/musb_trace.c b/drivers/usb/musb/musb_trace.c new file mode 100644 index 000000000000..70973d901a21 --- /dev/null +++ b/drivers/usb/musb/musb_trace.c @@ -0,0 +1,33 @@ +/* + * musb_trace.c - MUSB Controller Trace Support + * + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com + * + * Author: Bin Liu <b-liu@ti.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 of + * the License as published by the Free Software Foundation. + * + * This program 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. + */ + +#define CREATE_TRACE_POINTS +#include "musb_trace.h" + +void musb_dbg(struct musb *musb, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + + trace_musb_log(musb, &vaf); + + va_end(args); +} diff --git a/drivers/usb/musb/musb_trace.h b/drivers/usb/musb/musb_trace.h new file mode 100644 index 000000000000..f031c9e74322 --- /dev/null +++ b/drivers/usb/musb/musb_trace.h @@ -0,0 +1,371 @@ +/* + * musb_trace.h - MUSB Controller Trace Support + * + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com + * + * Author: Bin Liu <b-liu@ti.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 of + * the License as published by the Free Software Foundation. + * + * This program 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. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM musb + +#if !defined(__MUSB_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define __MUSB_TRACE_H + +#include <linux/types.h> +#include <linux/tracepoint.h> +#include <linux/usb.h> +#include "musb_core.h" +#ifdef CONFIG_USB_TI_CPPI41_DMA +#include "cppi_dma.h" +#endif + +#define MUSB_MSG_MAX 500 + +TRACE_EVENT(musb_log, + TP_PROTO(struct musb *musb, struct va_format *vaf), + TP_ARGS(musb, vaf), + TP_STRUCT__entry( + __string(name, dev_name(musb->controller)) + __dynamic_array(char, msg, MUSB_MSG_MAX) + ), + TP_fast_assign( + __assign_str(name, dev_name(musb->controller)); + vsnprintf(__get_str(msg), MUSB_MSG_MAX, vaf->fmt, *vaf->va); + ), + TP_printk("%s: %s", __get_str(name), __get_str(msg)) +); + +DECLARE_EVENT_CLASS(musb_regb, + TP_PROTO(void *caller, const void *addr, unsigned int offset, u8 data), + TP_ARGS(caller, addr, offset, data), + TP_STRUCT__entry( + __field(void *, caller) + __field(const void *, addr) + __field(unsigned int, offset) + __field(u8, data) + ), + TP_fast_assign( + __entry->caller = caller; + __entry->addr = addr; + __entry->offset = offset; + __entry->data = data; + ), + TP_printk("%pS: %p + %04x: %02x", + __entry->caller, __entry->addr, __entry->offset, __entry->data) +); + +DEFINE_EVENT(musb_regb, musb_readb, + TP_PROTO(void *caller, const void *addr, unsigned int offset, u8 data), + TP_ARGS(caller, addr, offset, data) +); + +DEFINE_EVENT(musb_regb, musb_writeb, + TP_PROTO(void *caller, const void *addr, unsigned int offset, u8 data), + TP_ARGS(caller, addr, offset, data) +); + +DECLARE_EVENT_CLASS(musb_regw, + TP_PROTO(void *caller, const void *addr, unsigned int offset, u16 data), + TP_ARGS(caller, addr, offset, data), + TP_STRUCT__entry( + __field(void *, caller) + __field(const void *, addr) + __field(unsigned int, offset) + __field(u16, data) + ), + TP_fast_assign( + __entry->caller = caller; + __entry->addr = addr; + __entry->offset = offset; + __entry->data = data; + ), + TP_printk("%pS: %p + %04x: %04x", + __entry->caller, __entry->addr, __entry->offset, __entry->data) +); + +DEFINE_EVENT(musb_regw, musb_readw, + TP_PROTO(void *caller, const void *addr, unsigned int offset, u16 data), + TP_ARGS(caller, addr, offset, data) +); + +DEFINE_EVENT(musb_regw, musb_writew, + TP_PROTO(void *caller, const void *addr, unsigned int offset, u16 data), + TP_ARGS(caller, addr, offset, data) +); + +DECLARE_EVENT_CLASS(musb_regl, + TP_PROTO(void *caller, const void *addr, unsigned int offset, u32 data), + TP_ARGS(caller, addr, offset, data), + TP_STRUCT__entry( + __field(void *, caller) + __field(const void *, addr) + __field(unsigned int, offset) + __field(u32, data) + ), + TP_fast_assign( + __entry->caller = caller; + __entry->addr = addr; + __entry->offset = offset; + __entry->data = data; + ), + TP_printk("%pS: %p + %04x: %08x", + __entry->caller, __entry->addr, __entry->offset, __entry->data) +); + +DEFINE_EVENT(musb_regl, musb_readl, + TP_PROTO(void *caller, const void *addr, unsigned int offset, u32 data), + TP_ARGS(caller, addr, offset, data) +); + +DEFINE_EVENT(musb_regl, musb_writel, + TP_PROTO(void *caller, const void *addr, unsigned int offset, u32 data), + TP_ARGS(caller, addr, offset, data) +); + +TRACE_EVENT(musb_isr, + TP_PROTO(struct musb *musb), + TP_ARGS(musb), + TP_STRUCT__entry( + __string(name, dev_name(musb->controller)) + __field(u8, int_usb) + __field(u16, int_tx) + __field(u16, int_rx) + ), + TP_fast_assign( + __assign_str(name, dev_name(musb->controller)); + __entry->int_usb = musb->int_usb; + __entry->int_tx = musb->int_tx; + __entry->int_rx = musb->int_rx; + ), + TP_printk("%s: usb %02x, tx %04x, rx %04x", + __get_str(name), __entry->int_usb, + __entry->int_tx, __entry->int_rx + ) +); + +DECLARE_EVENT_CLASS(musb_urb, + TP_PROTO(struct musb *musb, struct urb *urb), + TP_ARGS(musb, urb), + TP_STRUCT__entry( + __string(name, dev_name(musb->controller)) + __field(struct urb *, urb) + __field(unsigned int, pipe) + __field(int, status) + __field(unsigned int, flag) + __field(u32, buf_len) + __field(u32, actual_len) + ), + TP_fast_assign( + __assign_str(name, dev_name(musb->controller)); + __entry->urb = urb; + __entry->pipe = urb->pipe; + __entry->status = urb->status; + __entry->flag = urb->transfer_flags; + __entry->buf_len = urb->transfer_buffer_length; + __entry->actual_len = urb->actual_length; + ), + TP_printk("%s: %p, dev%d ep%d%s, flag 0x%x, len %d/%d, status %d", + __get_str(name), __entry->urb, + usb_pipedevice(__entry->pipe), + usb_pipeendpoint(__entry->pipe), + usb_pipein(__entry->pipe) ? "in" : "out", + __entry->flag, + __entry->actual_len, __entry->buf_len, + __entry->status + ) +); + +DEFINE_EVENT(musb_urb, musb_urb_start, + TP_PROTO(struct musb *musb, struct urb *urb), + TP_ARGS(musb, urb) +); + +DEFINE_EVENT(musb_urb, musb_urb_gb, + TP_PROTO(struct musb *musb, struct urb *urb), + TP_ARGS(musb, urb) +); + +DEFINE_EVENT(musb_urb, musb_urb_rx, + TP_PROTO(struct musb *musb, struct urb *urb), + TP_ARGS(musb, urb) +); + +DEFINE_EVENT(musb_urb, musb_urb_tx, + TP_PROTO(struct musb *musb, struct urb *urb), + TP_ARGS(musb, urb) +); + +DEFINE_EVENT(musb_urb, musb_urb_enq, + TP_PROTO(struct musb *musb, struct urb *urb), + TP_ARGS(musb, urb) +); + +DEFINE_EVENT(musb_urb, musb_urb_deq, + TP_PROTO(struct musb *musb, struct urb *urb), + TP_ARGS(musb, urb) +); + +DECLARE_EVENT_CLASS(musb_req, + TP_PROTO(struct musb_request *req), + TP_ARGS(req), + TP_STRUCT__entry( + __field(struct usb_request *, req) + __field(u8, is_tx) + __field(u8, epnum) + __field(int, status) + __field(unsigned int, buf_len) + __field(unsigned int, actual_len) + __field(unsigned int, zero) + __field(unsigned int, short_not_ok) + __field(unsigned int, no_interrupt) + ), + TP_fast_assign( + __entry->req = &req->request; + __entry->is_tx = req->tx; + __entry->epnum = req->epnum; + __entry->status = req->request.status; + __entry->buf_len = req->request.length; + __entry->actual_len = req->request.actual; + __entry->zero = req->request.zero; + __entry->short_not_ok = req->request.short_not_ok; + __entry->no_interrupt = req->request.no_interrupt; + ), + TP_printk("%p, ep%d %s, %s%s%s, len %d/%d, status %d", + __entry->req, __entry->epnum, + __entry->is_tx ? "tx/IN" : "rx/OUT", + __entry->zero ? "Z" : "z", + __entry->short_not_ok ? "S" : "s", + __entry->no_interrupt ? "I" : "i", + __entry->actual_len, __entry->buf_len, + __entry->status + ) +); + +DEFINE_EVENT(musb_req, musb_req_gb, + TP_PROTO(struct musb_request *req), + TP_ARGS(req) +); + +DEFINE_EVENT(musb_req, musb_req_tx, + TP_PROTO(struct musb_request *req), + TP_ARGS(req) +); + +DEFINE_EVENT(musb_req, musb_req_rx, + TP_PROTO(struct musb_request *req), + TP_ARGS(req) +); + +DEFINE_EVENT(musb_req, musb_req_alloc, + TP_PROTO(struct musb_request *req), + TP_ARGS(req) +); + +DEFINE_EVENT(musb_req, musb_req_free, + TP_PROTO(struct musb_request *req), + TP_ARGS(req) +); + +DEFINE_EVENT(musb_req, musb_req_start, + TP_PROTO(struct musb_request *req), + TP_ARGS(req) +); + +DEFINE_EVENT(musb_req, musb_req_enq, + TP_PROTO(struct musb_request *req), + TP_ARGS(req) +); + +DEFINE_EVENT(musb_req, musb_req_deq, + TP_PROTO(struct musb_request *req), + TP_ARGS(req) +); + +#ifdef CONFIG_USB_TI_CPPI41_DMA +DECLARE_EVENT_CLASS(musb_cppi41, + TP_PROTO(struct cppi41_dma_channel *ch), + TP_ARGS(ch), + TP_STRUCT__entry( + __field(struct cppi41_dma_channel *, ch) + __string(name, dev_name(ch->hw_ep->musb->controller)) + __field(u8, hwep) + __field(u8, port) + __field(u8, is_tx) + __field(u32, len) + __field(u32, prog_len) + __field(u32, xferred) + ), + TP_fast_assign( + __entry->ch = ch; + __assign_str(name, dev_name(ch->hw_ep->musb->controller)); + __entry->hwep = ch->hw_ep->epnum; + __entry->port = ch->port_num; + __entry->is_tx = ch->is_tx; + __entry->len = ch->total_len; + __entry->prog_len = ch->prog_len; + __entry->xferred = ch->transferred; + ), + TP_printk("%s: %p, hwep%d ch%d%s, prog_len %d, len %d/%d", + __get_str(name), __entry->ch, __entry->hwep, + __entry->port, __entry->is_tx ? "tx" : "rx", + __entry->prog_len, __entry->xferred, __entry->len + ) +); + +DEFINE_EVENT(musb_cppi41, musb_cppi41_done, + TP_PROTO(struct cppi41_dma_channel *ch), + TP_ARGS(ch) +); + +DEFINE_EVENT(musb_cppi41, musb_cppi41_gb, + TP_PROTO(struct cppi41_dma_channel *ch), + TP_ARGS(ch) +); + +DEFINE_EVENT(musb_cppi41, musb_cppi41_config, + TP_PROTO(struct cppi41_dma_channel *ch), + TP_ARGS(ch) +); + +DEFINE_EVENT(musb_cppi41, musb_cppi41_cont, + TP_PROTO(struct cppi41_dma_channel *ch), + TP_ARGS(ch) +); + +DEFINE_EVENT(musb_cppi41, musb_cppi41_alloc, + TP_PROTO(struct cppi41_dma_channel *ch), + TP_ARGS(ch) +); + +DEFINE_EVENT(musb_cppi41, musb_cppi41_abort, + TP_PROTO(struct cppi41_dma_channel *ch), + TP_ARGS(ch) +); + +DEFINE_EVENT(musb_cppi41, musb_cppi41_free, + TP_PROTO(struct cppi41_dma_channel *ch), + TP_ARGS(ch) +); +#endif /* CONFIG_USB_TI_CPPI41_DMA */ + +#endif /* __MUSB_TRACE_H */ + +/* this part has to be here */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . + +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE musb_trace + +#include <trace/define_trace.h> diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 92d5f718659b..192248f974ec 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -55,8 +55,7 @@ void musb_host_finish_resume(struct work_struct *work) power = musb_readb(musb->mregs, MUSB_POWER); power &= ~MUSB_POWER_RESUME; - dev_dbg(musb->controller, "root port resume stopped, power %02x\n", - power); + musb_dbg(musb, "root port resume stopped, power %02x", power); musb_writeb(musb->mregs, MUSB_POWER, power); /* @@ -104,7 +103,7 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) break; } - dev_dbg(musb->controller, "Root port suspended, power %02x\n", power); + musb_dbg(musb, "Root port suspended, power %02x", power); musb->port1_status |= USB_PORT_STAT_SUSPEND; switch (musb->xceiv->otg->state) { @@ -123,7 +122,7 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) musb_platform_try_idle(musb, 0); break; default: - dev_dbg(musb->controller, "bogus rh suspend? %s\n", + musb_dbg(musb, "bogus rh suspend? %s", usb_otg_state_string(musb->xceiv->otg->state)); } } else if (power & MUSB_POWER_SUSPENDM) { @@ -131,7 +130,7 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) power |= MUSB_POWER_RESUME; musb_writeb(mbase, MUSB_POWER, power); - dev_dbg(musb->controller, "Root port resuming, power %02x\n", power); + musb_dbg(musb, "Root port resuming, power %02x", power); /* later, GetPortStatus will stop RESUME signaling */ musb->port1_status |= MUSB_PORT_STAT_RESUME; @@ -146,7 +145,7 @@ void musb_port_reset(struct musb *musb, bool do_reset) void __iomem *mbase = musb->mregs; if (musb->xceiv->otg->state == OTG_STATE_B_IDLE) { - dev_dbg(musb->controller, "HNP: Returning from HNP; no hub reset from b_idle\n"); + musb_dbg(musb, "HNP: Returning from HNP; no hub reset from b_idle"); musb->port1_status &= ~USB_PORT_STAT_RESET; return; } @@ -194,7 +193,7 @@ void musb_port_reset(struct musb *musb, bool do_reset) schedule_delayed_work(&musb->deassert_reset_work, msecs_to_jiffies(50)); } else { - dev_dbg(musb->controller, "root port reset stopped\n"); + musb_dbg(musb, "root port reset stopped"); musb_platform_pre_root_reset_end(musb); musb_writeb(mbase, MUSB_POWER, power & ~MUSB_POWER_RESET); @@ -202,7 +201,7 @@ void musb_port_reset(struct musb *musb, bool do_reset) power = musb_readb(mbase, MUSB_POWER); if (power & MUSB_POWER_HSMODE) { - dev_dbg(musb->controller, "high-speed device connected\n"); + musb_dbg(musb, "high-speed device connected"); musb->port1_status |= USB_PORT_STAT_HIGH_SPEED; } @@ -242,7 +241,7 @@ void musb_root_disconnect(struct musb *musb) musb->xceiv->otg->state = OTG_STATE_B_IDLE; break; default: - dev_dbg(musb->controller, "host disconnect (%s)\n", + musb_dbg(musb, "host disconnect (%s)", usb_otg_state_string(musb->xceiv->otg->state)); } } @@ -337,7 +336,7 @@ int musb_hub_control( default: goto error; } - dev_dbg(musb->controller, "clear feature %d\n", wValue); + musb_dbg(musb, "clear feature %d", wValue); musb->port1_status &= ~(1 << wValue); break; case GetHubDescriptor: @@ -372,8 +371,7 @@ int musb_hub_control( (__le32 *) buf); /* port change status is more interesting */ - dev_dbg(musb->controller, "port status %08x\n", - musb->port1_status); + musb_dbg(musb, "port status %08x", musb->port1_status); break; case SetPortFeature: if ((wIndex & 0xff) != 1) @@ -443,7 +441,7 @@ int musb_hub_control( default: goto error; } - dev_dbg(musb->controller, "set feature %d\n", wValue); + musb_dbg(musb, "set feature %d", wValue); musb->port1_status |= 1 << wValue; break; diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 8abfe4ec62fb..3620073da58c 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -117,7 +117,7 @@ static void configure_channel(struct dma_channel *channel, u8 bchannel = musb_channel->idx; u16 csr = 0; - dev_dbg(musb->controller, "%p, pkt_sz %d, addr %pad, len %d, mode %d\n", + musb_dbg(musb, "%p, pkt_sz %d, addr %pad, len %d, mode %d", channel, packet_sz, &dma_addr, len, mode); if (mode) { @@ -152,7 +152,7 @@ static int dma_channel_program(struct dma_channel *channel, struct musb_dma_controller *controller = musb_channel->controller; struct musb *musb = controller->private_data; - dev_dbg(musb->controller, "ep%d-%s pkt_sz %d, dma_addr %pad length %d, mode %d\n", + musb_dbg(musb, "ep%d-%s pkt_sz %d, dma_addr %pad length %d, mode %d", musb_channel->epnum, musb_channel->transmit ? "Tx" : "Rx", packet_sz, &dma_addr, len, mode); @@ -266,7 +266,7 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) #endif if (!int_hsdma) { - dev_dbg(musb->controller, "spurious DMA irq\n"); + musb_dbg(musb, "spurious DMA irq"); for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { musb_channel = (struct musb_dma_channel *) @@ -280,7 +280,7 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) } } - dev_dbg(musb->controller, "int_hsdma = 0x%x\n", int_hsdma); + musb_dbg(musb, "int_hsdma = 0x%x", int_hsdma); if (!int_hsdma) goto done; @@ -307,7 +307,7 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) channel->actual_len = addr - musb_channel->start_addr; - dev_dbg(musb->controller, "ch %p, 0x%x -> 0x%x (%zu / %d) %s\n", + musb_dbg(musb, "ch %p, 0x%x -> 0x%x (%zu / %d) %s", channel, musb_channel->start_addr, addr, channel->actual_len, musb_channel->len, diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index c84e0322c108..0b4cec940386 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -49,97 +49,14 @@ struct omap2430_glue { enum musb_vbus_id_status status; struct work_struct omap_musb_mailbox_work; struct device *control_otghs; + bool cable_connected; + bool enabled; + bool powered; }; #define glue_to_musb(g) platform_get_drvdata(g->musb) static struct omap2430_glue *_glue; -static struct timer_list musb_idle_timer; - -static void musb_do_idle(unsigned long _musb) -{ - struct musb *musb = (void *)_musb; - unsigned long flags; - u8 power; - u8 devctl; - - spin_lock_irqsave(&musb->lock, flags); - - switch (musb->xceiv->otg->state) { - case OTG_STATE_A_WAIT_BCON: - - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->otg->state = OTG_STATE_B_IDLE; - MUSB_DEV_MODE(musb); - } else { - musb->xceiv->otg->state = OTG_STATE_A_IDLE; - MUSB_HST_MODE(musb); - } - break; - case OTG_STATE_A_SUSPEND: - /* finish RESUME signaling? */ - if (musb->port1_status & MUSB_PORT_STAT_RESUME) { - power = musb_readb(musb->mregs, MUSB_POWER); - power &= ~MUSB_POWER_RESUME; - dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power); - musb_writeb(musb->mregs, MUSB_POWER, power); - musb->is_active = 1; - musb->port1_status &= ~(USB_PORT_STAT_SUSPEND - | MUSB_PORT_STAT_RESUME); - musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; - usb_hcd_poll_rh_status(musb->hcd); - /* NOTE: it might really be A_WAIT_BCON ... */ - musb->xceiv->otg->state = OTG_STATE_A_HOST; - } - break; - case OTG_STATE_A_HOST: - devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - if (devctl & MUSB_DEVCTL_BDEVICE) - musb->xceiv->otg->state = OTG_STATE_B_IDLE; - else - musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON; - default: - break; - } - spin_unlock_irqrestore(&musb->lock, flags); -} - - -static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout) -{ - unsigned long default_timeout = jiffies + msecs_to_jiffies(3); - static unsigned long last_timer; - - if (timeout == 0) - timeout = default_timeout; - - /* Never idle if active, or when VBUS timeout is not set as host */ - if (musb->is_active || ((musb->a_wait_bcon == 0) - && (musb->xceiv->otg->state == OTG_STATE_A_WAIT_BCON))) { - dev_dbg(musb->controller, "%s active, deleting timer\n", - usb_otg_state_string(musb->xceiv->otg->state)); - del_timer(&musb_idle_timer); - last_timer = jiffies; - return; - } - - if (time_after(last_timer, timeout)) { - if (!timer_pending(&musb_idle_timer)) - last_timer = timeout; - else { - dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n"); - return; - } - } - last_timer = timeout; - - dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n", - usb_otg_state_string(musb->xceiv->otg->state), - (unsigned long)jiffies_to_msecs(timeout - jiffies)); - mod_timer(&musb_idle_timer, timeout); -} - static void omap2430_musb_set_vbus(struct musb *musb, int is_on) { struct usb_otg *otg = musb->xceiv->otg; @@ -205,16 +122,6 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on) musb_readb(musb->mregs, MUSB_DEVCTL)); } -static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode) -{ - u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - - devctl |= MUSB_DEVCTL_SESSION; - musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); - - return 0; -} - static inline void omap2430_low_level_exit(struct musb *musb) { u32 l; @@ -234,22 +141,63 @@ static inline void omap2430_low_level_init(struct musb *musb) musb_writel(musb->mregs, OTG_FORCESTDBY, l); } -static void omap2430_musb_mailbox(enum musb_vbus_id_status status) +/* + * We can get multiple cable events so we need to keep track + * of the power state. Only keep power enabled if USB cable is + * connected and a gadget is started. + */ +static void omap2430_set_power(struct musb *musb, bool enabled, bool cable) +{ + struct device *dev = musb->controller; + struct omap2430_glue *glue = dev_get_drvdata(dev->parent); + bool power_up; + int res; + + if (glue->enabled != enabled) + glue->enabled = enabled; + + if (glue->cable_connected != cable) + glue->cable_connected = cable; + + power_up = glue->enabled && glue->cable_connected; + if (power_up == glue->powered) { + dev_warn(musb->controller, "power state already %i\n", + power_up); + return; + } + + glue->powered = power_up; + + if (power_up) { + res = pm_runtime_get_sync(musb->controller); + if (res < 0) { + dev_err(musb->controller, "could not enable: %i", res); + glue->powered = false; + } + } else { + pm_runtime_mark_last_busy(musb->controller); + pm_runtime_put_autosuspend(musb->controller); + } +} + +static int omap2430_musb_mailbox(enum musb_vbus_id_status status) { struct omap2430_glue *glue = _glue; if (!glue) { pr_err("%s: musb core is not yet initialized\n", __func__); - return; + return -EPROBE_DEFER; } glue->status = status; if (!glue_to_musb(glue)) { pr_err("%s: musb core is not yet ready\n", __func__); - return; + return -EPROBE_DEFER; } schedule_work(&glue->omap_musb_mailbox_work); + + return 0; } static void omap_musb_set_mailbox(struct omap2430_glue *glue) @@ -259,6 +207,13 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev); struct omap_musb_board_data *data = pdata->board_data; struct usb_otg *otg = musb->xceiv->otg; + bool cable_connected; + + cable_connected = ((glue->status == MUSB_ID_GROUND) || + (glue->status == MUSB_VBUS_VALID)); + + if (cable_connected) + omap2430_set_power(musb, glue->enabled, cable_connected); switch (glue->status) { case MUSB_ID_GROUND: @@ -268,7 +223,6 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) musb->xceiv->otg->state = OTG_STATE_A_IDLE; musb->xceiv->last_event = USB_EVENT_ID; if (musb->gadget_driver) { - pm_runtime_get_sync(dev); omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST); omap2430_musb_set_vbus(musb, 1); @@ -281,8 +235,6 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) otg->default_a = false; musb->xceiv->otg->state = OTG_STATE_B_IDLE; musb->xceiv->last_event = USB_EVENT_VBUS; - if (musb->gadget_driver) - pm_runtime_get_sync(dev); omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); break; @@ -291,11 +243,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) dev_dbg(dev, "VBUS Disconnect\n"); musb->xceiv->last_event = USB_EVENT_NONE; - if (musb->gadget_driver) { + if (musb->gadget_driver) omap2430_musb_set_vbus(musb, 0); - pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); - } if (data->interface_type == MUSB_INTERFACE_UTMI) otg_set_vbus(musb->xceiv->otg, 0); @@ -307,6 +256,9 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) dev_dbg(dev, "ID float\n"); } + if (!cable_connected) + omap2430_set_power(musb, glue->enabled, cable_connected); + atomic_notifier_call_chain(&musb->xceiv->notifier, musb->xceiv->last_event, NULL); } @@ -316,13 +268,8 @@ static void omap_musb_mailbox_work(struct work_struct *mailbox_work) { struct omap2430_glue *glue = container_of(mailbox_work, struct omap2430_glue, omap_musb_mailbox_work); - struct musb *musb = glue_to_musb(glue); - struct device *dev = musb->controller; - pm_runtime_get_sync(dev); omap_musb_set_mailbox(glue); - pm_runtime_mark_last_busy(dev); - pm_runtime_put_autosuspend(dev); } static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci) @@ -389,23 +336,7 @@ static int omap2430_musb_init(struct musb *musb) return PTR_ERR(musb->phy); } musb->isr = omap2430_musb_interrupt; - - /* - * Enable runtime PM for musb parent (this driver). We can't - * do it earlier as struct musb is not yet allocated and we - * need to touch the musb registers for runtime PM. - */ - pm_runtime_enable(glue->dev); - status = pm_runtime_get_sync(glue->dev); - if (status < 0) - goto err1; - - status = pm_runtime_get_sync(dev); - if (status < 0) { - dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); - pm_runtime_put_sync(glue->dev); - goto err1; - } + phy_init(musb->phy); l = musb_readl(musb->mregs, OTG_INTERFSEL); @@ -427,20 +358,10 @@ static int omap2430_musb_init(struct musb *musb) musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); - setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); - if (glue->status != MUSB_UNKNOWN) omap_musb_set_mailbox(glue); - phy_init(musb->phy); - phy_power_on(musb->phy); - - pm_runtime_put_noidle(musb->controller); - pm_runtime_put_noidle(glue->dev); return 0; - -err1: - return status; } static void omap2430_musb_enable(struct musb *musb) @@ -452,6 +373,11 @@ static void omap2430_musb_enable(struct musb *musb) struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev); struct omap_musb_board_data *data = pdata->board_data; + if (!WARN_ON(!musb->phy)) + phy_power_on(musb->phy); + + omap2430_set_power(musb, true, glue->cable_connected); + switch (glue->status) { case MUSB_ID_GROUND: @@ -487,18 +413,25 @@ static void omap2430_musb_disable(struct musb *musb) struct device *dev = musb->controller; struct omap2430_glue *glue = dev_get_drvdata(dev->parent); + if (!WARN_ON(!musb->phy)) + phy_power_off(musb->phy); + if (glue->status != MUSB_UNKNOWN) omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DISCONNECT); + + omap2430_set_power(musb, false, glue->cable_connected); } static int omap2430_musb_exit(struct musb *musb) { - del_timer_sync(&musb_idle_timer); + struct device *dev = musb->controller; + struct omap2430_glue *glue = dev_get_drvdata(dev->parent); omap2430_low_level_exit(musb); - phy_power_off(musb->phy); phy_exit(musb->phy); + musb->phy = NULL; + cancel_work_sync(&glue->omap_musb_mailbox_work); return 0; } @@ -512,9 +445,6 @@ static const struct musb_platform_ops omap2430_ops = { .init = omap2430_musb_init, .exit = omap2430_musb_exit, - .set_mode = omap2430_musb_set_mode, - .try_idle = omap2430_musb_try_idle, - .set_vbus = omap2430_musb_set_vbus, .enable = omap2430_musb_enable, @@ -639,11 +569,9 @@ static int omap2430_probe(struct platform_device *pdev) goto err2; } - /* - * Note that we cannot enable PM runtime yet for this - * driver as we need struct musb initialized first. - * See omap2430_musb_init above. - */ + pm_runtime_enable(glue->dev); + pm_runtime_use_autosuspend(glue->dev); + pm_runtime_set_autosuspend_delay(glue->dev, 500); ret = platform_device_add(musb); if (ret) { @@ -662,12 +590,14 @@ err0: static int omap2430_remove(struct platform_device *pdev) { - struct omap2430_glue *glue = platform_get_drvdata(pdev); + struct omap2430_glue *glue = platform_get_drvdata(pdev); + struct musb *musb = glue_to_musb(glue); pm_runtime_get_sync(glue->dev); - cancel_work_sync(&glue->omap_musb_mailbox_work); platform_device_unregister(glue->musb); + omap2430_set_power(musb, false, false); pm_runtime_put_sync(glue->dev); + pm_runtime_dont_use_autosuspend(glue->dev); pm_runtime_disable(glue->dev); return 0; @@ -680,12 +610,13 @@ static int omap2430_runtime_suspend(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - if (musb) { - musb->context.otg_interfsel = musb_readl(musb->mregs, - OTG_INTERFSEL); + if (!musb) + return 0; - omap2430_low_level_exit(musb); - } + musb->context.otg_interfsel = musb_readl(musb->mregs, + OTG_INTERFSEL); + + omap2430_low_level_exit(musb); return 0; } @@ -696,7 +627,7 @@ static int omap2430_runtime_resume(struct device *dev) struct musb *musb = glue_to_musb(glue); if (!musb) - return -EPROBE_DEFER; + return 0; omap2430_low_level_init(musb); musb_writel(musb->mregs, OTG_INTERFSEL, @@ -738,18 +669,8 @@ static struct platform_driver omap2430_driver = { }, }; +module_platform_driver(omap2430_driver); + MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer"); MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); MODULE_LICENSE("GPL v2"); - -static int __init omap2430_init(void) -{ - return platform_driver_register(&omap2430_driver); -} -subsys_initcall(omap2430_init); - -static void __exit omap2430_exit(void) -{ - platform_driver_unregister(&omap2430_driver); -} -module_exit(omap2430_exit); diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index fdab4232cfbf..c6ee16660572 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c @@ -80,7 +80,8 @@ static struct musb *sunxi_musb; struct sunxi_glue { struct device *dev; - struct platform_device *musb; + struct musb *musb; + struct platform_device *musb_pdev; struct clk *clk; struct reset_control *rst; struct phy *phy; @@ -102,7 +103,7 @@ static void sunxi_musb_work(struct work_struct *work) return; if (test_and_clear_bit(SUNXI_MUSB_FL_HOSTMODE_PEND, &glue->flags)) { - struct musb *musb = platform_get_drvdata(glue->musb); + struct musb *musb = glue->musb; unsigned long flags; u8 devctl; @@ -112,7 +113,7 @@ static void sunxi_musb_work(struct work_struct *work) if (test_bit(SUNXI_MUSB_FL_HOSTMODE, &glue->flags)) { set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); musb->xceiv->otg->default_a = 1; - musb->xceiv->otg->state = OTG_STATE_A_IDLE; + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; MUSB_HST_MODE(musb); devctl |= MUSB_DEVCTL_SESSION; } else { @@ -145,10 +146,12 @@ static void sunxi_musb_set_vbus(struct musb *musb, int is_on) { struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent); - if (is_on) + if (is_on) { set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); - else + musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; + } else { clear_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); + } schedule_work(&glue->work); } @@ -253,26 +256,15 @@ static int sunxi_musb_init(struct musb *musb) writeb(SUNXI_MUSB_VEND0_PIO_MODE, musb->mregs + SUNXI_MUSB_VEND0); /* Register notifier before calling phy_init() */ - if (musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) { - ret = extcon_register_notifier(glue->extcon, EXTCON_USB_HOST, - &glue->host_nb); - if (ret) - goto error_reset_assert; - } + ret = extcon_register_notifier(glue->extcon, EXTCON_USB_HOST, + &glue->host_nb); + if (ret) + goto error_reset_assert; ret = phy_init(glue->phy); if (ret) goto error_unregister_notifier; - if (musb->port_mode == MUSB_PORT_MODE_HOST) { - ret = phy_power_on(glue->phy); - if (ret) - goto error_phy_exit; - set_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags); - /* Stop musb work from turning vbus off again */ - set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); - } - musb->isr = sunxi_musb_interrupt; /* Stop the musb-core from doing runtime pm (not supported on sunxi) */ @@ -280,12 +272,9 @@ static int sunxi_musb_init(struct musb *musb) return 0; -error_phy_exit: - phy_exit(glue->phy); error_unregister_notifier: - if (musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) - extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, - &glue->host_nb); + extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, + &glue->host_nb); error_reset_assert: if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) reset_control_assert(glue->rst); @@ -309,9 +298,8 @@ static int sunxi_musb_exit(struct musb *musb) phy_exit(glue->phy); - if (musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) - extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, - &glue->host_nb); + extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, + &glue->host_nb); if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) reset_control_assert(glue->rst); @@ -327,6 +315,8 @@ static void sunxi_musb_enable(struct musb *musb) { struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent); + glue->musb = musb; + /* musb_core does not call us in a balanced manner */ if (test_and_set_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags)) return; @@ -341,13 +331,13 @@ static void sunxi_musb_disable(struct musb *musb) clear_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags); } -struct dma_controller *sunxi_musb_dma_controller_create(struct musb *musb, - void __iomem *base) +static struct dma_controller * +sunxi_musb_dma_controller_create(struct musb *musb, void __iomem *base) { return NULL; } -void sunxi_musb_dma_controller_destroy(struct dma_controller *c) +static void sunxi_musb_dma_controller_destroy(struct dma_controller *c) { } @@ -624,10 +614,6 @@ static int sunxi_musb_probe(struct platform_device *pdev) return -EINVAL; } - glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); - if (!glue) - return -ENOMEM; - memset(&pdata, 0, sizeof(pdata)); switch (usb_get_dr_mode(&pdev->dev)) { #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_HOST @@ -635,15 +621,13 @@ static int sunxi_musb_probe(struct platform_device *pdev) pdata.mode = MUSB_PORT_MODE_HOST; break; #endif +#if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_GADGET + case USB_DR_MODE_PERIPHERAL: + pdata.mode = MUSB_PORT_MODE_GADGET; + break; +#endif #ifdef CONFIG_USB_MUSB_DUAL_ROLE case USB_DR_MODE_OTG: - glue->extcon = extcon_get_edev_by_phandle(&pdev->dev, 0); - if (IS_ERR(glue->extcon)) { - if (PTR_ERR(glue->extcon) == -EPROBE_DEFER) - return -EPROBE_DEFER; - dev_err(&pdev->dev, "Invalid or missing extcon\n"); - return PTR_ERR(glue->extcon); - } pdata.mode = MUSB_PORT_MODE_DUAL_ROLE; break; #endif @@ -654,6 +638,10 @@ static int sunxi_musb_probe(struct platform_device *pdev) pdata.platform_ops = &sunxi_musb_ops; pdata.config = &sunxi_musb_hdrc_config; + glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); + if (!glue) + return -ENOMEM; + glue->dev = &pdev->dev; INIT_WORK(&glue->work, sunxi_musb_work); glue->host_nb.notifier_call = sunxi_musb_host_notifier; @@ -687,6 +675,14 @@ static int sunxi_musb_probe(struct platform_device *pdev) } } + glue->extcon = extcon_get_edev_by_phandle(&pdev->dev, 0); + if (IS_ERR(glue->extcon)) { + if (PTR_ERR(glue->extcon) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_err(&pdev->dev, "Invalid or missing extcon\n"); + return PTR_ERR(glue->extcon); + } + glue->phy = devm_phy_get(&pdev->dev, "usb"); if (IS_ERR(glue->phy)) { if (PTR_ERR(glue->phy) == -EPROBE_DEFER) @@ -721,9 +717,9 @@ static int sunxi_musb_probe(struct platform_device *pdev) pinfo.data = &pdata; pinfo.size_data = sizeof(pdata); - glue->musb = platform_device_register_full(&pinfo); - if (IS_ERR(glue->musb)) { - ret = PTR_ERR(glue->musb); + glue->musb_pdev = platform_device_register_full(&pinfo); + if (IS_ERR(glue->musb_pdev)) { + ret = PTR_ERR(glue->musb_pdev); dev_err(&pdev->dev, "Error registering musb dev: %d\n", ret); goto err_unregister_usb_phy; } @@ -740,7 +736,7 @@ static int sunxi_musb_remove(struct platform_device *pdev) struct sunxi_glue *glue = platform_get_drvdata(pdev); struct platform_device *usb_phy = glue->usb_phy; - platform_device_unregister(glue->musb); /* Frees glue ! */ + platform_device_unregister(glue->musb_pdev); usb_phy_generic_unregister(usb_phy); return 0; |