Merge branch 'for-next/musb' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
* 'for-next/musb' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb: usb: musb: omap2430: fix compile warning usb: musb: fix pm_runtime calls while atomic usb: musb: drop ARCH dependency usb: musb: headers cleanup usb: musb: allow building USB_MUSB_TUSB6010 as a module usb: musb: use a Kconfig choice to pick the right DMA method usb: musb: omap2+: save and restore OTG_INTERFSEL usb: musb: omap2+: fix context api's usb: musb: ux500: optimize DMA callback routine
This commit is contained in:
commit
a1016ce33c
12 changed files with 70 additions and 103 deletions
|
@ -46,7 +46,7 @@ static struct device *mmc_device;
|
|||
#define TUSB6010_GPIO_ENABLE 0
|
||||
#define TUSB6010_DMACHAN 0x3f
|
||||
|
||||
#ifdef CONFIG_USB_MUSB_TUSB6010
|
||||
#if defined(CONFIG_USB_MUSB_TUSB6010) || defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
|
||||
/*
|
||||
* Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
|
||||
* 1.5 V voltage regulators of PM companion chip. Companion chip will then
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
|
||||
config USB_MUSB_HDRC
|
||||
depends on USB && USB_GADGET
|
||||
depends on (ARM || (BF54x && !BF544) || (BF52x && !BF522 && !BF523))
|
||||
select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN)
|
||||
select TWL4030_USB if MACH_OMAP_3430SDP
|
||||
select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
|
||||
|
@ -45,7 +44,6 @@ config USB_MUSB_DA8XX
|
|||
|
||||
config USB_MUSB_TUSB6010
|
||||
tristate "TUSB6010"
|
||||
depends on ARCH_OMAP
|
||||
|
||||
config USB_MUSB_OMAP2PLUS
|
||||
tristate "OMAP2430 and onwards"
|
||||
|
@ -65,46 +63,57 @@ config USB_MUSB_UX500
|
|||
|
||||
endchoice
|
||||
|
||||
config MUSB_PIO_ONLY
|
||||
bool 'Disable DMA (always use PIO)'
|
||||
depends on USB_MUSB_HDRC
|
||||
default USB_MUSB_TUSB6010 || USB_MUSB_DA8XX || USB_MUSB_AM35X
|
||||
choice
|
||||
prompt 'MUSB DMA mode'
|
||||
default USB_UX500_DMA if USB_MUSB_UX500
|
||||
default USB_INVENTRA_DMA if USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
|
||||
default USB_TI_CPPI_DMA if USB_MUSB_DAVINCI
|
||||
default USB_TUSB_OMAP_DMA if USB_MUSB_TUSB6010
|
||||
default MUSB_PIO_ONLY if USB_MUSB_TUSB6010 || USB_MUSB_DA8XX || USB_MUSB_AM35X
|
||||
help
|
||||
All data is copied between memory and FIFO by the CPU.
|
||||
DMA controllers are ignored.
|
||||
|
||||
Do not select 'n' here unless DMA support for your SOC or board
|
||||
is unavailable (or unstable). When DMA is enabled at compile time,
|
||||
you can still disable it at run time using the "use_dma=n" module
|
||||
parameter.
|
||||
Unfortunately, only one option can be enabled here. Ideally one
|
||||
should be able to build all these drivers into one kernel to
|
||||
allow using DMA on multiplatform kernels.
|
||||
|
||||
config USB_UX500_DMA
|
||||
bool
|
||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
||||
default USB_MUSB_UX500
|
||||
bool 'ST Ericsson U8500 and U5500'
|
||||
depends on USB_MUSB_HDRC
|
||||
depends on USB_MUSB_UX500
|
||||
help
|
||||
Enable DMA transfers on UX500 platforms.
|
||||
|
||||
config USB_INVENTRA_DMA
|
||||
bool
|
||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
||||
default USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
|
||||
bool 'Inventra'
|
||||
depends on USB_MUSB_HDRC
|
||||
depends on USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
|
||||
help
|
||||
Enable DMA transfers using Mentor's engine.
|
||||
|
||||
config USB_TI_CPPI_DMA
|
||||
bool
|
||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
||||
default USB_MUSB_DAVINCI
|
||||
bool 'TI CPPI (Davinci)'
|
||||
depends on USB_MUSB_HDRC
|
||||
depends on USB_MUSB_DAVINCI
|
||||
help
|
||||
Enable DMA transfers when TI CPPI DMA is available.
|
||||
|
||||
config USB_TUSB_OMAP_DMA
|
||||
bool
|
||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
||||
bool 'TUSB 6010'
|
||||
depends on USB_MUSB_HDRC
|
||||
depends on USB_MUSB_TUSB6010
|
||||
depends on ARCH_OMAP
|
||||
default y
|
||||
help
|
||||
Enable DMA transfers on TUSB 6010 when OMAP DMA is available.
|
||||
|
||||
config MUSB_PIO_ONLY
|
||||
bool 'Disable DMA (always use PIO)'
|
||||
depends on USB_MUSB_HDRC
|
||||
help
|
||||
All data is copied between memory and FIFO by the CPU.
|
||||
DMA controllers are ignored.
|
||||
|
||||
Do not choose this unless DMA support for your SOC or board
|
||||
is unavailable (or unstable). When DMA is enabled at compile time,
|
||||
you can still disable it at run time using the "use_dma=n" module
|
||||
parameter.
|
||||
|
||||
endchoice
|
||||
|
|
|
@ -24,25 +24,7 @@ obj-$(CONFIG_USB_MUSB_UX500) += ux500.o
|
|||
# PIO only, or DMA (several potential schemes).
|
||||
# though PIO is always there to back up DMA, and for ep0
|
||||
|
||||
ifneq ($(CONFIG_MUSB_PIO_ONLY),y)
|
||||
|
||||
ifeq ($(CONFIG_USB_INVENTRA_DMA),y)
|
||||
musb_hdrc-y += musbhsdma.o
|
||||
|
||||
else
|
||||
ifeq ($(CONFIG_USB_TI_CPPI_DMA),y)
|
||||
musb_hdrc-y += cppi_dma.o
|
||||
|
||||
else
|
||||
ifeq ($(CONFIG_USB_TUSB_OMAP_DMA),y)
|
||||
musb_hdrc-y += tusb6010_omap.o
|
||||
|
||||
else
|
||||
ifeq ($(CONFIG_USB_UX500_DMA),y)
|
||||
musb_hdrc-y += ux500_dma.o
|
||||
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
musb_hdrc-$(CONFIG_USB_INVENTRA_DMA) += musbhsdma.o
|
||||
musb_hdrc-$(CONFIG_USB_TI_CPPI_DMA) += cppi_dma.o
|
||||
musb_hdrc-$(CONFIG_USB_TUSB_OMAP_DMA) += tusb6010_omap.o
|
||||
musb_hdrc-$(CONFIG_USB_UX500_DMA) += ux500_dma.o
|
||||
|
|
|
@ -1431,7 +1431,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
|
|||
struct musb_hw_ep *hw_ep = musb->endpoints + i;
|
||||
|
||||
hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase;
|
||||
#ifdef CONFIG_USB_MUSB_TUSB6010
|
||||
#if defined(CONFIG_USB_MUSB_TUSB6010) || defined (CONFIG_USB_MUSB_TUSB6010_MODULE)
|
||||
hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i);
|
||||
hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i);
|
||||
hw_ep->fifo_sync_va =
|
||||
|
@ -1630,6 +1630,7 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)
|
|||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(musb_dma_completion);
|
||||
|
||||
#else
|
||||
#define use_dma 0
|
||||
|
@ -2157,6 +2158,7 @@ static void musb_save_context(struct musb *musb)
|
|||
if (!epio)
|
||||
continue;
|
||||
|
||||
musb_writeb(musb_base, MUSB_INDEX, i);
|
||||
musb->context.index_regs[i].txmaxp =
|
||||
musb_readw(epio, MUSB_TXMAXP);
|
||||
musb->context.index_regs[i].txcsr =
|
||||
|
@ -2232,6 +2234,7 @@ static void musb_restore_context(struct musb *musb)
|
|||
if (!epio)
|
||||
continue;
|
||||
|
||||
musb_writeb(musb_base, MUSB_INDEX, i);
|
||||
musb_writew(epio, MUSB_TXMAXP,
|
||||
musb->context.index_regs[i].txmaxp);
|
||||
musb_writew(epio, MUSB_TXCSR,
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
|
@ -311,6 +310,7 @@ struct musb_context_registers {
|
|||
u8 index, testmode;
|
||||
|
||||
u8 devctl, busctl, misc;
|
||||
u32 otg_interfsel;
|
||||
|
||||
struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
|
||||
};
|
||||
|
@ -327,6 +327,7 @@ struct musb {
|
|||
|
||||
irqreturn_t (*isr)(int, void *);
|
||||
struct work_struct irq_work;
|
||||
struct work_struct otg_notifier_work;
|
||||
u16 hwvers;
|
||||
|
||||
/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
|
||||
|
@ -372,6 +373,7 @@ struct musb {
|
|||
u16 int_tx;
|
||||
|
||||
struct otg_transceiver *xceiv;
|
||||
u8 xceiv_event;
|
||||
|
||||
int nIrq;
|
||||
unsigned irq_wake:1;
|
||||
|
|
|
@ -33,11 +33,7 @@
|
|||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
|
@ -46,10 +42,6 @@
|
|||
#include "musb_core.h"
|
||||
#include "musb_debug.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_DAVINCI
|
||||
#include "davinci.h"
|
||||
#endif
|
||||
|
||||
struct musb_register_map {
|
||||
char *name;
|
||||
unsigned offset;
|
||||
|
|
|
@ -40,8 +40,6 @@
|
|||
#include <linux/smp.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
|
|||
{ __raw_writel(data, addr + offset); }
|
||||
|
||||
|
||||
#ifdef CONFIG_USB_MUSB_TUSB6010
|
||||
#if defined(CONFIG_USB_MUSB_TUSB6010) || defined (CONFIG_USB_MUSB_TUSB6010_MODULE)
|
||||
|
||||
/*
|
||||
* TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum.
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
@ -228,11 +227,21 @@ static int musb_otg_notifications(struct notifier_block *nb,
|
|||
unsigned long event, void *unused)
|
||||
{
|
||||
struct musb *musb = container_of(nb, struct musb, nb);
|
||||
|
||||
musb->xceiv_event = event;
|
||||
schedule_work(&musb->otg_notifier_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
|
||||
{
|
||||
struct musb *musb = container_of(data_notifier_work, struct musb, otg_notifier_work);
|
||||
struct device *dev = musb->controller;
|
||||
struct musb_hdrc_platform_data *pdata = dev->platform_data;
|
||||
struct omap_musb_board_data *data = pdata->board_data;
|
||||
|
||||
switch (event) {
|
||||
switch (musb->xceiv_event) {
|
||||
case USB_EVENT_ID:
|
||||
dev_dbg(musb->controller, "ID GND\n");
|
||||
|
||||
|
@ -274,10 +283,7 @@ static int musb_otg_notifications(struct notifier_block *nb,
|
|||
break;
|
||||
default:
|
||||
dev_dbg(musb->controller, "ID float\n");
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int omap2430_musb_init(struct musb *musb)
|
||||
|
@ -297,6 +303,8 @@ static int omap2430_musb_init(struct musb *musb)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work);
|
||||
|
||||
status = pm_runtime_get_sync(dev);
|
||||
if (status < 0) {
|
||||
dev_err(dev, "pm_runtime_get_sync FAILED");
|
||||
|
@ -491,6 +499,9 @@ static int omap2430_runtime_suspend(struct device *dev)
|
|||
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
||||
struct musb *musb = glue_to_musb(glue);
|
||||
|
||||
musb->context.otg_interfsel = musb_readl(musb->mregs,
|
||||
OTG_INTERFSEL);
|
||||
|
||||
omap2430_low_level_exit(musb);
|
||||
otg_set_suspend(musb->xceiv, 1);
|
||||
|
||||
|
@ -503,6 +514,9 @@ static int omap2430_runtime_resume(struct device *dev)
|
|||
struct musb *musb = glue_to_musb(glue);
|
||||
|
||||
omap2430_low_level_init(musb);
|
||||
musb_writel(musb->mregs, OTG_INTERFSEL,
|
||||
musb->context.otg_interfsel);
|
||||
|
||||
otg_set_suspend(musb->xceiv, 0);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -56,6 +56,7 @@ u8 tusb_get_revision(struct musb *musb)
|
|||
|
||||
return rev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tusb_get_revision);
|
||||
|
||||
static int tusb_print_revision(struct musb *musb)
|
||||
{
|
||||
|
|
|
@ -37,7 +37,6 @@ struct ux500_dma_channel {
|
|||
struct dma_channel channel;
|
||||
struct ux500_dma_controller *controller;
|
||||
struct musb_hw_ep *hw_ep;
|
||||
struct work_struct channel_work;
|
||||
struct dma_chan *dma_chan;
|
||||
unsigned int cur_len;
|
||||
dma_cookie_t cookie;
|
||||
|
@ -56,31 +55,11 @@ struct ux500_dma_controller {
|
|||
dma_addr_t phy_base;
|
||||
};
|
||||
|
||||
/* Work function invoked from DMA callback to handle tx transfers. */
|
||||
static void ux500_tx_work(struct work_struct *data)
|
||||
{
|
||||
struct ux500_dma_channel *ux500_channel = container_of(data,
|
||||
struct ux500_dma_channel, channel_work);
|
||||
struct musb_hw_ep *hw_ep = ux500_channel->hw_ep;
|
||||
struct musb *musb = hw_ep->musb;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(musb->controller, "DMA tx transfer done on hw_ep=%d\n",
|
||||
hw_ep->epnum);
|
||||
|
||||
spin_lock_irqsave(&musb->lock, flags);
|
||||
ux500_channel->channel.actual_len = ux500_channel->cur_len;
|
||||
ux500_channel->channel.status = MUSB_DMA_STATUS_FREE;
|
||||
musb_dma_completion(musb, hw_ep->epnum,
|
||||
ux500_channel->is_tx);
|
||||
spin_unlock_irqrestore(&musb->lock, flags);
|
||||
}
|
||||
|
||||
/* Work function invoked from DMA callback to handle rx transfers. */
|
||||
static void ux500_rx_work(struct work_struct *data)
|
||||
void ux500_dma_callback(void *private_data)
|
||||
{
|
||||
struct ux500_dma_channel *ux500_channel = container_of(data,
|
||||
struct ux500_dma_channel, channel_work);
|
||||
struct dma_channel *channel = private_data;
|
||||
struct ux500_dma_channel *ux500_channel = channel->private_data;
|
||||
struct musb_hw_ep *hw_ep = ux500_channel->hw_ep;
|
||||
struct musb *musb = hw_ep->musb;
|
||||
unsigned long flags;
|
||||
|
@ -94,14 +73,7 @@ static void ux500_rx_work(struct work_struct *data)
|
|||
musb_dma_completion(musb, hw_ep->epnum,
|
||||
ux500_channel->is_tx);
|
||||
spin_unlock_irqrestore(&musb->lock, flags);
|
||||
}
|
||||
|
||||
void ux500_dma_callback(void *private_data)
|
||||
{
|
||||
struct dma_channel *channel = (struct dma_channel *)private_data;
|
||||
struct ux500_dma_channel *ux500_channel = channel->private_data;
|
||||
|
||||
schedule_work(&ux500_channel->channel_work);
|
||||
}
|
||||
|
||||
static bool ux500_configure_channel(struct dma_channel *channel,
|
||||
|
@ -330,7 +302,6 @@ static int ux500_dma_controller_start(struct dma_controller *c)
|
|||
void **param_array;
|
||||
struct ux500_dma_channel *channel_array;
|
||||
u32 ch_count;
|
||||
void (*musb_channel_work)(struct work_struct *);
|
||||
dma_cap_mask_t mask;
|
||||
|
||||
if ((data->num_rx_channels > UX500_MUSB_DMA_NUM_RX_CHANNELS) ||
|
||||
|
@ -347,7 +318,6 @@ static int ux500_dma_controller_start(struct dma_controller *c)
|
|||
channel_array = controller->rx_channel;
|
||||
ch_count = data->num_rx_channels;
|
||||
param_array = data->dma_rx_param_array;
|
||||
musb_channel_work = ux500_rx_work;
|
||||
|
||||
for (dir = 0; dir < 2; dir++) {
|
||||
for (ch_num = 0; ch_num < ch_count; ch_num++) {
|
||||
|
@ -374,15 +344,12 @@ static int ux500_dma_controller_start(struct dma_controller *c)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
INIT_WORK(&ux500_channel->channel_work,
|
||||
musb_channel_work);
|
||||
}
|
||||
|
||||
/* Prepare the loop for TX channels */
|
||||
channel_array = controller->tx_channel;
|
||||
ch_count = data->num_tx_channels;
|
||||
param_array = data->dma_tx_param_array;
|
||||
musb_channel_work = ux500_tx_work;
|
||||
is_tx = 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue