mirror of
https://github.com/torvalds/linux.git
synced 2024-11-06 03:51:48 +00:00
Merge branch 'musb-v2.6.37-rc2' of git://gitorious.org/usb/usb into work-linus
This commit is contained in:
commit
5c4dd2242a
@ -171,8 +171,9 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci)
|
||||
}
|
||||
|
||||
/* Start sampling ID pin, when plug is removed from MUSB */
|
||||
if (is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE
|
||||
|| musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
|
||||
if ((is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE
|
||||
|| musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) ||
|
||||
(musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) {
|
||||
mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY);
|
||||
musb->a_wait_bcon = TIMER_DELAY;
|
||||
}
|
||||
@ -323,30 +324,8 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int __init musb_platform_init(struct musb *musb, void *board_data)
|
||||
static void musb_platform_reg_init(struct musb *musb)
|
||||
{
|
||||
|
||||
/*
|
||||
* Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE
|
||||
* and OTG HOST modes, while rev 1.1 and greater require PE7 to
|
||||
* be low for DEVICE mode and high for HOST mode. We set it high
|
||||
* here because we are in host mode
|
||||
*/
|
||||
|
||||
if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) {
|
||||
printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n",
|
||||
musb->config->gpio_vrsel);
|
||||
return -ENODEV;
|
||||
}
|
||||
gpio_direction_output(musb->config->gpio_vrsel, 0);
|
||||
|
||||
usb_nop_xceiv_register();
|
||||
musb->xceiv = otg_get_transceiver();
|
||||
if (!musb->xceiv) {
|
||||
gpio_free(musb->config->gpio_vrsel);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (ANOMALY_05000346) {
|
||||
bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
|
||||
SSYNC();
|
||||
@ -358,7 +337,8 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
|
||||
}
|
||||
|
||||
/* Configure PLL oscillator register */
|
||||
bfin_write_USB_PLLOSC_CTRL(0x30a8);
|
||||
bfin_write_USB_PLLOSC_CTRL(0x3080 |
|
||||
((480/musb->config->clkin) << 1));
|
||||
SSYNC();
|
||||
|
||||
bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
|
||||
@ -380,6 +360,33 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
|
||||
EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
|
||||
EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
|
||||
SSYNC();
|
||||
}
|
||||
|
||||
int __init musb_platform_init(struct musb *musb, void *board_data)
|
||||
{
|
||||
|
||||
/*
|
||||
* Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE
|
||||
* and OTG HOST modes, while rev 1.1 and greater require PE7 to
|
||||
* be low for DEVICE mode and high for HOST mode. We set it high
|
||||
* here because we are in host mode
|
||||
*/
|
||||
|
||||
if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) {
|
||||
printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d\n",
|
||||
musb->config->gpio_vrsel);
|
||||
return -ENODEV;
|
||||
}
|
||||
gpio_direction_output(musb->config->gpio_vrsel, 0);
|
||||
|
||||
usb_nop_xceiv_register();
|
||||
musb->xceiv = otg_get_transceiver();
|
||||
if (!musb->xceiv) {
|
||||
gpio_free(musb->config->gpio_vrsel);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
musb_platform_reg_init(musb);
|
||||
|
||||
if (is_host_enabled(musb)) {
|
||||
musb->board_set_vbus = bfin_set_vbus;
|
||||
@ -394,6 +401,27 @@ int __init musb_platform_init(struct musb *musb, void *board_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
void musb_platform_save_context(struct musb *musb,
|
||||
struct musb_context_registers *musb_context)
|
||||
{
|
||||
if (is_host_active(musb))
|
||||
/*
|
||||
* During hibernate gpio_vrsel will change from high to low
|
||||
* low which will generate wakeup event resume the system
|
||||
* immediately. Set it to 0 before hibernate to avoid this
|
||||
* wakeup event.
|
||||
*/
|
||||
gpio_set_value(musb->config->gpio_vrsel, 0);
|
||||
}
|
||||
|
||||
void musb_platform_restore_context(struct musb *musb,
|
||||
struct musb_context_registers *musb_context)
|
||||
{
|
||||
musb_platform_reg_init(musb);
|
||||
}
|
||||
#endif
|
||||
|
||||
int musb_platform_exit(struct musb *musb)
|
||||
{
|
||||
gpio_free(musb->config->gpio_vrsel);
|
||||
|
@ -552,7 +552,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
|
||||
if (int_usb & MUSB_INTR_SESSREQ) {
|
||||
void __iomem *mbase = musb->mregs;
|
||||
|
||||
if (devctl & MUSB_DEVCTL_BDEVICE) {
|
||||
if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS
|
||||
&& (devctl & MUSB_DEVCTL_BDEVICE)) {
|
||||
DBG(3, "SessReq while on B state\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@ -1052,6 +1053,11 @@ static void musb_shutdown(struct platform_device *pdev)
|
||||
clk_put(musb->clock);
|
||||
spin_unlock_irqrestore(&musb->lock, flags);
|
||||
|
||||
if (!is_otg_enabled(musb) && is_host_enabled(musb))
|
||||
usb_remove_hcd(musb_to_hcd(musb));
|
||||
musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
|
||||
musb_platform_exit(musb);
|
||||
|
||||
/* FIXME power down */
|
||||
}
|
||||
|
||||
@ -2244,13 +2250,6 @@ static int __exit musb_remove(struct platform_device *pdev)
|
||||
*/
|
||||
musb_exit_debugfs(musb);
|
||||
musb_shutdown(pdev);
|
||||
#ifdef CONFIG_USB_MUSB_HDRC_HCD
|
||||
if (musb->board_mode == MUSB_HOST)
|
||||
usb_remove_hcd(musb_to_hcd(musb));
|
||||
#endif
|
||||
musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
|
||||
musb_platform_exit(musb);
|
||||
musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
|
||||
|
||||
musb_free(musb);
|
||||
iounmap(ctrl_base);
|
||||
@ -2411,9 +2410,6 @@ static int musb_suspend(struct device *dev)
|
||||
unsigned long flags;
|
||||
struct musb *musb = dev_to_musb(&pdev->dev);
|
||||
|
||||
if (!musb->clock)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&musb->lock, flags);
|
||||
|
||||
if (is_peripheral_active(musb)) {
|
||||
@ -2428,10 +2424,12 @@ static int musb_suspend(struct device *dev)
|
||||
|
||||
musb_save_context(musb);
|
||||
|
||||
if (musb->set_clock)
|
||||
musb->set_clock(musb->clock, 0);
|
||||
else
|
||||
clk_disable(musb->clock);
|
||||
if (musb->clock) {
|
||||
if (musb->set_clock)
|
||||
musb->set_clock(musb->clock, 0);
|
||||
else
|
||||
clk_disable(musb->clock);
|
||||
}
|
||||
spin_unlock_irqrestore(&musb->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
@ -2441,13 +2439,12 @@ static int musb_resume_noirq(struct device *dev)
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct musb *musb = dev_to_musb(&pdev->dev);
|
||||
|
||||
if (!musb->clock)
|
||||
return 0;
|
||||
|
||||
if (musb->set_clock)
|
||||
musb->set_clock(musb->clock, 1);
|
||||
else
|
||||
clk_enable(musb->clock);
|
||||
if (musb->clock) {
|
||||
if (musb->set_clock)
|
||||
musb->set_clock(musb->clock, 1);
|
||||
else
|
||||
clk_enable(musb->clock);
|
||||
}
|
||||
|
||||
musb_restore_context(musb);
|
||||
|
||||
|
@ -487,7 +487,7 @@ struct musb_context_registers {
|
||||
};
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
|
||||
defined(CONFIG_ARCH_OMAP4)
|
||||
defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_BLACKFIN)
|
||||
extern void musb_platform_save_context(struct musb *musb,
|
||||
struct musb_context_registers *musb_context);
|
||||
extern void musb_platform_restore_context(struct musb *musb,
|
||||
|
@ -644,10 +644,8 @@ static void rxstate(struct musb *musb, struct musb_request *req)
|
||||
*/
|
||||
|
||||
csr |= MUSB_RXCSR_DMAENAB;
|
||||
if (!musb_ep->hb_mult &&
|
||||
musb_ep->hw_ep->rx_double_buffered)
|
||||
csr |= MUSB_RXCSR_AUTOCLEAR;
|
||||
#ifdef USE_MODE1
|
||||
csr |= MUSB_RXCSR_AUTOCLEAR;
|
||||
/* csr |= MUSB_RXCSR_DMAMODE; */
|
||||
|
||||
/* this special sequence (enabling and then
|
||||
@ -656,6 +654,10 @@ static void rxstate(struct musb *musb, struct musb_request *req)
|
||||
*/
|
||||
musb_writew(epio, MUSB_RXCSR,
|
||||
csr | MUSB_RXCSR_DMAMODE);
|
||||
#else
|
||||
if (!musb_ep->hb_mult &&
|
||||
musb_ep->hw_ep->rx_double_buffered)
|
||||
csr |= MUSB_RXCSR_AUTOCLEAR;
|
||||
#endif
|
||||
musb_writew(epio, MUSB_RXCSR, csr);
|
||||
|
||||
@ -807,7 +809,7 @@ void musb_g_rx(struct musb *musb, u8 epnum)
|
||||
|
||||
#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
|
||||
/* Autoclear doesn't clear RxPktRdy for short packets */
|
||||
if ((dma->desired_mode == 0)
|
||||
if ((dma->desired_mode == 0 && !hw_ep->rx_double_buffered)
|
||||
|| (dma->actual_len
|
||||
& (musb_ep->packet_sz - 1))) {
|
||||
/* ack the read! */
|
||||
@ -818,8 +820,16 @@ void musb_g_rx(struct musb *musb, u8 epnum)
|
||||
/* incomplete, and not short? wait for next IN packet */
|
||||
if ((request->actual < request->length)
|
||||
&& (musb_ep->dma->actual_len
|
||||
== musb_ep->packet_sz))
|
||||
== musb_ep->packet_sz)) {
|
||||
/* In double buffer case, continue to unload fifo if
|
||||
* there is Rx packet in FIFO.
|
||||
**/
|
||||
csr = musb_readw(epio, MUSB_RXCSR);
|
||||
if ((csr & MUSB_RXCSR_RXPKTRDY) &&
|
||||
hw_ep->rx_double_buffered)
|
||||
goto exit;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
musb_g_giveback(musb_ep, request, 0);
|
||||
|
||||
@ -827,7 +837,7 @@ void musb_g_rx(struct musb *musb, u8 epnum)
|
||||
if (!request)
|
||||
return;
|
||||
}
|
||||
|
||||
exit:
|
||||
/* Analyze request */
|
||||
rxstate(musb, to_musb_request(request));
|
||||
}
|
||||
@ -916,13 +926,9 @@ static int musb_gadget_enable(struct usb_ep *ep,
|
||||
* likewise high bandwidth periodic tx
|
||||
*/
|
||||
/* Set TXMAXP with the FIFO size of the endpoint
|
||||
* to disable double buffering mode. Currently, It seems that double
|
||||
* buffering has problem if musb RTL revision number < 2.0.
|
||||
* to disable double buffering mode.
|
||||
*/
|
||||
if (musb->hwvers < MUSB_HWVERS_2000)
|
||||
musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx);
|
||||
else
|
||||
musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
|
||||
musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
|
||||
|
||||
csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
|
||||
if (musb_readw(regs, MUSB_TXCSR)
|
||||
@ -958,10 +964,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
|
||||
/* Set RXMAXP with the FIFO size of the endpoint
|
||||
* to disable double buffering mode.
|
||||
*/
|
||||
if (musb->hwvers < MUSB_HWVERS_2000)
|
||||
musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx);
|
||||
else
|
||||
musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
|
||||
musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11));
|
||||
|
||||
/* force shared fifo to OUT-only mode */
|
||||
if (hw_ep->is_shared_fifo) {
|
||||
@ -1166,8 +1169,6 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
|
||||
: DMA_FROM_DEVICE);
|
||||
request->mapped = 0;
|
||||
}
|
||||
} else if (!req->buf) {
|
||||
return -ENODATA;
|
||||
} else
|
||||
request->mapped = 0;
|
||||
|
||||
@ -1695,8 +1696,10 @@ int __init musb_gadget_setup(struct musb *musb)
|
||||
musb_platform_try_idle(musb, 0);
|
||||
|
||||
status = device_register(&musb->g.dev);
|
||||
if (status != 0)
|
||||
if (status != 0) {
|
||||
put_device(&musb->g.dev);
|
||||
the_gadget = NULL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -633,8 +633,9 @@ static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum)
|
||||
static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BLACKFIN */
|
||||
|
@ -158,6 +158,8 @@ static int dma_channel_program(struct dma_channel *channel,
|
||||
dma_addr_t dma_addr, u32 len)
|
||||
{
|
||||
struct musb_dma_channel *musb_channel = channel->private_data;
|
||||
struct musb_dma_controller *controller = musb_channel->controller;
|
||||
struct musb *musb = controller->private_data;
|
||||
|
||||
DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
|
||||
musb_channel->epnum,
|
||||
@ -167,6 +169,18 @@ static int dma_channel_program(struct dma_channel *channel,
|
||||
BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
|
||||
channel->status == MUSB_DMA_STATUS_BUSY);
|
||||
|
||||
/*
|
||||
* The DMA engine in RTL1.8 and above cannot handle
|
||||
* DMA addresses that are not aligned to a 4 byte boundary.
|
||||
* It ends up masking the last two bits of the address
|
||||
* programmed in DMA_ADDR.
|
||||
*
|
||||
* Fail such DMA transfers, so that the backup PIO mode
|
||||
* can carry out the transfer
|
||||
*/
|
||||
if ((musb->hwvers >= MUSB_HWVERS_1800) && (dma_addr % 4))
|
||||
return false;
|
||||
|
||||
channel->actual_len = 0;
|
||||
musb_channel->start_addr = dma_addr;
|
||||
musb_channel->len = len;
|
||||
|
@ -89,6 +89,8 @@ struct musb_hdrc_config {
|
||||
/* A GPIO controlling VRSEL in Blackfin */
|
||||
unsigned int gpio_vrsel;
|
||||
unsigned int gpio_vrsel_active;
|
||||
/* musb CLKIN in Blackfin in MHZ */
|
||||
unsigned char clkin;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user