Commit 8db67e15 authored by David Brownell's avatar David Brownell Committed by Tony Lindgren

musb_hdrc: Various bugfixes and other updates

Various bugfixes:
    - gadget side does dma_sync_single_for_*() if the buffer
      was mapped by the gadget driver (none do that just yet)
    - host side rx, always force dma request off "just in case",
      instead of just for Mentor's DMA (i.e. not just OMAP2430)
    - complain louder about the board needing different driver config
    - iounmap() registers on rmmod
    - fault handling fixes in tusb_start()
    - (from TI) save dma mask so modprobe after use_dma=n can use dma
    - (from TI) gadget side zero-length IN likes TXPKTRDY before status stage

Other updates:
    - catch up to pt_regs finally leaving the irq path, other build fixes
    - remove pointless headers like <linux/pci.h>
    - RemoveMoreCamelCaseNastiness
    - resolve some config-specific compiler warning/error messages
    - dump tusb irq status register too
    - remove that MIN_DMA thing; dma logic must now handle zlps
      in all cases, not just to terminate a transfer
    - comment fixes
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
parent d5877d41
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -246,7 +245,7 @@ static void davinci_set_vbus(struct musb *musb, int is_on) ...@@ -246,7 +245,7 @@ static void davinci_set_vbus(struct musb *musb, int is_on)
return davinci_vbus_power(musb, is_on, 0); return davinci_vbus_power(musb, is_on, 0);
} }
static irqreturn_t davinci_interrupt(int irq, void *__hci, struct pt_regs *r) static irqreturn_t davinci_interrupt(int irq, void *__hci)
{ {
unsigned long flags; unsigned long flags;
irqreturn_t retval = IRQ_NONE; irqreturn_t retval = IRQ_NONE;
...@@ -289,7 +288,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci, struct pt_regs *r) ...@@ -289,7 +288,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci, struct pt_regs *r)
>> DAVINCI_USB_TXINT_SHIFT; >> DAVINCI_USB_TXINT_SHIFT;
musb->int_usb = (tmp & DAVINCI_USB_USBINT_MASK) musb->int_usb = (tmp & DAVINCI_USB_USBINT_MASK)
>> DAVINCI_USB_USBINT_SHIFT; >> DAVINCI_USB_USBINT_SHIFT;
musb->int_regs = r;
/* treat DRVVBUS irq like an ID change IRQ (for now) */ /* treat DRVVBUS irq like an ID change IRQ (for now) */
if (tmp & (1 << (8 + DAVINCI_USB_USBINT_SHIFT))) { if (tmp & (1 << (8 + DAVINCI_USB_USBINT_SHIFT))) {
...@@ -317,7 +315,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci, struct pt_regs *r) ...@@ -317,7 +315,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci, struct pt_regs *r)
/* irq stays asserted until EOI is written */ /* irq stays asserted until EOI is written */
musb_writel(tibase, DAVINCI_USB_EOI_REG, 0); musb_writel(tibase, DAVINCI_USB_EOI_REG, 0);
musb->int_regs = NULL;
spin_unlock_irqrestore(&musb->Lock, flags); spin_unlock_irqrestore(&musb->Lock, flags);
/* REVISIT we sometimes get unhandled IRQs /* REVISIT we sometimes get unhandled IRQs
......
...@@ -556,9 +556,11 @@ musb_read_setup(struct musb *pThis, struct usb_ctrlrequest *req) ...@@ -556,9 +556,11 @@ musb_read_setup(struct musb *pThis, struct usb_ctrlrequest *req)
*/ */
pThis->bSetAddress = FALSE; pThis->bSetAddress = FALSE;
pThis->ackpend = MGC_M_CSR0_P_SVDRXPKTRDY; pThis->ackpend = MGC_M_CSR0_P_SVDRXPKTRDY;
if (req->wLength == 0) if (req->wLength == 0) {
if (req->bRequestType & USB_DIR_IN)
pThis->ackpend |= MGC_M_CSR0_TXPKTRDY;
pThis->ep0_state = MGC_END0_STAGE_ACKWAIT; pThis->ep0_state = MGC_END0_STAGE_ACKWAIT;
else if (req->bRequestType & USB_DIR_IN) { } else if (req->bRequestType & USB_DIR_IN) {
pThis->ep0_state = MGC_END0_STAGE_TX; pThis->ep0_state = MGC_END0_STAGE_TX;
musb_writew(regs, MGC_O_HDRC_CSR0, MGC_M_CSR0_P_SVDRXPKTRDY); musb_writew(regs, MGC_O_HDRC_CSR0, MGC_M_CSR0_P_SVDRXPKTRDY);
while ((musb_readw(regs, MGC_O_HDRC_CSR0) while ((musb_readw(regs, MGC_O_HDRC_CSR0)
......
...@@ -118,7 +118,8 @@ __acquires(ep->musb->Lock) ...@@ -118,7 +118,8 @@ __acquires(ep->musb->Lock)
ep->busy = 1; ep->busy = 1;
spin_unlock(&musb->Lock); spin_unlock(&musb->Lock);
if (is_dma_capable() && req->mapped) { if (is_dma_capable()) {
if (req->mapped) {
dma_unmap_single(musb->controller, dma_unmap_single(musb->controller,
req->request.dma, req->request.dma,
req->request.length, req->request.length,
...@@ -127,6 +128,13 @@ __acquires(ep->musb->Lock) ...@@ -127,6 +128,13 @@ __acquires(ep->musb->Lock)
: DMA_FROM_DEVICE); : DMA_FROM_DEVICE);
req->request.dma = DMA_ADDR_INVALID; req->request.dma = DMA_ADDR_INVALID;
req->mapped = 0; req->mapped = 0;
} else
dma_sync_single_for_cpu(musb->controller,
req->request.dma,
req->request.length,
req->bTx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
} }
if (pRequest->status == 0) if (pRequest->status == 0)
DBG(5, "%s done request %p, %d/%d\n", DBG(5, "%s done request %p, %d/%d\n",
...@@ -1135,7 +1143,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, ...@@ -1135,7 +1143,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
{ {
struct musb_ep *pEnd; struct musb_ep *pEnd;
struct musb_request *pRequest; struct musb_request *pRequest;
struct musb *pThis; struct musb *musb;
int status = 0; int status = 0;
unsigned long lockflags; unsigned long lockflags;
...@@ -1143,10 +1151,10 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, ...@@ -1143,10 +1151,10 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
return -EINVAL; return -EINVAL;
pEnd = to_musb_ep(ep); pEnd = to_musb_ep(ep);
pThis = pEnd->pThis; musb = pEnd->pThis;
pRequest = to_musb_request(req); pRequest = to_musb_request(req);
pRequest->musb = pThis; pRequest->musb = musb;
if (pRequest->ep != pEnd) if (pRequest->ep != pEnd)
return -EINVAL; return -EINVAL;
...@@ -1159,23 +1167,31 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, ...@@ -1159,23 +1167,31 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
pRequest->bEnd = pEnd->bEndNumber; pRequest->bEnd = pEnd->bEndNumber;
pRequest->bTx = pEnd->is_in; pRequest->bTx = pEnd->is_in;
if (is_dma_capable() if (is_dma_capable() && pEnd->dma) {
&& pRequest->request.dma == DMA_ADDR_INVALID if (pRequest->request.dma == DMA_ADDR_INVALID) {
&& pRequest->request.length >= MIN_DMA_REQUEST pRequest->request.dma = dma_map_single(
&& pEnd->dma) { musb->controller,
pRequest->request.dma = dma_map_single(pThis->controller,
pRequest->request.buf, pRequest->request.buf,
pRequest->request.length, pRequest->request.length,
pRequest->bTx pRequest->bTx
? DMA_TO_DEVICE ? DMA_TO_DEVICE
: DMA_FROM_DEVICE); : DMA_FROM_DEVICE);
pRequest->mapped = 1; pRequest->mapped = 1;
} else {
dma_sync_single_for_device(musb->controller,
pRequest->request.dma,
pRequest->request.length,
pRequest->bTx
? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
pRequest->mapped = 0;
}
} else if (!req->buf) { } else if (!req->buf) {
return -ENODATA; return -ENODATA;
} else } else
pRequest->mapped = 0; pRequest->mapped = 0;
spin_lock_irqsave(&pThis->Lock, lockflags); spin_lock_irqsave(&musb->Lock, lockflags);
/* don't queue if the ep is down */ /* don't queue if the ep is down */
if (!pEnd->desc) { if (!pEnd->desc) {
...@@ -1190,10 +1206,10 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, ...@@ -1190,10 +1206,10 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
/* it this is the head of the queue, start i/o ... */ /* it this is the head of the queue, start i/o ... */
if (!pEnd->busy && &pRequest->request.list == pEnd->req_list.next) if (!pEnd->busy && &pRequest->request.list == pEnd->req_list.next)
musb_ep_restart(pThis, pRequest); musb_ep_restart(musb, pRequest);
cleanup: cleanup:
spin_unlock_irqrestore(&pThis->Lock, lockflags); spin_unlock_irqrestore(&musb->Lock, lockflags);
return status; return status;
} }
......
...@@ -74,6 +74,7 @@ struct musb_ep { ...@@ -74,6 +74,7 @@ struct musb_ep {
/* later things are modified based on usage */ /* later things are modified based on usage */
struct list_head req_list; struct list_head req_list;
/* true if lock must be dropped but req_list may not be advanced */
u8 busy; u8 busy;
}; };
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
******************************************************************/ ******************************************************************/
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -284,7 +283,7 @@ __acquires(musb->Lock) ...@@ -284,7 +283,7 @@ __acquires(musb->Lock)
); );
spin_unlock(&musb->Lock); spin_unlock(&musb->Lock);
usb_hcd_giveback_urb(musb_to_hcd(musb), urb, musb->int_regs); usb_hcd_giveback_urb(musb_to_hcd(musb), urb);
spin_lock(&musb->Lock); spin_lock(&musb->Lock);
} }
...@@ -1485,8 +1484,8 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) ...@@ -1485,8 +1484,8 @@ void musb_host_rx(struct musb *pThis, u8 bEnd)
} }
if (unlikely(dma_channel_status(dma) == MGC_DMA_STATUS_BUSY)) { if (unlikely(dma_channel_status(dma) == MGC_DMA_STATUS_BUSY)) {
/* SHOULD NEVER HAPPEN */ /* SHOULD NEVER HAPPEN ... but at least DaVinci has done it */
ERR("RX%d dma busy\n", bEnd); ERR("RX%d dma busy, csr %04x\n", bEnd, wRxCsrVal);
goto finish; goto finish;
} }
...@@ -1521,9 +1520,15 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) ...@@ -1521,9 +1520,15 @@ void musb_host_rx(struct musb *pThis, u8 bEnd)
} }
#endif #endif
if (dma && (wRxCsrVal & MGC_M_RXCSR_DMAENAB)) { if (dma && (wRxCsrVal & MGC_M_RXCSR_DMAENAB)) {
xfer_len = dma->dwActualLength;
wVal &= ~(MGC_M_RXCSR_DMAENAB
| MGC_M_RXCSR_H_AUTOREQ
| MGC_M_RXCSR_AUTOCLEAR
| MGC_M_RXCSR_RXPKTRDY);
musb_writew(pEnd->regs, MGC_O_HDRC_RXCSR, wVal);
#ifdef CONFIG_USB_INVENTRA_DMA #ifdef CONFIG_USB_INVENTRA_DMA
xfer_len = dma->dwActualLength;
pUrb->actual_length += xfer_len; pUrb->actual_length += xfer_len;
qh->offset += xfer_len; qh->offset += xfer_len;
...@@ -1531,14 +1536,6 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) ...@@ -1531,14 +1536,6 @@ void musb_host_rx(struct musb *pThis, u8 bEnd)
bDone = (pUrb->actual_length >= pUrb->transfer_buffer_length) bDone = (pUrb->actual_length >= pUrb->transfer_buffer_length)
|| (dma->dwActualLength & (qh->maxpacket - 1)); || (dma->dwActualLength & (qh->maxpacket - 1));
wVal &= ~(MGC_M_RXCSR_DMAENAB
| MGC_M_RXCSR_H_AUTOREQ
| MGC_M_RXCSR_AUTOCLEAR
| MGC_M_RXCSR_RXPKTRDY);
MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
MGC_WriteCsr16(pBase, MGC_O_HDRC_RXCSR, bEnd, wVal);
/* send IN token for next packet, without AUTOREQ */ /* send IN token for next packet, without AUTOREQ */
if (!bDone) { if (!bDone) {
wVal |= MGC_M_RXCSR_H_REQPKT; wVal |= MGC_M_RXCSR_H_REQPKT;
...@@ -1552,7 +1549,6 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) ...@@ -1552,7 +1549,6 @@ void musb_host_rx(struct musb *pThis, u8 bEnd)
MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd)); MGC_ReadCsr16(pBase, MGC_O_HDRC_RXCOUNT, bEnd));
#else #else
bDone = TRUE; bDone = TRUE;
xfer_len = dma->dwActualLength;
#endif #endif
} else if (pUrb->status == -EINPROGRESS) { } else if (pUrb->status == -EINPROGRESS) {
/* if no errors, be sure a packet is ready for unloading */ /* if no errors, be sure a packet is ready for unloading */
...@@ -1682,7 +1678,7 @@ static int musb_schedule( ...@@ -1682,7 +1678,7 @@ static int musb_schedule(
int idle; int idle;
int wBestDiff; int wBestDiff;
int nBestEnd, nEnd; int nBestEnd, nEnd;
struct musb_hw_ep *hw_ep; struct musb_hw_ep *hw_ep = NULL;
struct list_head *head = NULL; struct list_head *head = NULL;
/* use fixed hardware for control and bulk */ /* use fixed hardware for control and bulk */
......
...@@ -558,7 +558,7 @@ static int dump_header_stats(struct musb *pThis, char *buffer) ...@@ -558,7 +558,7 @@ static int dump_header_stats(struct musb *pThis, char *buffer)
code = sprintf(buffer, code = sprintf(buffer,
"TUSB6010: devconf %08x, phy enable %08x drive %08x" "TUSB6010: devconf %08x, phy enable %08x drive %08x"
"\n\totg %03x timer %08x" "\n\totg %03x timer %08x"
"\n\tprcm conf %08x mgmt %08x; intmask %08x" "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
"\n", "\n",
musb_readl(pThis->ctrl_base, TUSB_DEV_CONF), musb_readl(pThis->ctrl_base, TUSB_DEV_CONF),
musb_readl(pThis->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE), musb_readl(pThis->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
...@@ -567,6 +567,7 @@ static int dump_header_stats(struct musb *pThis, char *buffer) ...@@ -567,6 +567,7 @@ static int dump_header_stats(struct musb *pThis, char *buffer)
musb_readl(pThis->ctrl_base, TUSB_DEV_OTG_TIMER), musb_readl(pThis->ctrl_base, TUSB_DEV_OTG_TIMER),
musb_readl(pThis->ctrl_base, TUSB_PRCM_CONF), musb_readl(pThis->ctrl_base, TUSB_PRCM_CONF),
musb_readl(pThis->ctrl_base, TUSB_PRCM_MNGMT), musb_readl(pThis->ctrl_base, TUSB_PRCM_MNGMT),
musb_readl(pThis->ctrl_base, TUSB_INT_SRC),
musb_readl(pThis->ctrl_base, TUSB_INT_MASK)); musb_readl(pThis->ctrl_base, TUSB_INT_MASK));
if (code <= 0) if (code <= 0)
goto done; goto done;
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#include <linux/usb_ch9.h> #include <linux/usb_ch9.h>
#include <linux/usb_gadget.h> #include <linux/usb_gadget.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usb_otg.h> #include <linux/usb/otg.h>
#include <linux/usb/musb.h> #include <linux/usb/musb.h>
struct musb; struct musb;
...@@ -75,9 +75,6 @@ struct musb_ep; ...@@ -75,9 +75,6 @@ struct musb_ep;
#include "otg.h" #include "otg.h"
/* REVISIT tune this */
#define MIN_DMA_REQUEST 1 /* use PIO below this xfer size */
#ifdef CONFIG_USB_MUSB_OTG #ifdef CONFIG_USB_MUSB_OTG
...@@ -374,7 +371,7 @@ static inline struct usb_request *next_out_request(struct musb_hw_ep *hw_ep) ...@@ -374,7 +371,7 @@ static inline struct usb_request *next_out_request(struct musb_hw_ep *hw_ep)
struct musb { struct musb {
spinlock_t Lock; spinlock_t Lock;
struct clk *clock; struct clk *clock;
irqreturn_t (*isr)(int, void *, struct pt_regs *); irqreturn_t (*isr)(int, void *);
struct work_struct irq_work; struct work_struct irq_work;
#ifdef CONFIG_USB_MUSB_HDRC_HCD #ifdef CONFIG_USB_MUSB_HDRC_HCD
...@@ -418,7 +415,6 @@ struct musb { ...@@ -418,7 +415,6 @@ struct musb {
u8 int_usb; u8 int_usb;
u16 int_rx; u16 int_rx;
u16 int_tx; u16 int_tx;
struct pt_regs *int_regs;
struct otg_transceiver xceiv; struct otg_transceiver xceiv;
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
* *
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -29,9 +28,6 @@ ...@@ -29,9 +28,6 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/arch/hardware.h> #include <asm/arch/hardware.h>
......
...@@ -94,7 +94,6 @@ ...@@ -94,7 +94,6 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -665,6 +664,7 @@ void musb_start(struct musb *musb) ...@@ -665,6 +664,7 @@ void musb_start(struct musb *musb)
musb_writeb(regs, MGC_O_HDRC_POWER, MGC_M_POWER_ISOUPDATE musb_writeb(regs, MGC_O_HDRC_POWER, MGC_M_POWER_ISOUPDATE
| MGC_M_POWER_SOFTCONN | MGC_M_POWER_SOFTCONN
| MGC_M_POWER_HSENAB | MGC_M_POWER_HSENAB
/* ENSUSPEND wedges tusb */
// | MGC_M_POWER_ENSUSPEND // | MGC_M_POWER_ENSUSPEND
); );
...@@ -672,7 +672,7 @@ void musb_start(struct musb *musb) ...@@ -672,7 +672,7 @@ void musb_start(struct musb *musb)
devctl = musb_readb(regs, MGC_O_HDRC_DEVCTL); devctl = musb_readb(regs, MGC_O_HDRC_DEVCTL);
devctl &= ~MGC_M_DEVCTL_SESSION; devctl &= ~MGC_M_DEVCTL_SESSION;
if (is_otg_enabled(pThis)) { if (is_otg_enabled(musb)) {
/* session started after: /* session started after:
* (a) ID-grounded irq, host mode; * (a) ID-grounded irq, host mode;
* (b) vbus present/connect IRQ, peripheral mode; * (b) vbus present/connect IRQ, peripheral mode;
...@@ -683,7 +683,7 @@ void musb_start(struct musb *musb) ...@@ -683,7 +683,7 @@ void musb_start(struct musb *musb)
else else
devctl |= MGC_M_DEVCTL_SESSION; devctl |= MGC_M_DEVCTL_SESSION;
} else if (is_host_enabled(pThis)) { } else if (is_host_enabled(musb)) {
/* assume ID pin is hard-wired to ground */ /* assume ID pin is hard-wired to ground */
devctl |= MGC_M_DEVCTL_SESSION; devctl |= MGC_M_DEVCTL_SESSION;
...@@ -1276,7 +1276,7 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis) ...@@ -1276,7 +1276,7 @@ static int __devinit musb_core_init(u16 wType, struct musb *pThis)
#ifdef CONFIG_ARCH_OMAP243X #ifdef CONFIG_ARCH_OMAP243X
static irqreturn_t generic_interrupt(int irq, void *__hci, struct pt_regs *r) static irqreturn_t generic_interrupt(int irq, void *__hci)
{ {
unsigned long flags; unsigned long flags;
irqreturn_t retval = IRQ_NONE; irqreturn_t retval = IRQ_NONE;
...@@ -1287,7 +1287,6 @@ static irqreturn_t generic_interrupt(int irq, void *__hci, struct pt_regs *r) ...@@ -1287,7 +1287,6 @@ static irqreturn_t generic_interrupt(int irq, void *__hci, struct pt_regs *r)
musb->int_usb = musb_readb(musb->pRegs, MGC_O_HDRC_INTRUSB); musb->int_usb = musb_readb(musb->pRegs, MGC_O_HDRC_INTRUSB);
musb->int_tx = musb_readw(musb->pRegs, MGC_O_HDRC_INTRTX); musb->int_tx = musb_readw(musb->pRegs, MGC_O_HDRC_INTRTX);
musb->int_rx = musb_readw(musb->pRegs, MGC_O_HDRC_INTRRX); musb->int_rx = musb_readw(musb->pRegs, MGC_O_HDRC_INTRRX);
musb->int_regs = r;
if (musb->int_usb || musb->int_tx || musb->int_rx) if (musb->int_usb || musb->int_tx || musb->int_rx)
retval = musb_interrupt(musb); retval = musb_interrupt(musb);
...@@ -1604,7 +1603,6 @@ static void musb_free(struct musb *musb) ...@@ -1604,7 +1603,6 @@ static void musb_free(struct musb *musb)
if (is_dma_capable() && musb->pDmaController) { if (is_dma_capable() && musb->pDmaController) {
struct dma_controller *c = musb->pDmaController; struct dma_controller *c = musb->pDmaController;
//
(void) c->stop(c->pPrivateData); (void) c->stop(c->pPrivateData);
dma_controller_factory.destroy(c); dma_controller_factory.destroy(c);
} }
...@@ -1667,7 +1665,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1667,7 +1665,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
bad_config: bad_config:
#endif #endif
default: default:
dev_dbg(dev, "incompatible Kconfig role setting\n"); dev_err(dev, "incompatible Kconfig role setting\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1811,8 +1809,9 @@ fail: ...@@ -1811,8 +1809,9 @@ fail:
INIT_WORK(&pThis->irq_work, musb_irq_work, pThis); INIT_WORK(&pThis->irq_work, musb_irq_work, pThis);
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
device_create_file(dev, &dev_attr_mode); status = device_create_file(dev, &dev_attr_mode);
device_create_file(dev, &dev_attr_cable); status = device_create_file(dev, &dev_attr_cable);
status = 0;
#endif #endif
return status; return status;
...@@ -1828,6 +1827,10 @@ fail2: ...@@ -1828,6 +1827,10 @@ fail2:
* bridge to a platform device; this driver then suffices. * bridge to a platform device; this driver then suffices.
*/ */
#ifndef CONFIG_USB_INVENTRA_FIFO
static u64 *orig_dma_mask;
#endif
static int __devinit musb_probe(struct platform_device *pdev) static int __devinit musb_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -1845,12 +1848,17 @@ static int __devinit musb_probe(struct platform_device *pdev) ...@@ -1845,12 +1848,17 @@ static int __devinit musb_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
#ifndef CONFIG_USB_INVENTRA_FIFO
/* clobbered by use_dma=n */
orig_dma_mask = dev->dma_mask;
#endif
return musb_init_controller(dev, irq, base); return musb_init_controller(dev, irq, base);
} }
static int __devexit musb_remove(struct platform_device *pdev) static int __devexit musb_remove(struct platform_device *pdev)
{ {
struct musb *musb = dev_to_musb(&pdev->dev); struct musb *musb = dev_to_musb(&pdev->dev);
void __iomem *ctrl_base = musb->ctrl_base;
/* this gets called on rmmod. /* this gets called on rmmod.
* - Host mode: host may still be active * - Host mode: host may still be active
...@@ -1864,7 +1872,11 @@ static int __devexit musb_remove(struct platform_device *pdev) ...@@ -1864,7 +1872,11 @@ static int __devexit musb_remove(struct platform_device *pdev)
usb_remove_hcd(musb_to_hcd(musb)); usb_remove_hcd(musb_to_hcd(musb));
#endif #endif
musb_free(musb); musb_free(musb);
iounmap(ctrl_base);
device_init_wakeup(&pdev->dev, 0); device_init_wakeup(&pdev->dev, 0);
#ifndef CONFIG_USB_INVENTRA_FIFO
dev->dma_mask = orig_dma_mask;
#endif
return 0; return 0;
} }
......
...@@ -146,6 +146,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf) ...@@ -146,6 +146,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf)
* at most mA current to be drawn from VBUS during a Default-B session * at most mA current to be drawn from VBUS during a Default-B session
* (that is, while VBUS exceeds 4.4V). In Default-A (including pure host * (that is, while VBUS exceeds 4.4V). In Default-A (including pure host
* mode), or low power Default-B sessions, something else supplies power. * mode), or low power Default-B sessions, something else supplies power.
* Caller must take care of locking.
*/ */
static int tusb_set_power(struct otg_transceiver *x, unsigned mA) static int tusb_set_power(struct otg_transceiver *x, unsigned mA)
{ {
...@@ -178,7 +179,7 @@ static int tusb_set_power(struct otg_transceiver *x, unsigned mA) ...@@ -178,7 +179,7 @@ static int tusb_set_power(struct otg_transceiver *x, unsigned mA)
* (to be fixed in rev3 silicon) ... symptoms include disconnect * (to be fixed in rev3 silicon) ... symptoms include disconnect
* or looping suspend/resume cycles * or looping suspend/resume cycles
*/ */
static void tusb_set_clock_source(struct musb *musb, int mode) static void tusb_set_clock_source(struct musb *musb, unsigned mode)
{ {
void __iomem *base = musb->ctrl_base; void __iomem *base = musb->ctrl_base;
u32 reg; u32 reg;
...@@ -186,10 +187,17 @@ static void tusb_set_clock_source(struct musb *musb, int mode) ...@@ -186,10 +187,17 @@ static void tusb_set_clock_source(struct musb *musb, int mode)
reg = musb_readl(base, TUSB_PRCM_CONF); reg = musb_readl(base, TUSB_PRCM_CONF);
reg &= ~TUSB_PRCM_CONF_SYS_CLKSEL(0x3); reg &= ~TUSB_PRCM_CONF_SYS_CLKSEL(0x3);
/* 0 = refclk (clkin, XI)
* 1 = PHY 60 MHz (internal PLL)
* 2 = not supported
* 3 = NOR clock (huh?)
*/
if (mode > 0) if (mode > 0)
reg |= TUSB_PRCM_CONF_SYS_CLKSEL(mode & 0x3); reg |= TUSB_PRCM_CONF_SYS_CLKSEL(mode & 0x3);
musb_writel(base, TUSB_PRCM_CONF, reg); musb_writel(base, TUSB_PRCM_CONF, reg);
// FIXME tusb6010_platform_retime(mode == 0);
} }
/* /*
...@@ -477,7 +485,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *base) ...@@ -477,7 +485,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *base)
} }
} }
static irqreturn_t tusb_interrupt(int irq, void *__hci, struct pt_regs *r) static irqreturn_t tusb_interrupt(int irq, void *__hci)
{ {
struct musb *musb = __hci; struct musb *musb = __hci;
void __iomem *base = musb->ctrl_base; void __iomem *base = musb->ctrl_base;
...@@ -489,7 +497,6 @@ static irqreturn_t tusb_interrupt(int irq, void *__hci, struct pt_regs *r) ...@@ -489,7 +497,6 @@ static irqreturn_t tusb_interrupt(int irq, void *__hci, struct pt_regs *r)
int_src = musb_readl(base, TUSB_INT_SRC) & ~TUSB_INT_SRC_RESERVED_BITS; int_src = musb_readl(base, TUSB_INT_SRC) & ~TUSB_INT_SRC_RESERVED_BITS;
DBG(3, "TUSB IRQ %08x\n", int_src); DBG(3, "TUSB IRQ %08x\n", int_src);
musb->int_regs = r;
musb->int_usb = (u8) int_src; musb->int_usb = (u8) int_src;
/* Acknowledge wake-up source interrupts */ /* Acknowledge wake-up source interrupts */
...@@ -570,7 +577,6 @@ static irqreturn_t tusb_interrupt(int irq, void *__hci, struct pt_regs *r) ...@@ -570,7 +577,6 @@ static irqreturn_t tusb_interrupt(int irq, void *__hci, struct pt_regs *r)
musb_writel(base, TUSB_INT_SRC_CLEAR, musb_writel(base, TUSB_INT_SRC_CLEAR,
int_src & ~TUSB_INT_MASK_RESERVED_BITS); int_src & ~TUSB_INT_MASK_RESERVED_BITS);
musb->int_regs = NULL;
musb_platform_try_idle(musb); musb_platform_try_idle(musb);
spin_unlock_irqrestore(&musb->Lock, flags); spin_unlock_irqrestore(&musb->Lock, flags);
...@@ -690,10 +696,10 @@ static int tusb_print_revision(struct musb *musb) ...@@ -690,10 +696,10 @@ static int tusb_print_revision(struct musb *musb)
return TUSB_REV_MAJOR(musb_readl(base, TUSB_INT_CTRL_REV)); return TUSB_REV_MAJOR(musb_readl(base, TUSB_INT_CTRL_REV));
} }
static int tusb_start(struct musb *musb) static int __devinit tusb_start(struct musb *musb)
{ {
void __iomem *base = musb->ctrl_base; void __iomem *base = musb->ctrl_base;
int ret = -1; int ret = 0;
unsigned long flags; unsigned long flags;
u32 reg; u32 reg;
...@@ -701,7 +707,7 @@ static int tusb_start(struct musb *musb) ...@@ -701,7 +707,7 @@ static int tusb_start(struct musb *musb)
ret = musb->board_set_power(1); ret = musb->board_set_power(1);
if (ret != 0) { if (ret != 0) {
printk(KERN_ERR "tusb: Cannot enable TUSB6010\n"); printk(KERN_ERR "tusb: Cannot enable TUSB6010\n");
goto err; return ret;
} }
spin_lock_irqsave(&musb->Lock, flags); spin_lock_irqsave(&musb->Lock, flags);
...@@ -752,6 +758,8 @@ static int tusb_start(struct musb *musb) ...@@ -752,6 +758,8 @@ static int tusb_start(struct musb *musb)
return 0; return 0;
err: err:
spin_unlock_irqrestore(&musb->Lock, flags);
if (musb->board_set_power) if (musb->board_set_power)
musb->board_set_power(0); musb->board_set_power(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment