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:
@@ -46,7 +46,7 @@ static struct device *mmc_device;
|
|||||||
#define TUSB6010_GPIO_ENABLE 0
|
#define TUSB6010_GPIO_ENABLE 0
|
||||||
#define TUSB6010_DMACHAN 0x3f
|
#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
|
* 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
|
* 1.5 V voltage regulators of PM companion chip. Companion chip will then
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
|
# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
|
||||||
config USB_MUSB_HDRC
|
config USB_MUSB_HDRC
|
||||||
depends on USB && USB_GADGET
|
depends on USB && USB_GADGET
|
||||||
depends on (ARM || (BF54x && !BF544) || (BF52x && !BF522 && !BF523))
|
|
||||||
select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN)
|
select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN)
|
||||||
select TWL4030_USB if MACH_OMAP_3430SDP
|
select TWL4030_USB if MACH_OMAP_3430SDP
|
||||||
select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
|
select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
|
||||||
@@ -45,7 +44,6 @@ config USB_MUSB_DA8XX
|
|||||||
|
|
||||||
config USB_MUSB_TUSB6010
|
config USB_MUSB_TUSB6010
|
||||||
tristate "TUSB6010"
|
tristate "TUSB6010"
|
||||||
depends on ARCH_OMAP
|
|
||||||
|
|
||||||
config USB_MUSB_OMAP2PLUS
|
config USB_MUSB_OMAP2PLUS
|
||||||
tristate "OMAP2430 and onwards"
|
tristate "OMAP2430 and onwards"
|
||||||
@@ -65,46 +63,57 @@ config USB_MUSB_UX500
|
|||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config MUSB_PIO_ONLY
|
choice
|
||||||
bool 'Disable DMA (always use PIO)'
|
prompt 'MUSB DMA mode'
|
||||||
depends on USB_MUSB_HDRC
|
default USB_UX500_DMA if USB_MUSB_UX500
|
||||||
default USB_MUSB_TUSB6010 || USB_MUSB_DA8XX || USB_MUSB_AM35X
|
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
|
help
|
||||||
All data is copied between memory and FIFO by the CPU.
|
Unfortunately, only one option can be enabled here. Ideally one
|
||||||
DMA controllers are ignored.
|
should be able to build all these drivers into one kernel to
|
||||||
|
allow using DMA on multiplatform kernels.
|
||||||
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.
|
|
||||||
|
|
||||||
config USB_UX500_DMA
|
config USB_UX500_DMA
|
||||||
bool
|
bool 'ST Ericsson U8500 and U5500'
|
||||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
depends on USB_MUSB_HDRC
|
||||||
default USB_MUSB_UX500
|
depends on USB_MUSB_UX500
|
||||||
help
|
help
|
||||||
Enable DMA transfers on UX500 platforms.
|
Enable DMA transfers on UX500 platforms.
|
||||||
|
|
||||||
config USB_INVENTRA_DMA
|
config USB_INVENTRA_DMA
|
||||||
bool
|
bool 'Inventra'
|
||||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
depends on USB_MUSB_HDRC
|
||||||
default USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
|
depends on USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
|
||||||
help
|
help
|
||||||
Enable DMA transfers using Mentor's engine.
|
Enable DMA transfers using Mentor's engine.
|
||||||
|
|
||||||
config USB_TI_CPPI_DMA
|
config USB_TI_CPPI_DMA
|
||||||
bool
|
bool 'TI CPPI (Davinci)'
|
||||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
depends on USB_MUSB_HDRC
|
||||||
default USB_MUSB_DAVINCI
|
depends on USB_MUSB_DAVINCI
|
||||||
help
|
help
|
||||||
Enable DMA transfers when TI CPPI DMA is available.
|
Enable DMA transfers when TI CPPI DMA is available.
|
||||||
|
|
||||||
config USB_TUSB_OMAP_DMA
|
config USB_TUSB_OMAP_DMA
|
||||||
bool
|
bool 'TUSB 6010'
|
||||||
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
|
depends on USB_MUSB_HDRC
|
||||||
depends on USB_MUSB_TUSB6010
|
depends on USB_MUSB_TUSB6010
|
||||||
depends on ARCH_OMAP
|
depends on ARCH_OMAP
|
||||||
default y
|
|
||||||
help
|
help
|
||||||
Enable DMA transfers on TUSB 6010 when OMAP DMA is available.
|
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).
|
# PIO only, or DMA (several potential schemes).
|
||||||
# though PIO is always there to back up DMA, and for ep0
|
# though PIO is always there to back up DMA, and for ep0
|
||||||
|
|
||||||
ifneq ($(CONFIG_MUSB_PIO_ONLY),y)
|
musb_hdrc-$(CONFIG_USB_INVENTRA_DMA) += musbhsdma.o
|
||||||
|
musb_hdrc-$(CONFIG_USB_TI_CPPI_DMA) += cppi_dma.o
|
||||||
ifeq ($(CONFIG_USB_INVENTRA_DMA),y)
|
musb_hdrc-$(CONFIG_USB_TUSB_OMAP_DMA) += tusb6010_omap.o
|
||||||
musb_hdrc-y += musbhsdma.o
|
musb_hdrc-$(CONFIG_USB_UX500_DMA) += ux500_dma.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
|
|
||||||
|
@@ -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;
|
struct musb_hw_ep *hw_ep = musb->endpoints + i;
|
||||||
|
|
||||||
hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase;
|
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_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i);
|
||||||
hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i);
|
hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i);
|
||||||
hw_ep->fifo_sync_va =
|
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
|
#else
|
||||||
#define use_dma 0
|
#define use_dma 0
|
||||||
@@ -2157,6 +2158,7 @@ static void musb_save_context(struct musb *musb)
|
|||||||
if (!epio)
|
if (!epio)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
musb_writeb(musb_base, MUSB_INDEX, i);
|
||||||
musb->context.index_regs[i].txmaxp =
|
musb->context.index_regs[i].txmaxp =
|
||||||
musb_readw(epio, MUSB_TXMAXP);
|
musb_readw(epio, MUSB_TXMAXP);
|
||||||
musb->context.index_regs[i].txcsr =
|
musb->context.index_regs[i].txcsr =
|
||||||
@@ -2232,6 +2234,7 @@ static void musb_restore_context(struct musb *musb)
|
|||||||
if (!epio)
|
if (!epio)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
musb_writeb(musb_base, MUSB_INDEX, i);
|
||||||
musb_writew(epio, MUSB_TXMAXP,
|
musb_writew(epio, MUSB_TXMAXP,
|
||||||
musb->context.index_regs[i].txmaxp);
|
musb->context.index_regs[i].txmaxp);
|
||||||
musb_writew(epio, MUSB_TXCSR,
|
musb_writew(epio, MUSB_TXCSR,
|
||||||
|
@@ -40,7 +40,6 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/usb/ch9.h>
|
#include <linux/usb/ch9.h>
|
||||||
#include <linux/usb/gadget.h>
|
#include <linux/usb/gadget.h>
|
||||||
@@ -311,6 +310,7 @@ struct musb_context_registers {
|
|||||||
u8 index, testmode;
|
u8 index, testmode;
|
||||||
|
|
||||||
u8 devctl, busctl, misc;
|
u8 devctl, busctl, misc;
|
||||||
|
u32 otg_interfsel;
|
||||||
|
|
||||||
struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
|
struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
|
||||||
};
|
};
|
||||||
@@ -327,6 +327,7 @@ struct musb {
|
|||||||
|
|
||||||
irqreturn_t (*isr)(int, void *);
|
irqreturn_t (*isr)(int, void *);
|
||||||
struct work_struct irq_work;
|
struct work_struct irq_work;
|
||||||
|
struct work_struct otg_notifier_work;
|
||||||
u16 hwvers;
|
u16 hwvers;
|
||||||
|
|
||||||
/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
|
/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
|
||||||
@@ -372,6 +373,7 @@ struct musb {
|
|||||||
u16 int_tx;
|
u16 int_tx;
|
||||||
|
|
||||||
struct otg_transceiver *xceiv;
|
struct otg_transceiver *xceiv;
|
||||||
|
u8 xceiv_event;
|
||||||
|
|
||||||
int nIrq;
|
int nIrq;
|
||||||
unsigned irq_wake:1;
|
unsigned irq_wake:1;
|
||||||
|
@@ -33,11 +33,7 @@
|
|||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
|
||||||
@@ -46,10 +42,6 @@
|
|||||||
#include "musb_core.h"
|
#include "musb_core.h"
|
||||||
#include "musb_debug.h"
|
#include "musb_debug.h"
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_DAVINCI
|
|
||||||
#include "davinci.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct musb_register_map {
|
struct musb_register_map {
|
||||||
char *name;
|
char *name;
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
|
@@ -40,8 +40,6 @@
|
|||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/moduleparam.h>
|
|
||||||
#include <linux/stat.h>
|
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
@@ -37,7 +37,6 @@
|
|||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/interrupt.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); }
|
{ __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.
|
* TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum.
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
@@ -228,11 +227,21 @@ static int musb_otg_notifications(struct notifier_block *nb,
|
|||||||
unsigned long event, void *unused)
|
unsigned long event, void *unused)
|
||||||
{
|
{
|
||||||
struct musb *musb = container_of(nb, struct musb, nb);
|
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 device *dev = musb->controller;
|
||||||
struct musb_hdrc_platform_data *pdata = dev->platform_data;
|
struct musb_hdrc_platform_data *pdata = dev->platform_data;
|
||||||
struct omap_musb_board_data *data = pdata->board_data;
|
struct omap_musb_board_data *data = pdata->board_data;
|
||||||
|
|
||||||
switch (event) {
|
switch (musb->xceiv_event) {
|
||||||
case USB_EVENT_ID:
|
case USB_EVENT_ID:
|
||||||
dev_dbg(musb->controller, "ID GND\n");
|
dev_dbg(musb->controller, "ID GND\n");
|
||||||
|
|
||||||
@@ -274,10 +283,7 @@ static int musb_otg_notifications(struct notifier_block *nb,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_dbg(musb->controller, "ID float\n");
|
dev_dbg(musb->controller, "ID float\n");
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NOTIFY_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int omap2430_musb_init(struct musb *musb)
|
static int omap2430_musb_init(struct musb *musb)
|
||||||
@@ -297,6 +303,8 @@ static int omap2430_musb_init(struct musb *musb)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work);
|
||||||
|
|
||||||
status = pm_runtime_get_sync(dev);
|
status = pm_runtime_get_sync(dev);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
dev_err(dev, "pm_runtime_get_sync FAILED");
|
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 omap2430_glue *glue = dev_get_drvdata(dev);
|
||||||
struct musb *musb = glue_to_musb(glue);
|
struct musb *musb = glue_to_musb(glue);
|
||||||
|
|
||||||
|
musb->context.otg_interfsel = musb_readl(musb->mregs,
|
||||||
|
OTG_INTERFSEL);
|
||||||
|
|
||||||
omap2430_low_level_exit(musb);
|
omap2430_low_level_exit(musb);
|
||||||
otg_set_suspend(musb->xceiv, 1);
|
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);
|
struct musb *musb = glue_to_musb(glue);
|
||||||
|
|
||||||
omap2430_low_level_init(musb);
|
omap2430_low_level_init(musb);
|
||||||
|
musb_writel(musb->mregs, OTG_INTERFSEL,
|
||||||
|
musb->context.otg_interfsel);
|
||||||
|
|
||||||
otg_set_suspend(musb->xceiv, 0);
|
otg_set_suspend(musb->xceiv, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -56,6 +56,7 @@ u8 tusb_get_revision(struct musb *musb)
|
|||||||
|
|
||||||
return rev;
|
return rev;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(tusb_get_revision);
|
||||||
|
|
||||||
static int tusb_print_revision(struct musb *musb)
|
static int tusb_print_revision(struct musb *musb)
|
||||||
{
|
{
|
||||||
|
@@ -37,7 +37,6 @@ struct ux500_dma_channel {
|
|||||||
struct dma_channel channel;
|
struct dma_channel channel;
|
||||||
struct ux500_dma_controller *controller;
|
struct ux500_dma_controller *controller;
|
||||||
struct musb_hw_ep *hw_ep;
|
struct musb_hw_ep *hw_ep;
|
||||||
struct work_struct channel_work;
|
|
||||||
struct dma_chan *dma_chan;
|
struct dma_chan *dma_chan;
|
||||||
unsigned int cur_len;
|
unsigned int cur_len;
|
||||||
dma_cookie_t cookie;
|
dma_cookie_t cookie;
|
||||||
@@ -56,31 +55,11 @@ struct ux500_dma_controller {
|
|||||||
dma_addr_t phy_base;
|
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. */
|
/* 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 dma_channel *channel = private_data;
|
||||||
struct ux500_dma_channel, channel_work);
|
struct ux500_dma_channel *ux500_channel = channel->private_data;
|
||||||
struct musb_hw_ep *hw_ep = ux500_channel->hw_ep;
|
struct musb_hw_ep *hw_ep = ux500_channel->hw_ep;
|
||||||
struct musb *musb = hw_ep->musb;
|
struct musb *musb = hw_ep->musb;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@@ -94,14 +73,7 @@ static void ux500_rx_work(struct work_struct *data)
|
|||||||
musb_dma_completion(musb, hw_ep->epnum,
|
musb_dma_completion(musb, hw_ep->epnum,
|
||||||
ux500_channel->is_tx);
|
ux500_channel->is_tx);
|
||||||
spin_unlock_irqrestore(&musb->lock, flags);
|
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,
|
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;
|
void **param_array;
|
||||||
struct ux500_dma_channel *channel_array;
|
struct ux500_dma_channel *channel_array;
|
||||||
u32 ch_count;
|
u32 ch_count;
|
||||||
void (*musb_channel_work)(struct work_struct *);
|
|
||||||
dma_cap_mask_t mask;
|
dma_cap_mask_t mask;
|
||||||
|
|
||||||
if ((data->num_rx_channels > UX500_MUSB_DMA_NUM_RX_CHANNELS) ||
|
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;
|
channel_array = controller->rx_channel;
|
||||||
ch_count = data->num_rx_channels;
|
ch_count = data->num_rx_channels;
|
||||||
param_array = data->dma_rx_param_array;
|
param_array = data->dma_rx_param_array;
|
||||||
musb_channel_work = ux500_rx_work;
|
|
||||||
|
|
||||||
for (dir = 0; dir < 2; dir++) {
|
for (dir = 0; dir < 2; dir++) {
|
||||||
for (ch_num = 0; ch_num < ch_count; ch_num++) {
|
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;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_WORK(&ux500_channel->channel_work,
|
|
||||||
musb_channel_work);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare the loop for TX channels */
|
/* Prepare the loop for TX channels */
|
||||||
channel_array = controller->tx_channel;
|
channel_array = controller->tx_channel;
|
||||||
ch_count = data->num_tx_channels;
|
ch_count = data->num_tx_channels;
|
||||||
param_array = data->dma_tx_param_array;
|
param_array = data->dma_tx_param_array;
|
||||||
musb_channel_work = ux500_tx_work;
|
|
||||||
is_tx = 1;
|
is_tx = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user