Commit 6e0abdbc authored by Juha Yrjola's avatar Juha Yrjola

Merge branch 'master' of /home/git/linux-omap-2.6

parents 40cedbdb 6c4a8512
...@@ -508,7 +508,6 @@ void musb_g_tx(struct musb *pThis, u8 bEnd) ...@@ -508,7 +508,6 @@ void musb_g_tx(struct musb *pThis, u8 bEnd)
if (!pRequest) { if (!pRequest) {
DBG(4, "%s idle now\n", DBG(4, "%s idle now\n",
pEnd->end_point.name); pEnd->end_point.name);
musb_platform_try_idle(pThis);
break; break;
} }
} }
...@@ -974,8 +973,7 @@ static int musb_gadget_enable(struct usb_ep *ep, ...@@ -974,8 +973,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
pEnd->dma ? "dma, " : "", pEnd->dma ? "dma, " : "",
pEnd->wPacketSize); pEnd->wPacketSize);
pThis->status |= MUSB_VBUS_STATUS_CHG; sysfs_notify(&pThis->controller->kobj, NULL, "cable");
schedule_work(&pThis->irq_work);
fail: fail:
spin_unlock_irqrestore(&pThis->Lock, flags); spin_unlock_irqrestore(&pThis->Lock, flags);
...@@ -1018,8 +1016,7 @@ static int musb_gadget_disable(struct usb_ep *ep) ...@@ -1018,8 +1016,7 @@ static int musb_gadget_disable(struct usb_ep *ep)
/* abort all pending DMA and requests */ /* abort all pending DMA and requests */
nuke(pEnd, -ESHUTDOWN); nuke(pEnd, -ESHUTDOWN);
pThis->status |= MUSB_VBUS_STATUS_CHG; /* FIXME not for ep_disable!! */ sysfs_notify(&pThis->controller->kobj, NULL, "cable");
schedule_work(&pThis->irq_work);
spin_unlock_irqrestore(&(pThis->Lock), flags); spin_unlock_irqrestore(&(pThis->Lock), flags);
...@@ -1664,6 +1661,9 @@ int __devinit musb_gadget_setup(struct musb *pThis) ...@@ -1664,6 +1661,9 @@ int __devinit musb_gadget_setup(struct musb *pThis)
musb_g_init_endpoints(pThis); musb_g_init_endpoints(pThis);
pThis->is_active = 0;
musb_platform_try_idle(pThis);
status = device_register(&pThis->g.dev); status = device_register(&pThis->g.dev);
if (status != 0) if (status != 0)
the_gadget = NULL; the_gadget = NULL;
...@@ -1746,6 +1746,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) ...@@ -1746,6 +1746,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
*/ */
pThis->xceiv.gadget = &pThis->g; pThis->xceiv.gadget = &pThis->g;
pThis->xceiv.state = OTG_STATE_B_IDLE; pThis->xceiv.state = OTG_STATE_B_IDLE;
pThis->is_active = 1;
/* FIXME this ignores the softconnect flag. Drivers are /* FIXME this ignores the softconnect flag. Drivers are
* allowed hold the peripheral inactive until for example * allowed hold the peripheral inactive until for example
...@@ -1857,6 +1858,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ...@@ -1857,6 +1858,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
musb->pGadgetDriver = NULL; musb->pGadgetDriver = NULL;
musb->g.dev.driver = NULL; musb->g.dev.driver = NULL;
musb->is_active = 0;
musb_platform_try_idle(musb); musb_platform_try_idle(musb);
} else } else
retval = -EINVAL; retval = -EINVAL;
...@@ -1944,6 +1946,8 @@ void musb_g_disconnect(struct musb *pThis) ...@@ -1944,6 +1946,8 @@ void musb_g_disconnect(struct musb *pThis)
case OTG_STATE_B_SRP_INIT: case OTG_STATE_B_SRP_INIT:
break; break;
} }
pThis->is_active = 0;
} }
void musb_g_reset(struct musb *pThis) void musb_g_reset(struct musb *pThis)
...@@ -1977,6 +1981,7 @@ __acquires(pThis->Lock) ...@@ -1977,6 +1981,7 @@ __acquires(pThis->Lock)
? USB_SPEED_HIGH : USB_SPEED_FULL; ? USB_SPEED_HIGH : USB_SPEED_FULL;
/* start in USB_STATE_DEFAULT */ /* start in USB_STATE_DEFAULT */
pThis->is_active = 1;
MUSB_DEV_MODE(pThis); MUSB_DEV_MODE(pThis);
pThis->bAddress = 0; pThis->bAddress = 0;
pThis->ep0_state = MGC_END0_STAGE_SETUP; pThis->ep0_state = MGC_END0_STAGE_SETUP;
......
...@@ -754,11 +754,11 @@ static int musb_proc_read(char *page, char **start, ...@@ -754,11 +754,11 @@ static int musb_proc_read(char *page, char **start,
} }
} }
musb_platform_try_idle(pThis);
spin_unlock_irqrestore(&pThis->Lock, flags); spin_unlock_irqrestore(&pThis->Lock, flags);
*eof = 1; *eof = 1;
musb_platform_try_idle(pThis);
return (buffer - page) - off; return (buffer - page) - off;
} }
......
...@@ -197,9 +197,6 @@ enum musb_g_ep0_state { ...@@ -197,9 +197,6 @@ enum musb_g_ep0_state {
MGC_END0_STAGE_ACKWAIT, /* after zlp, before statusin */ MGC_END0_STAGE_ACKWAIT, /* after zlp, before statusin */
} __attribute__ ((packed)); } __attribute__ ((packed));
/* driver and cable VBUS status states for musb_irq_work */
#define MUSB_VBUS_STATUS_CHG (1 << 0)
/* failure codes */ /* failure codes */
#define MUSB_ERR_WAITING 1 #define MUSB_ERR_WAITING 1
#define MUSB_ERR_VBUS -1 #define MUSB_ERR_VBUS -1
...@@ -395,7 +392,6 @@ struct musb { ...@@ -395,7 +392,6 @@ 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 pt_regs *);
struct work_struct irq_work;
#ifdef CONFIG_USB_MUSB_HDRC_HCD #ifdef CONFIG_USB_MUSB_HDRC_HCD
...@@ -450,10 +446,11 @@ struct musb { ...@@ -450,10 +446,11 @@ struct musb {
u8 board_mode; /* enum musb_mode */ u8 board_mode; /* enum musb_mode */
int (*board_set_power)(int state); int (*board_set_power)(int state);
u8 status; /* status change flags for musb_irq_work */
s8 bFailCode; /* one of MUSB_ERR_* failure code */ s8 bFailCode; /* one of MUSB_ERR_* failure code */
/* active means connected and not suspended */
unsigned is_active:1;
unsigned bIsMultipoint:1; unsigned bIsMultipoint:1;
unsigned bIsDevice:1; unsigned bIsDevice:1;
unsigned bIsHost:1; unsigned bIsHost:1;
......
...@@ -212,6 +212,7 @@ static void otg_timeout(unsigned long ptr) ...@@ -212,6 +212,7 @@ static void otg_timeout(unsigned long ptr)
default: default:
WARN("timeout in state %d, now what?\n", pMachine->bState); WARN("timeout in state %d, now what?\n", pMachine->bState);
} }
musb_platform_try_idle(musb);
spin_unlock_irqrestore(&musb->Lock, flags); spin_unlock_irqrestore(&musb->Lock, flags);
} }
......
...@@ -384,6 +384,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB, ...@@ -384,6 +384,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
if (bIntrUSB & MGC_M_INTR_RESUME) { if (bIntrUSB & MGC_M_INTR_RESUME) {
handled = IRQ_HANDLED; handled = IRQ_HANDLED;
DBG(3, "RESUME\n"); DBG(3, "RESUME\n");
pThis->is_active = 1;
if (devctl & MGC_M_DEVCTL_HM) { if (devctl & MGC_M_DEVCTL_HM) {
#ifdef CONFIG_USB_MUSB_HDRC_HCD #ifdef CONFIG_USB_MUSB_HDRC_HCD
...@@ -458,6 +459,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB, ...@@ -458,6 +459,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
if (bIntrUSB & MGC_M_INTR_CONNECT) { if (bIntrUSB & MGC_M_INTR_CONNECT) {
handled = IRQ_HANDLED; handled = IRQ_HANDLED;
pThis->is_active = 1;
pThis->bEnd0Stage = MGC_END0_START; pThis->bEnd0Stage = MGC_END0_START;
...@@ -527,6 +529,8 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB, ...@@ -527,6 +529,8 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
otg_input_changed(pThis, devctl, TRUE, FALSE, otg_input_changed(pThis, devctl, TRUE, FALSE,
(power & MGC_M_POWER_SUSPENDM) (power & MGC_M_POWER_SUSPENDM)
? TRUE : FALSE); ? TRUE : FALSE);
sysfs_notify(&pThis->controller->kobj, NULL, "cable");
} }
handled = IRQ_HANDLED; handled = IRQ_HANDLED;
...@@ -598,6 +602,7 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB, ...@@ -598,6 +602,7 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
DBG(1, "DISCONNECT as %s, devctl %02x\n", DBG(1, "DISCONNECT as %s, devctl %02x\n",
MUSB_MODE(pThis), devctl); MUSB_MODE(pThis), devctl);
handled = IRQ_HANDLED; handled = IRQ_HANDLED;
pThis->is_active = 0;
/* need to check it against pThis, because devctl is going /* need to check it against pThis, because devctl is going
* to report ID low as soon as the device gets disconnected * to report ID low as soon as the device gets disconnected
...@@ -609,6 +614,8 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB, ...@@ -609,6 +614,8 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
/* REVISIT all OTG state machine transitions */ /* REVISIT all OTG state machine transitions */
otg_input_changed_X(pThis, FALSE, FALSE); otg_input_changed_X(pThis, FALSE, FALSE);
sysfs_notify(&pThis->controller->kobj, NULL, "cable");
} }
if (bIntrUSB & MGC_M_INTR_SUSPEND) { if (bIntrUSB & MGC_M_INTR_SUSPEND) {
...@@ -618,9 +625,15 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB, ...@@ -618,9 +625,15 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
/* peripheral suspend, may trigger HNP */ /* peripheral suspend, may trigger HNP */
if (!(devctl & MGC_M_DEVCTL_HM)) { if (!(devctl & MGC_M_DEVCTL_HM)) {
musb_g_suspend(pThis); musb_g_suspend(pThis);
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
pThis->is_active = is_otg_enabled(pThis)
&& pThis->xceiv.gadget->b_hnp_enable;
#else
pThis->is_active = 0;
#endif
otg_input_changed(pThis, devctl, FALSE, FALSE, TRUE); otg_input_changed(pThis, devctl, FALSE, FALSE, TRUE);
musb_platform_try_idle(pThis); } else
} pThis->is_active = 0;
} }
return handled; return handled;
...@@ -1416,7 +1429,6 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -1416,7 +1429,6 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
v2 = "connected"; v2 = "connected";
else else
v2 = "disconnected"; v2 = "disconnected";
musb_platform_try_idle(musb);
#else #else
/* NOTE: board-specific issues, like too-big capacitors keeping /* NOTE: board-specific issues, like too-big capacitors keeping
* VBUS high for a long time after power has been removed, can * VBUS high for a long time after power has been removed, can
...@@ -1440,6 +1452,7 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -1440,6 +1452,7 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
} else /* VBUS level below A-Valid */ } else /* VBUS level below A-Valid */
v2 = "disconnected"; v2 = "disconnected";
#endif #endif
musb_platform_try_idle(musb);
spin_unlock_irqrestore(&musb->Lock, flags); spin_unlock_irqrestore(&musb->Lock, flags);
return sprintf(buf, "%s%s\n", v1, v2); return sprintf(buf, "%s%s\n", v1, v2);
...@@ -1448,25 +1461,6 @@ static DEVICE_ATTR(cable, S_IRUGO, musb_cable_show, NULL); ...@@ -1448,25 +1461,6 @@ static DEVICE_ATTR(cable, S_IRUGO, musb_cable_show, NULL);
#endif #endif
static void musb_irq_work(void *data)
{
struct musb *musb = (struct musb *)data;
unsigned long flags;
u8 event = 0;
spin_lock_irqsave(&musb->Lock, flags);
if (musb->status & MUSB_VBUS_STATUS_CHG) {
musb->status &= ~MUSB_VBUS_STATUS_CHG;
event = 1;
}
musb_platform_try_idle(musb);
spin_unlock_irqrestore(&musb->Lock, flags);
#ifdef CONFIG_SYSFS
if (event)
sysfs_notify(&musb->controller->kobj, NULL, "cable");
#endif
}
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* Init support * Init support
*/ */
...@@ -1654,6 +1648,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1654,6 +1648,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
goto fail2; goto fail2;
} }
pThis->nIrq = nIrq; pThis->nIrq = nIrq;
device_init_wakeup(dev, 1);
pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n", pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n",
musb_driver_name, musb_driver_name,
...@@ -1668,11 +1663,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1668,11 +1663,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
? "DMA" : "PIO", ? "DMA" : "PIO",
pThis->nIrq); pThis->nIrq);
// FIXME:
// - convert to the HCD framework
// - if (board_mode == MUSB_OTG) do startup with peripheral
// - ... involves refcounting updates
#ifdef CONFIG_USB_MUSB_HDRC_HCD #ifdef CONFIG_USB_MUSB_HDRC_HCD
/* host side needs more setup, except for no-host modes */ /* host side needs more setup, except for no-host modes */
if (pThis->board_mode != MUSB_PERIPHERAL) { if (pThis->board_mode != MUSB_PERIPHERAL) {
...@@ -1737,11 +1727,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1737,11 +1727,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
musb_debug_create("driver/musb_hdrc", pThis); musb_debug_create("driver/musb_hdrc", pThis);
else { else {
fail: fail:
device_init_wakeup(dev, 0);
musb_free(pThis); musb_free(pThis);
return status;
} }
INIT_WORK(&pThis->irq_work, musb_irq_work, pThis);
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
device_create_file(dev, &dev_attr_mode); device_create_file(dev, &dev_attr_mode);
device_create_file(dev, &dev_attr_cable); device_create_file(dev, &dev_attr_cable);
...@@ -1796,15 +1786,12 @@ static int __devexit musb_remove(struct platform_device *pdev) ...@@ -1796,15 +1786,12 @@ 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);
device_init_wakeup(&pdev->dev, 0);
return 0; return 0;
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* REVISIT when power savings matter on DaVinci, look at turning
* off its phy clock during system suspend iff wakeup is disabled
*/
static int musb_suspend(struct platform_device *pdev, pm_message_t message) static int musb_suspend(struct platform_device *pdev, pm_message_t message)
{ {
unsigned long flags; unsigned long flags;
...@@ -1821,11 +1808,10 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message) ...@@ -1821,11 +1808,10 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
*/ */
} else if (is_host_active(musb)) { } else if (is_host_active(musb)) {
/* we know all the children are suspended; sometimes /* we know all the children are suspended; sometimes
* they will even be wakeup-enabled * they will even be wakeup-enabled.
*/ */
} }
musb_platform_try_idle(musb);
clk_disable(musb->clock); clk_disable(musb->clock);
spin_unlock_irqrestore(&musb->Lock, flags); spin_unlock_irqrestore(&musb->Lock, flags);
return 0; return 0;
......
This diff is collapsed.
...@@ -103,9 +103,20 @@ ...@@ -103,9 +103,20 @@
#define TUSB_PRCM_MNGMT_5V_CPEN (1 << 2) #define TUSB_PRCM_MNGMT_5V_CPEN (1 << 2)
#define TUSB_PRCM_MNGMT_PM_IDLE (1 << 1) #define TUSB_PRCM_MNGMT_PM_IDLE (1 << 1)
#define TUSB_PRCM_MNGMT_DEV_IDLE (1 << 0) #define TUSB_PRCM_MNGMT_DEV_IDLE (1 << 0)
#define TUSB_PRCM_MNGMT_PM_CLEAR_MASK ((0x3 << 3) | (0x3 << 0))
#define TUSB_PRCM_MNGMT_CPEN_MASK ((1 << 9) | (0x3 << 3)) #define TUSB_PRCM_MNGMT_PM_CLEAR_MASK \
#define TUSB_PRCM_MNGMT_SUSPEND_MASK ((1 << 10) | (0x3 << 0)) ( TUSB_PRCM_MNGMT_15_SW_EN \
| TUSB_PRCM_MNGMT_33_SW_EN \
| TUSB_PRCM_MNGMT_PM_IDLE \
| TUSB_PRCM_MNGMT_DEV_IDLE )
#define TUSB_PRCM_MNGMT_CPEN_MASK \
( TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN \
| TUSB_PRCM_MNGMT_15_SW_EN \
| TUSB_PRCM_MNGMT_33_SW_EN )
#define TUSB_PRCM_MNGMT_SUSPEND_MASK \
( TUSB_PRCM_MNGMT_OTG_SESS_END_EN \
| TUSB_PRCM_MNGMT_PM_IDLE \
| TUSB_PRCM_MNGMT_DEV_IDLE )
/* Wake-up source clear and mask registers */ /* Wake-up source clear and mask registers */
#define TUSB_PRCM_WAKEUP_SOURCE (TUSB_SYS_REG_BASE + 0x020) #define TUSB_PRCM_WAKEUP_SOURCE (TUSB_SYS_REG_BASE + 0x020)
......
...@@ -145,7 +145,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data) ...@@ -145,7 +145,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
struct musb_hw_ep *hw_ep = chdat->hw_ep; struct musb_hw_ep *hw_ep = chdat->hw_ep;
void __iomem *ep_conf = hw_ep->conf; void __iomem *ep_conf = hw_ep->conf;
void __iomem *musb_base = musb->pRegs; void __iomem *musb_base = musb->pRegs;
unsigned long transferred, flags; unsigned long remaining, flags;
int ch; int ch;
spin_lock_irqsave(&musb->Lock, flags); spin_lock_irqsave(&musb->Lock, flags);
...@@ -158,17 +158,19 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data) ...@@ -158,17 +158,19 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
if (ch_status != OMAP_DMA_BLOCK_IRQ) if (ch_status != OMAP_DMA_BLOCK_IRQ)
printk(KERN_ERR "TUSB DMA error status: %i\n", ch_status); printk(KERN_ERR "TUSB DMA error status: %i\n", ch_status);
DBG(3, "ep%i %s dma callback ch: %i status: %x\n", DBG(2, "ep%i %s dma callback ch: %i status: %x\n",
chdat->epnum, chdat->tx ? "tx" : "rx", chdat->epnum, chdat->tx ? "tx" : "rx",
ch, ch_status); ch, ch_status);
if (chdat->tx) if (chdat->tx)
transferred = musb_readl(ep_conf, TUSB_EP_TX_OFFSET); remaining = musb_readl(ep_conf, TUSB_EP_TX_OFFSET);
else else
transferred = musb_readl(ep_conf, TUSB_EP_RX_OFFSET); remaining = musb_readl(ep_conf, TUSB_EP_RX_OFFSET);
transferred = TUSB_EP_CONFIG_XFR_SIZE(transferred); remaining = TUSB_EP_CONFIG_XFR_SIZE(remaining);
channel->dwActualLength = chdat->transfer_len - transferred; channel->dwActualLength = chdat->transfer_len - remaining;
DBG(2, "remaining %lu/%lu\n", remaining, chdat->transfer_len);
if (!dmareq_works()) if (!dmareq_works())
tusb_omap_free_shared_dmareq(chdat); tusb_omap_free_shared_dmareq(chdat);
...@@ -192,7 +194,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data) ...@@ -192,7 +194,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
u16 csr; u16 csr;
if (chdat->tx) { if (chdat->tx) {
DBG(3, "terminating short tx packet\n"); DBG(2, "terminating short tx packet\n");
MGC_SelectEnd(musb_base, chdat->epnum); MGC_SelectEnd(musb_base, chdat->epnum);
csr = musb_readw(hw_ep->regs, MGC_O_HDRC_TXCSR); csr = musb_readw(hw_ep->regs, MGC_O_HDRC_TXCSR);
csr |= MGC_M_TXCSR_MODE | MGC_M_TXCSR_TXPKTRDY; csr |= MGC_M_TXCSR_MODE | MGC_M_TXCSR_TXPKTRDY;
...@@ -221,53 +223,27 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, ...@@ -221,53 +223,27 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
s8 dmareq; s8 dmareq;
s8 sync_dev; s8 sync_dev;
if (len < 32) { if (unlikely(dma_addr & 0x1))
DBG(3, "dma too short for ep%i %s dma_addr: %08x len: %u\n",
chdat->epnum, chdat->tx ? "tx" : "rx", dma_addr, len);
return FALSE; return FALSE;
} if (len < 32)
#if 0
if ((len % 32 != 0)) {
transfer_len = len / 32;
transfer_len *= 32;
DBG(3, "ep%i short %s dma: %lu/%lu %lu remainder\n",
chdat->epnum, chdat->tx ? "tx" : "rx",
transfer_len, len, len - transfer_len);
} else
transfer_len = len;
#else
if ((len % 32) != 0) {
DBG(3, "bad dma length for ep%i %s dma_addr: %08x len: %u\n",
chdat->epnum, chdat->tx ? "tx" : "rx", dma_addr, len);
return FALSE; return FALSE;
} else if ((len % 32 != 0))
transfer_len = len;
#endif
if (dma_addr & 0x1) {
DBG(3, "unaligned dma address for ep%i %s: %08x\n",
chdat->epnum, chdat->tx ? "tx" : "rx", dma_addr);
return FALSE; return FALSE;
} else
transfer_len = len;
if (dmareq_works()) { if (dmareq_works()) {
/* FIXME: Check for allocated dma ch */
ch = chdat->ch; ch = chdat->ch;
dmareq = chdat->dmareq; dmareq = chdat->dmareq;
sync_dev = chdat->sync_dev; sync_dev = chdat->sync_dev;
} else { } else {
if (tusb_omap_use_shared_dmareq(chdat) != 0) if (tusb_omap_use_shared_dmareq(chdat) != 0) {
DBG(3, "could not get dma for ep%i\n", chdat->epnum);
return FALSE; return FALSE;
}
/* FIXME: Check for allocated dma ch */
ch = tusb_dma->ch; ch = tusb_dma->ch;
dmareq = tusb_dma->dmareq; dmareq = tusb_dma->dmareq;
sync_dev = tusb_dma->sync_dev; sync_dev = tusb_dma->sync_dev;
omap_set_dma_callback(ch, tusb_omap_dma_cb, channel); omap_set_dma_callback(ch, tusb_omap_dma_cb, channel);
} }
...@@ -278,26 +254,32 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, ...@@ -278,26 +254,32 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
chdat->dma_addr = (void __iomem *)dma_addr; chdat->dma_addr = (void __iomem *)dma_addr;
channel->bStatus = MGC_DMA_STATUS_BUSY; channel->bStatus = MGC_DMA_STATUS_BUSY;
DBG(3, "ep%i %s dma ch%i dma: %08x len: %u packet_sz: %i rndis: %d\n",
chdat->epnum, chdat->tx ? "tx" : "rx",
ch, dma_addr, transfer_len, packet_sz, rndis_mode);
/* Since we're recycling dma areas, we need to clean or invalidate */ /* Since we're recycling dma areas, we need to clean or invalidate */
if (chdat->tx) if (chdat->tx) {
consistent_sync(phys_to_virt(dma_addr), len, consistent_sync(phys_to_virt(dma_addr), len, DMA_TO_DEVICE);
DMA_TO_DEVICE); } else
else consistent_sync(phys_to_virt(dma_addr), len, DMA_FROM_DEVICE);
consistent_sync(phys_to_virt(dma_addr), len,
DMA_FROM_DEVICE); /* Use 16-bit transfer if dma_addr is not 32-bit aligned */
if ((dma_addr & 0x3) == 0) {
dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
dma_params.elem_count = 8; /* Elements in frame */
} else {
dma_params.data_type = OMAP_DMA_DATA_TYPE_S16;
dma_params.elem_count = 16; /* Elements in frame */
fifo = hw_ep->fifo_async;
}
dma_params.frame_count = transfer_len / 32; /* Burst sz frame */
DBG(2, "ep%i %s dma ch%i dma: %08x len: %u(%u) packet_sz: %i\n",
chdat->epnum, chdat->tx ? "tx" : "rx",
ch, dma_addr, transfer_len, len, packet_sz);
/* /*
* Prepare omap DMA for transfer * Prepare omap DMA for transfer
*/ */
if (chdat->tx) { if (chdat->tx) {
dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
dma_params.elem_count = 8; /* 8x32-bit burst */
dma_params.frame_count = transfer_len / 32; /* Burst sz */
dma_params.src_amode = OMAP_DMA_AMODE_POST_INC; dma_params.src_amode = OMAP_DMA_AMODE_POST_INC;
dma_params.src_start = (unsigned long)dma_addr; dma_params.src_start = (unsigned long)dma_addr;
dma_params.src_ei = 0; dma_params.src_ei = 0;
...@@ -306,23 +288,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, ...@@ -306,23 +288,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dma_params.dst_amode = OMAP_DMA_AMODE_DOUBLE_IDX; dma_params.dst_amode = OMAP_DMA_AMODE_DOUBLE_IDX;
dma_params.dst_start = (unsigned long)fifo; dma_params.dst_start = (unsigned long)fifo;
dma_params.dst_ei = 1; dma_params.dst_ei = 1;
dma_params.dst_fi = -31; /* Loop 32 byte window */ dma_params.dst_fi = -31; /* Loop 32 byte window */
dma_params.trigger = sync_dev; dma_params.trigger = sync_dev;
dma_params.sync_mode = OMAP_DMA_SYNC_FRAME; dma_params.sync_mode = OMAP_DMA_SYNC_FRAME;
dma_params.src_or_dst_synch = 0; /* Dest sync */ dma_params.src_or_dst_synch = 0; /* Dest sync */
src_burst = OMAP_DMA_DATA_BURST_16; src_burst = OMAP_DMA_DATA_BURST_16; /* 16x32 read */
dst_burst = OMAP_DMA_DATA_BURST_8; dst_burst = OMAP_DMA_DATA_BURST_8; /* 8x32 write */
} else { } else {
dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
dma_params.elem_count = 8; /* 8x32-bit burst */
dma_params.frame_count = transfer_len / 32; /* Burst sz */
dma_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX; dma_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX;
dma_params.src_start = (unsigned long)fifo; dma_params.src_start = (unsigned long)fifo;
dma_params.src_ei = 1; dma_params.src_ei = 1;
dma_params.src_fi = -31; /* Loop 32 byte window */ dma_params.src_fi = -31; /* Loop 32 byte window */
dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
dma_params.dst_start = (unsigned long)dma_addr; dma_params.dst_start = (unsigned long)dma_addr;
...@@ -337,25 +315,11 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, ...@@ -337,25 +315,11 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dst_burst = OMAP_DMA_DATA_BURST_16; /* 16x32 write */ dst_burst = OMAP_DMA_DATA_BURST_16; /* 16x32 write */
} }
/* Use 16x16 transfer if addresses not 32-bit aligned */ DBG(2, "ep%i %s using %i-bit %s dma from 0x%08lx to 0x%08lx\n",
if ((dma_params.src_start & 0x2) || (dma_params.dst_start & 0x2)) { chdat->epnum, chdat->tx ? "tx" : "rx",
DBG(3, "using 16x16 async dma from 0x%08lx to 0x%08lx\n", (dma_params.data_type == OMAP_DMA_DATA_TYPE_S32) ? 32 : 16,
dma_params.src_start, dma_params.dst_start); ((dma_addr & 0x3) == 0) ? "sync" : "async",
dma_params.data_type = OMAP_DMA_DATA_TYPE_S16; dma_params.src_start, dma_params.dst_start);
dma_params.elem_count = 16; /* 16x16-bit burst */
fifo = hw_ep->fifo_async;
/* REVISIT: Check if 16x16 sync dma might also work */
if (chdat->tx)
dma_params.dst_start = (unsigned long) fifo;
else
dma_params.src_start =(unsigned long) fifo;
} else {
DBG(3, "ep%i %s using 16x32 sync dma from 0x%08lx to 0x%08lx\n",
chdat->epnum, chdat->tx ? "tx" : "rx",
dma_params.src_start, dma_params.dst_start);
}
omap_set_dma_params(ch, &dma_params); omap_set_dma_params(ch, &dma_params);
omap_set_dma_src_burst_mode(ch, src_burst); omap_set_dma_src_burst_mode(ch, src_burst);
......
...@@ -58,11 +58,15 @@ static void musb_port_suspend(struct musb *musb, u8 bSuspend) ...@@ -58,11 +58,15 @@ static void musb_port_suspend(struct musb *musb, u8 bSuspend)
musb_writeb(pBase, MGC_O_HDRC_POWER, musb_writeb(pBase, MGC_O_HDRC_POWER,
power | MGC_M_POWER_SUSPENDM); power | MGC_M_POWER_SUSPENDM);
musb->port1_status |= USB_PORT_STAT_SUSPEND; musb->port1_status |= USB_PORT_STAT_SUSPEND;
musb->is_active = is_otg_enabled(musb)
&& musb->xceiv.host->b_hnp_enable;
musb_platform_try_idle(musb);
} else if (power & MGC_M_POWER_SUSPENDM) { } else if (power & MGC_M_POWER_SUSPENDM) {
DBG(3, "Root port resumed\n"); DBG(3, "Root port resumed\n");
musb_writeb(pBase, MGC_O_HDRC_POWER, musb_writeb(pBase, MGC_O_HDRC_POWER,
power | MGC_M_POWER_RESUME); power | MGC_M_POWER_RESUME);
musb->is_active = 1;
musb_writeb(pBase, MGC_O_HDRC_POWER, power); musb_writeb(pBase, MGC_O_HDRC_POWER, power);
musb->port1_status &= ~USB_PORT_STAT_SUSPEND; musb->port1_status &= ~USB_PORT_STAT_SUSPEND;
musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
...@@ -134,6 +138,7 @@ void musb_root_disconnect(struct musb *musb) ...@@ -134,6 +138,7 @@ void musb_root_disconnect(struct musb *musb)
); );
musb->port1_status |= USB_PORT_STAT_C_CONNECTION << 16; musb->port1_status |= USB_PORT_STAT_C_CONNECTION << 16;
usb_hcd_poll_rh_status(musb_to_hcd(musb)); usb_hcd_poll_rh_status(musb_to_hcd(musb));
musb->is_active = 0;
switch (musb->xceiv.state) { switch (musb->xceiv.state) {
case OTG_STATE_A_HOST: case OTG_STATE_A_HOST:
......
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