summaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-13 15:28:01 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-13 15:28:01 -0700
commit165f60642ae988f0b9dcfd4988806e7a938b26c7 (patch)
tree29293f73a4b022620f68dbf48d7450e501be5855 /drivers/usb/musb
parentc23bda365dfbf56aa4d6d4a97f83136c36050e01 (diff)
parent8b841cb217fac676498de3dfe8fabe38b39cba4e (diff)
downloadblackbird-op-linux-165f60642ae988f0b9dcfd4988806e7a938b26c7.tar.gz
blackbird-op-linux-165f60642ae988f0b9dcfd4988806e7a938b26c7.zip
Merge tag 'usb-for-v3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: usb: patches for v3.12 merge window All patches here have been pending on linux-usb and sitting in linux-next for a while now. The biggest things in this tag are: DWC3 learned proper usage of threaded IRQ handlers and now we spend very little time in hardirq context. MUSB now has proper support for BeagleBone and Beaglebone Black. Tegra's USB support also got quite a bit of love and is learning to use PHY layer and generic DT attributes. Other than that, the usual pack of cleanups and non-critical fixes follow. Signed-of-by: Felipe Balbi <balbi@ti.com> Conflicts: drivers/usb/gadget/udc-core.c drivers/usb/host/ehci-tegra.c drivers/usb/musb/omap2430.c drivers/usb/musb/tusb6010.c
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/Kconfig9
-rw-r--r--drivers/usb/musb/Makefile4
-rw-r--r--drivers/usb/musb/am35x.c16
-rw-r--r--drivers/usb/musb/blackfin.c4
-rw-r--r--drivers/usb/musb/cppi_dma.c18
-rw-r--r--drivers/usb/musb/da8xx.c4
-rw-r--r--drivers/usb/musb/davinci.c4
-rw-r--r--drivers/usb/musb/musb_am335x.c55
-rw-r--r--drivers/usb/musb/musb_core.c30
-rw-r--r--drivers/usb/musb/musb_core.h8
-rw-r--r--drivers/usb/musb/musb_cppi41.c555
-rw-r--r--drivers/usb/musb/musb_dma.h21
-rw-r--r--drivers/usb/musb/musb_dsps.c382
-rw-r--r--drivers/usb/musb/musb_gadget.c87
-rw-r--r--drivers/usb/musb/musbhsdma.c17
-rw-r--r--drivers/usb/musb/omap2430.c8
-rw-r--r--drivers/usb/musb/tusb6010.c4
-rw-r--r--drivers/usb/musb/tusb6010_omap.c24
-rw-r--r--drivers/usb/musb/ux500.c2
-rw-r--r--drivers/usb/musb/ux500_dma.c21
20 files changed, 830 insertions, 443 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 797e3fd45510..c64ee09a7c0e 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -83,6 +83,8 @@ config USB_MUSB_AM35X
config USB_MUSB_DSPS
tristate "TI DSPS platforms"
+ select USB_MUSB_AM335X_CHILD
+ depends on OF_IRQ
config USB_MUSB_BLACKFIN
tristate "Blackfin"
@@ -93,6 +95,9 @@ config USB_MUSB_UX500
endchoice
+config USB_MUSB_AM335X_CHILD
+ tristate
+
choice
prompt 'MUSB DMA mode'
default MUSB_PIO_ONLY if ARCH_MULTIPLATFORM
@@ -125,6 +130,10 @@ config USB_TI_CPPI_DMA
help
Enable DMA transfers when TI CPPI DMA is available.
+config USB_TI_CPPI41_DMA
+ bool 'TI CPPI 4.1 (AM335x)'
+ depends on ARCH_OMAP
+
config USB_TUSB_OMAP_DMA
bool 'TUSB 6010'
depends on USB_MUSB_TUSB6010
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 2b82ed7c85ca..c5ea5c6dc169 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -20,6 +20,9 @@ obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o
obj-$(CONFIG_USB_MUSB_BLACKFIN) += blackfin.o
obj-$(CONFIG_USB_MUSB_UX500) += ux500.o
+
+obj-$(CONFIG_USB_MUSB_AM335X_CHILD) += musb_am335x.o
+
# the kconfig must guarantee that only one of the
# possible I/O schemes will be enabled at a time ...
# PIO only, or DMA (several potential schemes).
@@ -29,3 +32,4 @@ 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
+musb_hdrc-$(CONFIG_USB_TI_CPPI41_DMA) += musb_cppi41.o
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 2231850c0625..5c310c664218 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -33,7 +33,7 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
#include <linux/platform_data/usb-omap.h>
#include "musb_core.h"
@@ -218,7 +218,7 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
struct musb *musb = hci;
void __iomem *reg_base = musb->ctrl_base;
struct device *dev = musb->controller;
- struct musb_hdrc_platform_data *plat = dev->platform_data;
+ struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
struct omap_musb_board_data *data = plat->board_data;
struct usb_otg *otg = musb->xceiv->otg;
unsigned long flags;
@@ -335,7 +335,7 @@ eoi:
static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode)
{
struct device *dev = musb->controller;
- struct musb_hdrc_platform_data *plat = dev->platform_data;
+ struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
struct omap_musb_board_data *data = plat->board_data;
int retval = 0;
@@ -350,7 +350,7 @@ static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode)
static int am35x_musb_init(struct musb *musb)
{
struct device *dev = musb->controller;
- struct musb_hdrc_platform_data *plat = dev->platform_data;
+ struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
struct omap_musb_board_data *data = plat->board_data;
void __iomem *reg_base = musb->ctrl_base;
u32 rev;
@@ -394,7 +394,7 @@ static int am35x_musb_init(struct musb *musb)
static int am35x_musb_exit(struct musb *musb)
{
struct device *dev = musb->controller;
- struct musb_hdrc_platform_data *plat = dev->platform_data;
+ struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
struct omap_musb_board_data *data = plat->board_data;
del_timer_sync(&otg_workaround);
@@ -456,7 +456,7 @@ static u64 am35x_dmamask = DMA_BIT_MASK(32);
static int am35x_probe(struct platform_device *pdev)
{
- struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct am35x_glue *glue;
@@ -577,7 +577,7 @@ static int am35x_remove(struct platform_device *pdev)
static int am35x_suspend(struct device *dev)
{
struct am35x_glue *glue = dev_get_drvdata(dev);
- struct musb_hdrc_platform_data *plat = dev->platform_data;
+ struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
struct omap_musb_board_data *data = plat->board_data;
/* Shutdown the on-chip PHY and its PLL. */
@@ -593,7 +593,7 @@ static int am35x_suspend(struct device *dev)
static int am35x_resume(struct device *dev)
{
struct am35x_glue *glue = dev_get_drvdata(dev);
- struct musb_hdrc_platform_data *plat = dev->platform_data;
+ struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
struct omap_musb_board_data *data = plat->board_data;
int ret;
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index 6ba8439bd5a6..72e2056b6082 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -19,7 +19,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/prefetch.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
#include <asm/cacheflush.h>
@@ -451,7 +451,7 @@ static u64 bfin_dmamask = DMA_BIT_MASK(32);
static int bfin_probe(struct platform_device *pdev)
{
struct resource musb_resources[2];
- struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct bfin_glue *glue;
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 9db211ee15b5..904fb85d85a6 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -150,14 +150,11 @@ static void cppi_pool_free(struct cppi_channel *c)
c->last_processed = NULL;
}
-static int cppi_controller_start(struct dma_controller *c)
+static void cppi_controller_start(struct cppi *controller)
{
- struct cppi *controller;
void __iomem *tibase;
int i;
- controller = container_of(c, struct cppi, controller);
-
/* do whatever is necessary to start controller */
for (i = 0; i < ARRAY_SIZE(controller->tx); i++) {
controller->tx[i].transmit = true;
@@ -212,8 +209,6 @@ static int cppi_controller_start(struct dma_controller *c)
/* disable RNDIS mode, also host rx RNDIS autorequest */
musb_writel(tibase, DAVINCI_RNDIS_REG, 0);
musb_writel(tibase, DAVINCI_AUTOREQ_REG, 0);
-
- return 0;
}
/*
@@ -222,14 +217,12 @@ static int cppi_controller_start(struct dma_controller *c)
* De-Init the DMA controller as necessary.
*/
-static int cppi_controller_stop(struct dma_controller *c)
+static void cppi_controller_stop(struct cppi *controller)
{
- struct cppi *controller;
void __iomem *tibase;
int i;
struct musb *musb;
- controller = container_of(c, struct cppi, controller);
musb = controller->musb;
tibase = controller->tibase;
@@ -255,8 +248,6 @@ static int cppi_controller_stop(struct dma_controller *c)
/*disable tx/rx cppi */
musb_writel(tibase, DAVINCI_TXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_DISABLE);
musb_writel(tibase, DAVINCI_RXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_DISABLE);
-
- return 0;
}
/* While dma channel is allocated, we only want the core irqs active
@@ -1321,8 +1312,6 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mr
controller->tibase = mregs - DAVINCI_BASE_OFFSET;
controller->musb = musb;
- controller->controller.start = cppi_controller_start;
- controller->controller.stop = cppi_controller_stop;
controller->controller.channel_alloc = cppi_channel_allocate;
controller->controller.channel_release = cppi_channel_release;
controller->controller.channel_program = cppi_channel_program;
@@ -1351,6 +1340,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mr
controller->irq = irq;
}
+ cppi_controller_start(controller);
return &controller->controller;
}
@@ -1363,6 +1353,8 @@ void dma_controller_destroy(struct dma_controller *c)
cppi = container_of(c, struct cppi, controller);
+ cppi_controller_stop(cppi);
+
if (cppi->irq)
free_irq(cppi->irq, cppi->musb);
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 0da6f648a9fe..d9ddf4122f37 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -33,7 +33,7 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
#include <mach/da8xx.h>
#include <linux/platform_data/usb-davinci.h>
@@ -477,7 +477,7 @@ static u64 da8xx_dmamask = DMA_BIT_MASK(32);
static int da8xx_probe(struct platform_device *pdev)
{
struct resource musb_resources[2];
- struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct da8xx_glue *glue;
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index f8aeaf2e2cd1..ed0834e2b72e 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -33,7 +33,7 @@
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
#include <mach/cputype.h>
#include <mach/hardware.h>
@@ -510,7 +510,7 @@ static u64 davinci_dmamask = DMA_BIT_MASK(32);
static int davinci_probe(struct platform_device *pdev)
{
struct resource musb_resources[2];
- struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct davinci_glue *glue;
struct clk *clk;
diff --git a/drivers/usb/musb/musb_am335x.c b/drivers/usb/musb/musb_am335x.c
new file mode 100644
index 000000000000..41ac5b5b57ce
--- /dev/null
+++ b/drivers/usb/musb/musb_am335x.c
@@ -0,0 +1,55 @@
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+
+static int am335x_child_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ pm_runtime_enable(&pdev->dev);
+
+ ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ pm_runtime_disable(&pdev->dev);
+ return ret;
+}
+
+static int of_remove_populated_child(struct device *dev, void *d)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ of_device_unregister(pdev);
+ return 0;
+}
+
+static int am335x_child_remove(struct platform_device *pdev)
+{
+ device_for_each_child(&pdev->dev, NULL, of_remove_populated_child);
+ pm_runtime_disable(&pdev->dev);
+ return 0;
+}
+
+static const struct of_device_id am335x_child_of_match[] = {
+ { .compatible = "ti,am33xx-usb" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, am335x_child_of_match);
+
+static struct platform_driver am335x_child_driver = {
+ .probe = am335x_child_probe,
+ .remove = am335x_child_remove,
+ .driver = {
+ .name = "am335x-usb-childs",
+ .of_match_table = of_match_ptr(am335x_child_of_match),
+ },
+};
+
+module_platform_driver(am335x_child_driver);
+MODULE_DESCRIPTION("AM33xx child devices");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 9e59710efee7..18e877ffe7b7 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1763,12 +1763,8 @@ static void musb_free(struct musb *musb)
disable_irq_wake(musb->nIrq);
free_irq(musb->nIrq, musb);
}
- if (is_dma_capable() && musb->dma_controller) {
- struct dma_controller *c = musb->dma_controller;
-
- (void) c->stop(c);
- dma_controller_destroy(c);
- }
+ if (musb->dma_controller)
+ dma_controller_destroy(musb->dma_controller);
musb_host_free(musb);
}
@@ -1786,7 +1782,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
{
int status;
struct musb *musb;
- struct musb_hdrc_platform_data *plat = dev->platform_data;
+ struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
/* The driver might handle more features than the board; OK.
* Fail when the board needs a feature that's not enabled.
@@ -1843,19 +1839,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
pm_runtime_get_sync(musb->controller);
-#ifndef CONFIG_MUSB_PIO_ONLY
- if (use_dma && dev->dma_mask) {
- struct dma_controller *c;
-
- c = dma_controller_create(musb, musb->mregs);
- musb->dma_controller = c;
- if (c)
- (void) c->start(c);
- }
-#endif
- /* ideally this would be abstracted in platform setup */
- if (!is_dma_capable() || !musb->dma_controller)
- dev->dma_mask = NULL;
+ if (use_dma && dev->dma_mask)
+ musb->dma_controller = dma_controller_create(musb, musb->mregs);
/* be sure interrupts are disabled before connecting ISR */
musb_platform_disable(musb);
@@ -1943,6 +1928,8 @@ fail4:
musb_gadget_cleanup(musb);
fail3:
+ if (musb->dma_controller)
+ dma_controller_destroy(musb->dma_controller);
pm_runtime_put_sync(musb->controller);
fail2:
@@ -2001,9 +1988,6 @@ static int musb_remove(struct platform_device *pdev)
musb_free(musb);
device_init_wakeup(dev, 0);
-#ifndef CONFIG_MUSB_PIO_ONLY
- dma_set_mask(dev, *dev->parent->dma_mask);
-#endif
return 0;
}
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 7d341c387eab..65f3917b4fc5 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -83,11 +83,6 @@ enum {
MUSB_PORT_MODE_DUAL_ROLE,
};
-#ifdef CONFIG_PROC_FS
-#include <linux/fs.h>
-#define MUSB_CONFIG_PROC_FS
-#endif
-
/****************************** CONSTANTS ********************************/
#ifndef MUSB_C_NUM_EPS
@@ -425,9 +420,6 @@ struct musb {
struct musb_hdrc_config *config;
-#ifdef MUSB_CONFIG_PROC_FS
- struct proc_dir_entry *proc_entry;
-#endif
int xceiv_old_state;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_root;
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
new file mode 100644
index 000000000000..e64701d15401
--- /dev/null
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -0,0 +1,555 @@
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/sizes.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+
+#include "musb_core.h"
+
+#define RNDIS_REG(x) (0x80 + ((x - 1) * 4))
+
+#define EP_MODE_AUTOREG_NONE 0
+#define EP_MODE_AUTOREG_ALL_NEOP 1
+#define EP_MODE_AUTOREG_ALWAYS 3
+
+#define EP_MODE_DMA_TRANSPARENT 0
+#define EP_MODE_DMA_RNDIS 1
+#define EP_MODE_DMA_GEN_RNDIS 3
+
+#define USB_CTRL_TX_MODE 0x70
+#define USB_CTRL_RX_MODE 0x74
+#define USB_CTRL_AUTOREQ 0xd0
+#define USB_TDOWN 0xd8
+
+struct cppi41_dma_channel {
+ struct dma_channel channel;
+ struct cppi41_dma_controller *controller;
+ struct musb_hw_ep *hw_ep;
+ struct dma_chan *dc;
+ dma_cookie_t cookie;
+ u8 port_num;
+ u8 is_tx;
+ u8 is_allocated;
+ u8 usb_toggle;
+
+ dma_addr_t buf_addr;
+ u32 total_len;
+ u32 prog_len;
+ u32 transferred;
+ u32 packet_sz;
+};
+
+#define MUSB_DMA_NUM_CHANNELS 15
+
+struct cppi41_dma_controller {
+ struct dma_controller controller;
+ struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS];
+ struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS];
+ struct musb *musb;
+ u32 rx_mode;
+ u32 tx_mode;
+ u32 auto_req;
+};
+
+static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
+{
+ u16 csr;
+ u8 toggle;
+
+ if (cppi41_channel->is_tx)
+ return;
+ if (!is_host_active(cppi41_channel->controller->musb))
+ return;
+
+ csr = musb_readw(cppi41_channel->hw_ep->regs, MUSB_RXCSR);
+ toggle = csr & MUSB_RXCSR_H_DATATOGGLE ? 1 : 0;
+
+ cppi41_channel->usb_toggle = toggle;
+}
+
+static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
+{
+ u16 csr;
+ u8 toggle;
+
+ if (cppi41_channel->is_tx)
+ return;
+ if (!is_host_active(cppi41_channel->controller->musb))
+ return;
+
+ csr = musb_readw(cppi41_channel->hw_ep->regs, MUSB_RXCSR);
+ toggle = csr & MUSB_RXCSR_H_DATATOGGLE ? 1 : 0;
+
+ /*
+ * AM335x Advisory 1.0.13: Due to internal synchronisation error the
+ * data toggle may reset from DATA1 to DATA0 during receiving data from
+ * more than one endpoint.
+ */
+ if (!toggle && toggle == cppi41_channel->usb_toggle) {
+ csr |= MUSB_RXCSR_H_DATATOGGLE | MUSB_RXCSR_H_WR_DATATOGGLE;
+ musb_writew(cppi41_channel->hw_ep->regs, MUSB_RXCSR, csr);
+ dev_dbg(cppi41_channel->controller->musb->controller,
+ "Restoring DATA1 toggle.\n");
+ }
+
+ cppi41_channel->usb_toggle = toggle;
+}
+
+static void cppi41_dma_callback(void *private_data)
+{
+ struct dma_channel *channel = private_data;
+ struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+ struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
+ struct musb *musb = hw_ep->musb;
+ unsigned long flags;
+ struct dma_tx_state txstate;
+ u32 transferred;
+
+ spin_lock_irqsave(&musb->lock, flags);
+
+ dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
+ &txstate);
+ transferred = cppi41_channel->prog_len - txstate.residue;
+ cppi41_channel->transferred += transferred;
+
+ dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n",
+ hw_ep->epnum, cppi41_channel->transferred,
+ cppi41_channel->total_len);
+
+ update_rx_toggle(cppi41_channel);
+
+ if (cppi41_channel->transferred == cppi41_channel->total_len ||
+ transferred < cppi41_channel->packet_sz) {
+
+ /* done, complete */
+ cppi41_channel->channel.actual_len =
+ cppi41_channel->transferred;
+ cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE;
+ musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx);
+ } else {
+ /* next iteration, reload */
+ struct dma_chan *dc = cppi41_channel->dc;
+ struct dma_async_tx_descriptor *dma_desc;
+ enum dma_transfer_direction direction;
+ u16 csr;
+ u32 remain_bytes;
+ void __iomem *epio = cppi41_channel->hw_ep->regs;
+
+ cppi41_channel->buf_addr += cppi41_channel->packet_sz;
+
+ remain_bytes = cppi41_channel->total_len;
+ remain_bytes -= cppi41_channel->transferred;
+ remain_bytes = min(remain_bytes, cppi41_channel->packet_sz);
+ cppi41_channel->prog_len = remain_bytes;
+
+ direction = cppi41_channel->is_tx ? DMA_MEM_TO_DEV
+ : DMA_DEV_TO_MEM;
+ dma_desc = dmaengine_prep_slave_single(dc,
+ cppi41_channel->buf_addr,
+ remain_bytes,
+ direction,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (WARN_ON(!dma_desc))
+ return;
+
+ dma_desc->callback = cppi41_dma_callback;
+ dma_desc->callback_param = channel;
+ cppi41_channel->cookie = dma_desc->tx_submit(dma_desc);
+ dma_async_issue_pending(dc);
+
+ if (!cppi41_channel->is_tx) {
+ csr = musb_readw(epio, MUSB_RXCSR);
+ csr |= MUSB_RXCSR_H_REQPKT;
+ musb_writew(epio, MUSB_RXCSR, csr);
+ }
+ }
+ spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+static u32 update_ep_mode(unsigned ep, unsigned mode, u32 old)
+{
+ unsigned shift;
+
+ shift = (ep - 1) * 2;
+ old &= ~(3 << shift);
+ old |= mode << shift;
+ return old;
+}
+
+static void cppi41_set_dma_mode(struct cppi41_dma_channel *cppi41_channel,
+ unsigned mode)
+{
+ struct cppi41_dma_controller *controller = cppi41_channel->controller;
+ u32 port;
+ u32 new_mode;
+ u32 old_mode;
+
+ if (cppi41_channel->is_tx)
+ old_mode = controller->tx_mode;
+ else
+ old_mode = controller->rx_mode;
+ port = cppi41_channel->port_num;
+ new_mode = update_ep_mode(port, mode, old_mode);
+
+ if (new_mode == old_mode)
+ return;
+ if (cppi41_channel->is_tx) {
+ controller->tx_mode = new_mode;
+ musb_writel(controller->musb->ctrl_base, USB_CTRL_TX_MODE,
+ new_mode);
+ } else {
+ controller->rx_mode = new_mode;
+ musb_writel(controller->musb->ctrl_base, USB_CTRL_RX_MODE,
+ new_mode);
+ }
+}
+
+static void cppi41_set_autoreq_mode(struct cppi41_dma_channel *cppi41_channel,
+ unsigned mode)
+{
+ struct cppi41_dma_controller *controller = cppi41_channel->controller;
+ u32 port;
+ u32 new_mode;
+ u32 old_mode;
+
+ old_mode = controller->auto_req;
+ port = cppi41_channel->port_num;
+ new_mode = update_ep_mode(port, mode, old_mode);
+
+ if (new_mode == old_mode)
+ return;
+ controller->auto_req = new_mode;
+ musb_writel(controller->musb->ctrl_base, USB_CTRL_AUTOREQ, new_mode);
+}
+
+static bool cppi41_configure_channel(struct dma_channel *channel,
+ u16 packet_sz, u8 mode,
+ dma_addr_t dma_addr, u32 len)
+{
+ struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+ struct dma_chan *dc = cppi41_channel->dc;
+ struct dma_async_tx_descriptor *dma_desc;
+ enum dma_transfer_direction direction;
+ struct musb *musb = cppi41_channel->controller->musb;
+ unsigned use_gen_rndis = 0;
+
+ dev_dbg(musb->controller,
+ "configure ep%d/%x packet_sz=%d, mode=%d, dma_addr=0x%llx, len=%d is_tx=%d\n",
+ cppi41_channel->port_num, RNDIS_REG(cppi41_channel->port_num),
+ packet_sz, mode, (unsigned long long) dma_addr,
+ len, cppi41_channel->is_tx);
+
+ cppi41_channel->buf_addr = dma_addr;
+ cppi41_channel->total_len = len;
+ cppi41_channel->transferred = 0;
+ cppi41_channel->packet_sz = packet_sz;
+
+ /*
+ * Due to AM335x' Advisory 1.0.13 we are not allowed to transfer more
+ * than max packet size at a time.
+ */
+ if (cppi41_channel->is_tx)
+ use_gen_rndis = 1;
+
+ if (use_gen_rndis) {
+ /* RNDIS mode */
+ if (len > packet_sz) {
+ musb_writel(musb->ctrl_base,
+ RNDIS_REG(cppi41_channel->port_num), len);
+ /* gen rndis */
+ cppi41_set_dma_mode(cppi41_channel,
+ EP_MODE_DMA_GEN_RNDIS);
+
+ /* auto req */
+ cppi41_set_autoreq_mode(cppi41_channel,
+ EP_MODE_AUTOREG_ALL_NEOP);
+ } else {
+ musb_writel(musb->ctrl_base,
+ RNDIS_REG(cppi41_channel->port_num), 0);
+ cppi41_set_dma_mode(cppi41_channel,
+ EP_MODE_DMA_TRANSPARENT);
+ cppi41_set_autoreq_mode(cppi41_channel,
+ EP_MODE_AUTOREG_NONE);
+ }
+ } else {
+ /* fallback mode */
+ cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT);
+ cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREG_NONE);
+ len = min_t(u32, packet_sz, len);
+ }
+ cppi41_channel->prog_len = len;
+ direction = cppi41_channel->is_tx ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
+ dma_desc = dmaengine_prep_slave_single(dc, dma_addr, len, direction,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!dma_desc)
+ return false;
+
+ dma_desc->callback = cppi41_dma_callback;
+ dma_desc->callback_param = channel;
+ cppi41_channel->cookie = dma_desc->tx_submit(dma_desc);
+
+ save_rx_toggle(cppi41_channel);
+ dma_async_issue_pending(dc);
+ return true;
+}
+
+static struct dma_channel *cppi41_dma_channel_allocate(struct dma_controller *c,
+ struct musb_hw_ep *hw_ep, u8 is_tx)
+{
+ struct cppi41_dma_controller *controller = container_of(c,
+ struct cppi41_dma_controller, controller);
+ struct cppi41_dma_channel *cppi41_channel = NULL;
+ u8 ch_num = hw_ep->epnum - 1;
+
+ if (ch_num >= MUSB_DMA_NUM_CHANNELS)
+ return NULL;
+
+ if (is_tx)
+ cppi41_channel = &controller->tx_channel[ch_num];
+ else
+ cppi41_channel = &controller->rx_channel[ch_num];
+
+ if (!cppi41_channel->dc)
+ return NULL;
+
+ if (cppi41_channel->is_allocated)
+ return NULL;
+
+ cppi41_channel->hw_ep = hw_ep;
+ cppi41_channel->is_allocated = 1;
+
+ return &cppi41_channel->channel;
+}
+
+static void cppi41_dma_channel_release(struct dma_channel *channel)
+{
+ struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+
+ if (cppi41_channel->is_allocated) {
+ cppi41_channel->is_allocated = 0;
+ channel->status = MUSB_DMA_STATUS_FREE;
+ channel->actual_len = 0;
+ }
+}
+
+static int cppi41_dma_channel_program(struct dma_channel *channel,
+ u16 packet_sz, u8 mode,
+ dma_addr_t dma_addr, u32 len)
+{
+ int ret;
+
+ BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
+ channel->status == MUSB_DMA_STATUS_BUSY);
+
+ channel->status = MUSB_DMA_STATUS_BUSY;
+ channel->actual_len = 0;
+ ret = cppi41_configure_channel(channel, packet_sz, mode, dma_addr, len);
+ if (!ret)
+ channel->status = MUSB_DMA_STATUS_FREE;
+
+ return ret;
+}
+
+static int cppi41_is_compatible(struct dma_channel *channel, u16 maxpacket,
+ void *buf, u32 length)
+{
+ struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+ struct cppi41_dma_controller *controller = cppi41_channel->controller;
+ struct musb *musb = controller->musb;
+
+ if (is_host_active(musb)) {
+ WARN_ON(1);
+ return 1;
+ }
+ if (cppi41_channel->is_tx)
+ return 1;
+ /* AM335x Advisory 1.0.13. No workaround for device RX mode */
+ return 0;
+}
+
+static int cppi41_dma_channel_abort(struct dma_channel *channel)
+{
+ struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+ struct cppi41_dma_controller *controller = cppi41_channel->controller;
+ struct musb *musb = controller->musb;
+ void __iomem *epio = cppi41_channel->hw_ep->regs;
+ int tdbit;
+ int ret;
+ unsigned is_tx;
+ u16 csr;
+
+ is_tx = cppi41_channel->is_tx;
+ dev_dbg(musb->controller, "abort channel=%d, is_tx=%d\n",
+ cppi41_channel->port_num, is_tx);
+
+ if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)
+ return 0;
+
+ if (is_tx) {
+ csr = musb_readw(epio, MUSB_TXCSR);
+ csr &= ~MUSB_TXCSR_DMAENAB;
+ musb_writew(epio, MUSB_TXCSR, csr);
+ } else {
+ csr = musb_readw(epio, MUSB_RXCSR);
+ csr &= ~(MUSB_RXCSR_H_REQPKT | MUSB_RXCSR_DMAENAB);
+ musb_writew(epio, MUSB_RXCSR, csr);
+
+ csr = musb_readw(epio, MUSB_RXCSR);
+ if (csr & MUSB_RXCSR_RXPKTRDY) {
+ csr |= MUSB_RXCSR_FLUSHFIFO;
+ musb_writew(epio, MUSB_RXCSR, csr);
+ musb_writew(epio, MUSB_RXCSR, csr);
+ }
+ }
+
+ tdbit = 1 << cppi41_channel->port_num;
+ if (is_tx)
+ tdbit <<= 16;
+
+ do {
+ musb_writel(musb->ctrl_base, USB_TDOWN, tdbit);
+ ret = dmaengine_terminate_all(cppi41_channel->dc);
+ } while (ret == -EAGAIN);
+
+ musb_writel(musb->ctrl_base, USB_TDOWN, tdbit);
+
+ if (is_tx) {
+ csr = musb_readw(epio, MUSB_TXCSR);
+ if (csr & MUSB_TXCSR_TXPKTRDY) {
+ csr |= MUSB_TXCSR_FLUSHFIFO;
+ musb_writew(epio, MUSB_TXCSR, csr);
+ }
+ }
+
+ cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE;
+ return 0;
+}
+
+static void cppi41_release_all_dma_chans(struct cppi41_dma_controller *ctrl)
+{
+ struct dma_chan *dc;
+ int i;
+
+ for (i = 0; i < MUSB_DMA_NUM_CHANNELS; i++) {
+ dc = ctrl->tx_channel[i].dc;
+ if (dc)
+ dma_release_channel(dc);
+ dc = ctrl->rx_channel[i].dc;
+ if (dc)
+ dma_release_channel(dc);
+ }
+}
+
+static void cppi41_dma_controller_stop(struct cppi41_dma_controller *controller)
+{
+ cppi41_release_all_dma_chans(controller);
+}
+
+static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
+{
+ struct musb *musb = controller->musb;
+ struct device *dev = musb->controller;
+ struct device_node *np = dev->of_node;
+ struct cppi41_dma_channel *cppi41_channel;
+ int count;
+ int i;
+ int ret;
+
+ count = of_property_count_strings(np, "dma-names");
+ if (count < 0)
+ return count;
+
+ for (i = 0; i < count; i++) {
+ struct dma_chan *dc;
+ struct dma_channel *musb_dma;
+ const char *str;
+ unsigned is_tx;
+ unsigned int port;
+
+ ret = of_property_read_string_index(np, "dma-names", i, &str);
+ if (ret)
+ goto err;
+ if (!strncmp(str, "tx", 2))
+ is_tx = 1;
+ else if (!strncmp(str, "rx", 2))
+ is_tx = 0;
+ else {
+ dev_err(dev, "Wrong dmatype %s\n", str);
+ goto err;
+ }
+ ret = kstrtouint(str + 2, 0, &port);
+ if (ret)
+ goto err;
+
+ if (port > MUSB_DMA_NUM_CHANNELS || !port)
+ goto err;
+ if (is_tx)
+ cppi41_channel = &controller->tx_channel[port - 1];
+ else
+ cppi41_channel = &controller->rx_channel[port - 1];
+
+ cppi41_channel->controller = controller;
+ cppi41_channel->port_num = port;
+ cppi41_channel->is_tx = is_tx;
+
+ musb_dma = &cppi41_channel->channel;
+ musb_dma->private_data = cppi41_channel;
+ musb_dma->status = MUSB_DMA_STATUS_FREE;
+ musb_dma->max_len = SZ_4M;
+
+ dc = dma_request_slave_channel(dev, str);
+ if (!dc) {
+ dev_err(dev, "Falied to request %s.\n", str);
+ goto err;
+ }
+ cppi41_channel->dc = dc;
+ }
+ return 0;
+err:
+ cppi41_release_all_dma_chans(controller);
+ return -EINVAL;
+}
+
+void dma_controller_destroy(struct dma_controller *c)
+{
+ struct cppi41_dma_controller *controller = container_of(c,
+ struct cppi41_dma_controller, controller);
+
+ cppi41_dma_controller_stop(controller);
+ kfree(controller);
+}
+
+struct dma_controller *dma_controller_create(struct musb *musb,
+ void __iomem *base)
+{
+ struct cppi41_dma_controller *controller;
+ int ret;
+
+ if (!musb->controller->of_node) {
+ dev_err(musb->controller, "Need DT for the DMA engine.\n");
+ return NULL;
+ }
+
+ controller = kzalloc(sizeof(*controller), GFP_KERNEL);
+ if (!controller)
+ goto kzalloc_fail;
+
+ controller->musb = musb;
+
+ controller->controller.channel_alloc = cppi41_dma_channel_allocate;
+ controller->controller.channel_release = cppi41_dma_channel_release;
+ controller->controller.channel_program = cppi41_dma_channel_program;
+ controller->controller.channel_abort = cppi41_dma_channel_abort;
+ controller->controller.is_compatible = cppi41_is_compatible;
+
+ ret = cppi41_dma_controller_start(controller);
+ if (ret)
+ goto plat_get_fail;
+ return &controller->controller;
+
+plat_get_fail:
+ kfree(controller);
+kzalloc_fail:
+ return NULL;
+}
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
index 1b6b827b769f..1345a4ff041a 100644
--- a/drivers/usb/musb/musb_dma.h
+++ b/drivers/usb/musb/musb_dma.h
@@ -62,13 +62,13 @@ struct musb_hw_ep;
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
-#ifndef CONFIG_MUSB_PIO_ONLY
-#define is_dma_capable() (1)
-#else
+#ifdef CONFIG_MUSB_PIO_ONLY
#define is_dma_capable() (0)
+#else
+#define is_dma_capable() (1)
#endif
-#ifdef CONFIG_USB_TI_CPPI_DMA
+#if defined(CONFIG_USB_TI_CPPI_DMA) || defined(CONFIG_USB_TI_CPPI41_DMA)
#define is_cppi_enabled() 1
#else
#define is_cppi_enabled() 0
@@ -159,8 +159,6 @@ dma_channel_status(struct dma_channel *c)
* Controllers manage dma channels.
*/
struct dma_controller {
- int (*start)(struct dma_controller *);
- int (*stop)(struct dma_controller *);
struct dma_channel *(*channel_alloc)(struct dma_controller *,
struct musb_hw_ep *, u8 is_tx);
void (*channel_release)(struct dma_channel *);
@@ -177,9 +175,20 @@ struct dma_controller {
/* called after channel_program(), may indicate a fault */
extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit);
+#ifdef CONFIG_MUSB_PIO_ONLY
+static inline struct dma_controller *dma_controller_create(struct musb *m,
+ void __iomem *io)
+{
+ return NULL;
+}
+
+static inline void dma_controller_destroy(struct dma_controller *d) { }
+
+#else
extern struct dma_controller *dma_controller_create(struct musb *, void __iomem *);
extern void dma_controller_destroy(struct dma_controller *);
+#endif
#endif /* __MUSB_DMA_H__ */
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 5233804d66b1..4ffbaace7913 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -36,19 +36,18 @@
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/module.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
#include <linux/platform_data/usb-omap.h>
#include <linux/sizes.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include "musb_core.h"
-#ifdef CONFIG_OF
static const struct of_device_id musb_dsps_of_match[];
-#endif
/**
* avoid using musb_readx()/musb_writex() as glue layer should not be
@@ -75,7 +74,6 @@ struct dsps_musb_wrapper {
u16 revision;
u16 control;
u16 status;
- u16 eoi;
u16 epintr_set;
u16 epintr_clear;
u16 epintr_status;
@@ -108,10 +106,7 @@ struct dsps_musb_wrapper {
/* bit positions for mode */
unsigned iddig:5;
/* miscellaneous stuff */
- u32 musb_core_offset;
u8 poll_seconds;
- /* number of musb instances */
- u8 instances;
};
/**
@@ -119,53 +114,12 @@ struct dsps_musb_wrapper {
*/
struct dsps_glue {
struct device *dev;
- struct platform_device *musb[2]; /* child musb pdev */
+ struct platform_device *musb; /* child musb pdev */
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
- struct timer_list timer[2]; /* otg_workaround timer */
- unsigned long last_timer[2]; /* last timer data for each instance */
- u32 __iomem *usb_ctrl[2];
+ struct timer_list timer; /* otg_workaround timer */
+ unsigned long last_timer; /* last timer data for each instance */
};
-#define DSPS_AM33XX_CONTROL_MODULE_PHYS_0 0x44e10620
-#define DSPS_AM33XX_CONTROL_MODULE_PHYS_1 0x44e10628
-
-static const resource_size_t dsps_control_module_phys[] = {
- DSPS_AM33XX_CONTROL_MODULE_PHYS_0,
- DSPS_AM33XX_CONTROL_MODULE_PHYS_1,
-};
-
-#define USBPHY_CM_PWRDN (1 << 0)
-#define USBPHY_OTG_PWRDN (1 << 1)
-#define USBPHY_OTGVDET_EN (1 << 19)
-#define USBPHY_OTGSESSEND_EN (1 << 20)
-
-/**
- * musb_dsps_phy_control - phy on/off
- * @glue: struct dsps_glue *
- * @id: musb instance
- * @on: flag for phy to be switched on or off
- *
- * This is to enable the PHY using usb_ctrl register in system control
- * module space.
- *
- * XXX: This function will be removed once we have a seperate driver for
- * control module
- */
-static void musb_dsps_phy_control(struct dsps_glue *glue, u8 id, u8 on)
-{
- u32 usbphycfg;
-
- usbphycfg = readl(glue->usb_ctrl[id]);
-
- if (on) {
- usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN);
- usbphycfg |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN;
- } else {
- usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
- }
-
- writel(usbphycfg, glue->usb_ctrl[id]);
-}
/**
* dsps_musb_enable - enable interrupts
*/
@@ -205,7 +159,6 @@ static void dsps_musb_disable(struct musb *musb)
dsps_writel(reg_base, wrp->epintr_clear,
wrp->txep_bitmap | wrp->rxep_bitmap);
dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
- dsps_writel(reg_base, wrp->eoi, 0);
}
static void otg_timer(unsigned long _musb)
@@ -213,7 +166,6 @@ static void otg_timer(unsigned long _musb)
struct musb *musb = (void *)_musb;
void __iomem *mregs = musb->mregs;
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev);
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
const struct dsps_musb_wrapper *wrp = glue->wrp;
u8 devctl;
@@ -250,7 +202,7 @@ static void otg_timer(unsigned long _musb)
case OTG_STATE_B_IDLE:
devctl = dsps_readb(mregs, MUSB_DEVCTL);
if (devctl & MUSB_DEVCTL_BDEVICE)
- mod_timer(&glue->timer[pdev->id],
+ mod_timer(&glue->timer,
jiffies + wrp->poll_seconds * HZ);
else
musb->xceiv->state = OTG_STATE_A_IDLE;
@@ -264,7 +216,6 @@ static void otg_timer(unsigned long _musb)
static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
{
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev);
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
if (timeout == 0)
@@ -275,23 +226,23 @@ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
dev_dbg(musb->controller, "%s active, deleting timer\n",
usb_otg_state_string(musb->xceiv->state));
- del_timer(&glue->timer[pdev->id]);
- glue->last_timer[pdev->id] = jiffies;
+ del_timer(&glue->timer);
+ glue->last_timer = jiffies;
return;
}
- if (time_after(glue->last_timer[pdev->id], timeout) &&
- timer_pending(&glue->timer[pdev->id])) {
+ if (time_after(glue->last_timer, timeout) &&
+ timer_pending(&glue->timer)) {
dev_dbg(musb->controller,
"Longer idle timer already pending, ignoring...\n");
return;
}
- glue->last_timer[pdev->id] = timeout;
+ glue->last_timer = timeout;
dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
usb_otg_state_string(musb->xceiv->state),
jiffies_to_msecs(timeout - jiffies));
- mod_timer(&glue->timer[pdev->id], timeout);
+ mod_timer(&glue->timer, timeout);
}
static irqreturn_t dsps_interrupt(int irq, void *hci)
@@ -299,7 +250,6 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
struct musb *musb = hci;
void __iomem *reg_base = musb->ctrl_base;
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev);
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
const struct dsps_musb_wrapper *wrp = glue->wrp;
unsigned long flags;
@@ -319,7 +269,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
/* Get usb core interrupts */
usbintr = dsps_readl(reg_base, wrp->coreintr_status);
if (!usbintr && !epintr)
- goto eoi;
+ goto out;
musb->int_usb = (usbintr & wrp->usb_bitmap) >> wrp->usb_shift;
if (usbintr)
@@ -359,7 +309,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
*/
musb->int_usb &= ~MUSB_INTR_VBUSERROR;
musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
- mod_timer(&glue->timer[pdev->id],
+ mod_timer(&glue->timer,
jiffies + wrp->poll_seconds * HZ);
WARNING("VBUS error workaround (delay coming)\n");
} else if (drvvbus) {
@@ -367,7 +317,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
MUSB_HST_MODE(musb);
musb->xceiv->otg->default_a = 1;
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
- del_timer(&glue->timer[pdev->id]);
+ del_timer(&glue->timer);
} else {
musb->is_active = 0;
MUSB_DEV_MODE(musb);
@@ -387,16 +337,10 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
if (musb->int_tx || musb->int_rx || musb->int_usb)
ret |= musb_interrupt(musb);
- eoi:
- /* EOI needs to be written for the IRQ to be re-asserted. */
- if (ret == IRQ_HANDLED || epintr || usbintr)
- dsps_writel(reg_base, wrp->eoi, 1);
-
/* Poll for ID change */
if (musb->xceiv->state == OTG_STATE_B_IDLE)
- mod_timer(&glue->timer[pdev->id],
- jiffies + wrp->poll_seconds * HZ);
-
+ mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
+out:
spin_unlock_irqrestore(&musb->lock, flags);
return ret;
@@ -405,37 +349,38 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
static int dsps_musb_init(struct musb *musb)
{
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev);
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
+ struct platform_device *parent = to_platform_device(dev->parent);
const struct dsps_musb_wrapper *wrp = glue->wrp;
- void __iomem *reg_base = musb->ctrl_base;
+ void __iomem *reg_base;
+ struct resource *r;
u32 rev, val;
- int status;
- /* mentor core register starts at offset of 0x400 from musb base */
- musb->mregs += wrp->musb_core_offset;
+ r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control");
+ if (!r)
+ return -EINVAL;
+
+ reg_base = devm_ioremap_resource(dev, r);
+ if (!musb->ctrl_base)
+ return -EINVAL;
+ musb->ctrl_base = reg_base;
/* NOP driver needs change if supporting dual instance */
- usb_nop_xceiv_register();
- musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
- if (IS_ERR_OR_NULL(musb->xceiv))
- return -EPROBE_DEFER;
+ musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0);
+ if (IS_ERR(musb->xceiv))
+ return PTR_ERR(musb->xceiv);
/* Returns zero if e.g. not clocked */
rev = dsps_readl(reg_base, wrp->revision);
- if (!rev) {
- status = -ENODEV;
- goto err0;
- }
+ if (!rev)
+ return -ENODEV;
- setup_timer(&glue->timer[pdev->id], otg_timer, (unsigned long) musb);
+ usb_phy_init(musb->xceiv);
+ setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
/* Reset the musb */
dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
- /* Start the on-chip PHY and its PLL. */
- musb_dsps_phy_control(glue, pdev->id, 1);
-
musb->isr = dsps_interrupt;
/* reset the otgdisable bit, needed for host mode to work */
@@ -443,31 +388,17 @@ static int dsps_musb_init(struct musb *musb)
val &= ~(1 << wrp->otg_disable);
dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
- /* clear level interrupt */
- dsps_writel(reg_base, wrp->eoi, 0);
-
return 0;
-err0:
- usb_put_phy(musb->xceiv);
- usb_nop_xceiv_unregister();
- return status;
}
static int dsps_musb_exit(struct musb *musb)
{
struct device *dev = musb->controller;
- struct platform_device *pdev = to_platform_device(dev);
struct dsps_glue *glue = dev_get_drvdata(dev->parent);
- del_timer_sync(&glue->timer[pdev->id]);
-
- /* Shutdown the on-chip PHY and its PLL. */
- musb_dsps_phy_control(glue, pdev->id, 0);
-
- /* NOP driver needs change if supporting dual instance */
- usb_put_phy(musb->xceiv);
- usb_nop_xceiv_unregister();
+ del_timer_sync(&glue->timer);
+ usb_phy_shutdown(musb->xceiv);
return 0;
}
@@ -483,116 +414,98 @@ static struct musb_platform_ops dsps_ops = {
static u64 musb_dmamask = DMA_BIT_MASK(32);
-static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
+static int get_int_prop(struct device_node *dn, const char *s)
{
- struct device *dev = glue->dev;
- struct platform_device *pdev = to_platform_device(dev);
- struct musb_hdrc_platform_data *pdata = dev->platform_data;
- struct device_node *np = pdev->dev.of_node;
- struct musb_hdrc_config *config;
- struct platform_device *musb;
- struct resource *res;
+ int ret;
+ u32 val;
+
+ ret = of_property_read_u32(dn, s, &val);
+ if (ret)
+ return 0;
+ return val;
+}
+
+static int dsps_create_musb_pdev(struct dsps_glue *glue,
+ struct platform_device *parent)
+{
+ struct musb_hdrc_platform_data pdata;
struct resource resources[2];
- char res_name[11];
+ struct device *dev = &parent->dev;
+ struct musb_hdrc_config *config;
+ struct platform_device *musb;
+ struct device_node *dn = parent->dev.of_node;
+ struct device_node *child_node;
int ret;
- resources[0].start = dsps_control_module_phys[id];
- resources[0].end = resources[0].start + SZ_4 - 1;
- resources[0].flags = IORESOURCE_MEM;
+ child_node = of_get_child_by_name(dn, "usb");
+ if (!child_node)
+ return -EINVAL;
- glue->usb_ctrl[id] = devm_ioremap_resource(&pdev->dev, resources);
- if (IS_ERR(glue->usb_ctrl[id])) {
- ret = PTR_ERR(glue->usb_ctrl[id]);
- goto err0;
+ memset(resources, 0, sizeof(resources));
+ ret = of_address_to_resource(child_node, 0, &resources[0]);
+ if (ret) {
+ dev_err(dev, "failed to get memory.\n");
+ return ret;
}
- /* first resource is for usbss, so start index from 1 */
- res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1);
- if (!res) {
- dev_err(dev, "failed to get memory for instance %d\n", id);
- ret = -ENODEV;
- goto err0;
- }
- res->parent = NULL;
- resources[0] = *res;
-
- /* first resource is for usbss, so start index from 1 */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, id + 1);
- if (!res) {
- dev_err(dev, "failed to get irq for instance %d\n", id);
- ret = -ENODEV;
- goto err0;
+ ret = of_irq_to_resource(child_node, 0, &resources[1]);
+ if (ret == 0) {
+ dev_err(dev, "failed to get irq.\n");
+ ret = -EINVAL;
+ return ret;
}
- res->parent = NULL;
- resources[1] = *res;
- resources[1].name = "mc";
/* allocate the child platform device */
musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
if (!musb) {
dev_err(dev, "failed to allocate musb device\n");
- ret = -ENOMEM;
- goto err0;
+ return -ENOMEM;
}
musb->dev.parent = dev;
musb->dev.dma_mask = &musb_dmamask;
musb->dev.coherent_dma_mask = musb_dmamask;
+ musb->dev.of_node = of_node_get(child_node);
- glue->musb[id] = musb;
+ glue->musb = musb;
- ret = platform_device_add_resources(musb, resources, 2);
+ ret = platform_device_add_resources(musb, resources,
+ ARRAY_SIZE(resources));
if (ret) {
dev_err(dev, "failed to add resources\n");
- goto err2;
+ goto err;
}
- if (np) {
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata) {
- dev_err(&pdev->dev,
- "failed to allocate musb platform data\n");
- ret = -ENOMEM;
- goto err2;
- }
-
- config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
- if (!config) {
- dev_err(&pdev->dev,
- "failed to allocate musb hdrc config\n");
- ret = -ENOMEM;
- goto err2;
- }
-
- of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
- of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
- snprintf(res_name, sizeof(res_name), "port%d-mode", id);
- of_property_read_u32(np, res_name, (u32 *)&pdata->mode);
- of_property_read_u32(np, "power", (u32 *)&pdata->power);
- config->multipoint = of_property_read_bool(np, "multipoint");
-
- pdata->config = config;
+ config = devm_kzalloc(&parent->dev, sizeof(*config), GFP_KERNEL);
+ if (!config) {
+ dev_err(dev, "failed to allocate musb hdrc config\n");
+ ret = -ENOMEM;
+ goto err;
}
+ pdata.config = config;
+ pdata.platform_ops = &dsps_ops;
- pdata->platform_ops = &dsps_ops;
+ config->num_eps = get_int_prop(child_node, "num-eps");
+ config->ram_bits = get_int_prop(child_node, "ram-bits");
+ pdata.mode = get_int_prop(child_node, "port-mode");
+ pdata.power = get_int_prop(child_node, "power");
+ config->multipoint = of_property_read_bool(child_node, "multipoint");
- ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+ ret = platform_device_add_data(musb, &pdata, sizeof(pdata));
if (ret) {
dev_err(dev, "failed to add platform_data\n");
- goto err2;
+ goto err;
}
ret = platform_device_add(musb);
if (ret) {
dev_err(dev, "failed to register musb device\n");
- goto err2;
+ goto err;
}
-
return 0;
-err2:
+err:
platform_device_put(musb);
-err0:
return ret;
}
@@ -601,14 +514,12 @@ static int dsps_probe(struct platform_device *pdev)
const struct of_device_id *match;
const struct dsps_musb_wrapper *wrp;
struct dsps_glue *glue;
- struct resource *iomem;
- int ret, i;
+ int ret;
match = of_match_node(musb_dsps_of_match, pdev->dev.of_node);
if (!match) {
dev_err(&pdev->dev, "fail to get matching of_match struct\n");
- ret = -EINVAL;
- goto err0;
+ return -EINVAL;
}
wrp = match->data;
@@ -616,29 +527,13 @@ static int dsps_probe(struct platform_device *pdev)
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
if (!glue) {
dev_err(&pdev->dev, "unable to allocate glue memory\n");
- ret = -ENOMEM;
- goto err0;
- }
-
- /* get memory resource */
- iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iomem) {
- dev_err(&pdev->dev, "failed to get usbss mem resourse\n");
- ret = -ENODEV;
- goto err1;
+ return -ENOMEM;
}
glue->dev = &pdev->dev;
+ glue->wrp = wrp;
- glue->wrp = kmemdup(wrp, sizeof(*wrp), GFP_KERNEL);
- if (!glue->wrp) {
- dev_err(&pdev->dev, "failed to duplicate wrapper struct memory\n");
- ret = -ENOMEM;
- goto err1;
- }
platform_set_drvdata(pdev, glue);
-
- /* enable the usbss clocks */
pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
@@ -647,17 +542,9 @@ static int dsps_probe(struct platform_device *pdev)
goto err2;
}
- /* create the child platform device for all instances of musb */
- for (i = 0; i < wrp->instances ; i++) {
- ret = dsps_create_musb_pdev(glue, i);
- if (ret != 0) {
- dev_err(&pdev->dev, "failed to create child pdev\n");
- /* release resources of previously created instances */
- for (i--; i >= 0 ; i--)
- platform_device_unregister(glue->musb[i]);
- goto err3;
- }
- }
+ ret = dsps_create_musb_pdev(glue, pdev);
+ if (ret)
+ goto err3;
return 0;
@@ -665,65 +552,27 @@ err3:
pm_runtime_put(&pdev->dev);
err2:
pm_runtime_disable(&pdev->dev);
- kfree(glue->wrp);
-err1:
kfree(glue);
-err0:
return ret;
}
+
static int dsps_remove(struct platform_device *pdev)
{
struct dsps_glue *glue = platform_get_drvdata(pdev);
- const struct dsps_musb_wrapper *wrp = glue->wrp;
- int i;
- /* delete the child platform device */
- for (i = 0; i < wrp->instances ; i++)
- platform_device_unregister(glue->musb[i]);
+ platform_device_unregister(glue->musb);
/* disable usbss clocks */
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- kfree(glue->wrp);
kfree(glue);
return 0;
}
-#ifdef CONFIG_PM_SLEEP
-static int dsps_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev->parent);
- struct dsps_glue *glue = platform_get_drvdata(pdev);
- const struct dsps_musb_wrapper *wrp = glue->wrp;
- int i;
-
- for (i = 0; i < wrp->instances; i++)
- musb_dsps_phy_control(glue, i, 0);
-
- return 0;
-}
-
-static int dsps_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev->parent);
- struct dsps_glue *glue = platform_get_drvdata(pdev);
- const struct dsps_musb_wrapper *wrp = glue->wrp;
- int i;
-
- for (i = 0; i < wrp->instances; i++)
- musb_dsps_phy_control(glue, i, 1);
-
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume);
-
-static const struct dsps_musb_wrapper ti81xx_driver_data = {
+static const struct dsps_musb_wrapper am33xx_driver_data = {
.revision = 0x00,
.control = 0x14,
.status = 0x18,
- .eoi = 0x24,
.epintr_set = 0x38,
.epintr_clear = 0x40,
.epintr_status = 0x30,
@@ -745,38 +594,23 @@ static const struct dsps_musb_wrapper ti81xx_driver_data = {
.rxep_shift = 16,
.rxep_mask = 0xfffe,
.rxep_bitmap = (0xfffe << 16),
- .musb_core_offset = 0x400,
.poll_seconds = 2,
- .instances = 1,
-};
-
-static const struct platform_device_id musb_dsps_id_table[] = {
- {
- .name = "musb-ti81xx",
- .driver_data = (kernel_ulong_t) &ti81xx_driver_data,
- },
- { }, /* Terminating Entry */
};
-MODULE_DEVICE_TABLE(platform, musb_dsps_id_table);
-#ifdef CONFIG_OF
static const struct of_device_id musb_dsps_of_match[] = {
{ .compatible = "ti,musb-am33xx",
- .data = (void *) &ti81xx_driver_data, },
+ .data = (void *) &am33xx_driver_data, },
{ },
};
MODULE_DEVICE_TABLE(of, musb_dsps_of_match);
-#endif
static struct platform_driver dsps_usbss_driver = {
.probe = dsps_probe,
.remove = dsps_remove,
.driver = {
.name = "musb-dsps",
- .pm = &dsps_pm_ops,
.of_match_table = of_match_ptr(musb_dsps_of_match),
},
- .id_table = musb_dsps_id_table,
};
MODULE_DESCRIPTION("TI DSPS MUSB Glue Layer");
@@ -784,14 +618,4 @@ MODULE_AUTHOR("Ravi B <ravibabu@ti.com>");
MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
MODULE_LICENSE("GPL v2");
-static int __init dsps_init(void)
-{
- return platform_driver_register(&dsps_usbss_driver);
-}
-subsys_initcall(dsps_init);
-
-static void __exit dsps_exit(void)
-{
- platform_driver_unregister(&dsps_usbss_driver);
-}
-module_exit(dsps_exit);
+module_platform_driver(dsps_usbss_driver);
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 0414bc19d009..4376f51f5ef1 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -357,47 +357,49 @@ static void txstate(struct musb *musb, struct musb_request *req)
}
}
-#elif defined(CONFIG_USB_TI_CPPI_DMA)
- /* program endpoint CSR first, then setup DMA */
- csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
- csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE |
- MUSB_TXCSR_MODE;
- musb_writew(epio, MUSB_TXCSR,
- (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
- | csr);
-
- /* ensure writebuffer is empty */
- csr = musb_readw(epio, MUSB_TXCSR);
-
- /* NOTE host side sets DMAENAB later than this; both are
- * OK since the transfer dma glue (between CPPI and Mentor
- * fifos) just tells CPPI it could start. Data only moves
- * to the USB TX fifo when both fifos are ready.
- */
-
- /* "mode" is irrelevant here; handle terminating ZLPs like
- * PIO does, since the hardware RNDIS mode seems unreliable
- * except for the last-packet-is-already-short case.
- */
- use_dma = use_dma && c->channel_program(
- musb_ep->dma, musb_ep->packet_sz,
- 0,
- request->dma + request->actual,
- request_size);
- if (!use_dma) {
- c->channel_release(musb_ep->dma);
- musb_ep->dma = NULL;
- csr &= ~MUSB_TXCSR_DMAENAB;
- musb_writew(epio, MUSB_TXCSR, csr);
- /* invariant: prequest->buf is non-null */
- }
-#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
- use_dma = use_dma && c->channel_program(
- musb_ep->dma, musb_ep->packet_sz,
- request->zero,
- request->dma + request->actual,
- request_size);
#endif
+ if (is_cppi_enabled()) {
+ /* program endpoint CSR first, then setup DMA */
+ csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY);
+ csr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_DMAMODE |
+ MUSB_TXCSR_MODE;
+ musb_writew(epio, MUSB_TXCSR, (MUSB_TXCSR_P_WZC_BITS &
+ ~MUSB_TXCSR_P_UNDERRUN) | csr);
+
+ /* ensure writebuffer is empty */
+ csr = musb_readw(epio, MUSB_TXCSR);
+
+ /*
+ * NOTE host side sets DMAENAB later than this; both are
+ * OK since the transfer dma glue (between CPPI and
+ * Mentor fifos) just tells CPPI it could start. Data
+ * only moves to the USB TX fifo when both fifos are
+ * ready.
+ */
+ /*
+ * "mode" is irrelevant here; handle terminating ZLPs
+ * like PIO does, since the hardware RNDIS mode seems
+ * unreliable except for the
+ * last-packet-is-already-short case.
+ */
+ use_dma = use_dma && c->channel_program(
+ musb_ep->dma, musb_ep->packet_sz,
+ 0,
+ request->dma + request->actual,
+ request_size);
+ if (!use_dma) {
+ c->channel_release(musb_ep->dma);
+ musb_ep->dma = NULL;
+ csr &= ~MUSB_TXCSR_DMAENAB;
+ musb_writew(epio, MUSB_TXCSR, csr);
+ /* invariant: prequest->buf is non-null */
+ }
+ } else if (tusb_dma_omap())
+ use_dma = use_dma && c->channel_program(
+ musb_ep->dma, musb_ep->packet_sz,
+ request->zero,
+ request->dma + request->actual,
+ request_size);
}
#endif
@@ -1266,7 +1268,8 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
dev_dbg(musb->controller, "req %p queued to %s while ep %s\n",
req, ep->name, "disabled");
status = -ESHUTDOWN;
- goto cleanup;
+ unmap_dma_buffer(request, musb);
+ goto unlock;
}
/* add request to the list */
@@ -1276,7 +1279,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
if (!musb_ep->busy && &request->list == musb_ep->req_list.next)
musb_ep_restart(musb, request);
-cleanup:
+unlock:
spin_unlock_irqrestore(&musb->lock, lockflags);
return status;
}
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 3d1fd52a15a9..e8e9f9aab203 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -37,18 +37,10 @@
#include "musb_core.h"
#include "musbhsdma.h"
-static int dma_controller_start(struct dma_controller *c)
-{
- /* nothing to do */
- return 0;
-}
-
static void dma_channel_release(struct dma_channel *channel);
-static int dma_controller_stop(struct dma_controller *c)
+static void dma_controller_stop(struct musb_dma_controller *controller)
{
- struct musb_dma_controller *controller = container_of(c,
- struct musb_dma_controller, controller);
struct musb *musb = controller->private_data;
struct dma_channel *channel;
u8 bit;
@@ -67,8 +59,6 @@ static int dma_controller_stop(struct dma_controller *c)
}
}
}
-
- return 0;
}
static struct dma_channel *dma_channel_allocate(struct dma_controller *c,
@@ -371,8 +361,7 @@ void dma_controller_destroy(struct dma_controller *c)
struct musb_dma_controller *controller = container_of(c,
struct musb_dma_controller, controller);
- if (!controller)
- return;
+ dma_controller_stop(controller);
if (controller->irq)
free_irq(controller->irq, c);
@@ -400,8 +389,6 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba
controller->private_data = musb;
controller->base = base;
- controller->controller.start = dma_controller_start;
- controller->controller.stop = dma_controller_stop;
controller->controller.channel_alloc = dma_channel_allocate;
controller->controller.channel_release = dma_channel_release;
controller->controller.channel_program = dma_channel_program;
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index f44e8b5e00c9..59d2245db1c8 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -255,7 +255,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
{
struct musb *musb = glue_to_musb(glue);
struct device *dev = musb->controller;
- struct musb_hdrc_platform_data *pdata = dev->platform_data;
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev);
struct omap_musb_board_data *data = pdata->board_data;
struct usb_otg *otg = musb->xceiv->otg;
@@ -341,7 +341,7 @@ static int omap2430_musb_init(struct musb *musb)
int status = 0;
struct device *dev = musb->controller;
struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
- struct musb_hdrc_platform_data *plat = dev->platform_data;
+ struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
struct omap_musb_board_data *data = plat->board_data;
/* We require some kind of external transceiver, hooked
@@ -412,7 +412,7 @@ static void omap2430_musb_enable(struct musb *musb)
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
struct device *dev = musb->controller;
struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
- struct musb_hdrc_platform_data *pdata = dev->platform_data;
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev);
struct omap_musb_board_data *data = pdata->board_data;
switch (glue->status) {
@@ -482,7 +482,7 @@ static u64 omap2430_dmamask = DMA_BIT_MASK(32);
static int omap2430_probe(struct platform_device *pdev)
{
struct resource musb_resources[3];
- struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct omap_musb_board_data *data;
struct platform_device *musb;
struct omap2430_glue *glue;
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 6f8a9ca96ae7..b3b3ed723882 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -25,7 +25,7 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/usb/nop-usb-xceiv.h>
+#include <linux/usb/usb_phy_gen_xceiv.h>
#include "musb_core.h"
@@ -1157,7 +1157,7 @@ static u64 tusb_dmamask = DMA_BIT_MASK(32);
static int tusb_probe(struct platform_device *pdev)
{
struct resource musb_resources[3];
- struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct tusb6010_glue *glue;
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 98df17c984a8..b8794eb81e9c 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -66,28 +66,6 @@ struct tusb_omap_dma {
unsigned multichannel:1;
};
-static int tusb_omap_dma_start(struct dma_controller *c)
-{
- struct tusb_omap_dma *tusb_dma;
-
- tusb_dma = container_of(c, struct tusb_omap_dma, controller);
-
- /* dev_dbg(musb->controller, "ep%i ch: %i\n", chdat->epnum, chdat->ch); */
-
- return 0;
-}
-
-static int tusb_omap_dma_stop(struct dma_controller *c)
-{
- struct tusb_omap_dma *tusb_dma;
-
- tusb_dma = container_of(c, struct tusb_omap_dma, controller);
-
- /* dev_dbg(musb->controller, "ep%i ch: %i\n", chdat->epnum, chdat->ch); */
-
- return 0;
-}
-
/*
* Allocate dmareq0 to the current channel unless it's already taken
*/
@@ -695,8 +673,6 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *ba
tusb_dma->dmareq = -1;
tusb_dma->sync_dev = -1;
- tusb_dma->controller.start = tusb_omap_dma_start;
- tusb_dma->controller.stop = tusb_omap_dma_stop;
tusb_dma->controller.channel_alloc = tusb_omap_dma_allocate;
tusb_dma->controller.channel_release = tusb_omap_dma_release;
tusb_dma->controller.channel_program = tusb_omap_dma_program;
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c
index fce71b605936..59256b12f746 100644
--- a/drivers/usb/musb/ux500.c
+++ b/drivers/usb/musb/ux500.c
@@ -227,7 +227,7 @@ ux500_of_probe(struct platform_device *pdev, struct device_node *np)
static int ux500_probe(struct platform_device *pdev)
{
struct resource musb_resources[2];
- struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device_node *np = pdev->dev.of_node;
struct platform_device *musb;
struct ux500_glue *glue;
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c
index bfb7a65d83cc..e51dd9b88e71 100644
--- a/drivers/usb/musb/ux500_dma.c
+++ b/drivers/usb/musb/ux500_dma.c
@@ -254,10 +254,8 @@ static int ux500_dma_channel_abort(struct dma_channel *channel)
return 0;
}
-static int ux500_dma_controller_stop(struct dma_controller *c)
+static void ux500_dma_controller_stop(struct ux500_dma_controller *controller)
{
- struct ux500_dma_controller *controller = container_of(c,
- struct ux500_dma_controller, controller);
struct ux500_dma_channel *ux500_channel;
struct dma_channel *channel;
u8 ch_num;
@@ -281,18 +279,14 @@ static int ux500_dma_controller_stop(struct dma_controller *c)
if (ux500_channel->dma_chan)
dma_release_channel(ux500_channel->dma_chan);
}
-
- return 0;
}
-static int ux500_dma_controller_start(struct dma_controller *c)
+static int ux500_dma_controller_start(struct ux500_dma_controller *controller)
{
- struct ux500_dma_controller *controller = container_of(c,
- struct ux500_dma_controller, controller);
struct ux500_dma_channel *ux500_channel = NULL;
struct musb *musb = controller->private_data;
struct device *dev = musb->controller;
- struct musb_hdrc_platform_data *plat = dev->platform_data;
+ struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
struct ux500_musb_board_data *data;
struct dma_channel *dma_channel = NULL;
char **chan_names;
@@ -347,7 +341,7 @@ static int ux500_dma_controller_start(struct dma_controller *c)
dir, ch_num);
/* Release already allocated channels */
- ux500_dma_controller_stop(c);
+ ux500_dma_controller_stop(controller);
return -EBUSY;
}
@@ -369,6 +363,7 @@ void dma_controller_destroy(struct dma_controller *c)
struct ux500_dma_controller *controller = container_of(c,
struct ux500_dma_controller, controller);
+ ux500_dma_controller_stop(controller);
kfree(controller);
}
@@ -378,6 +373,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,
struct ux500_dma_controller *controller;
struct platform_device *pdev = to_platform_device(musb->controller);
struct resource *iomem;
+ int ret;
controller = kzalloc(sizeof(*controller), GFP_KERNEL);
if (!controller)
@@ -394,14 +390,15 @@ struct dma_controller *dma_controller_create(struct musb *musb,
controller->phy_base = (dma_addr_t) iomem->start;
- controller->controller.start = ux500_dma_controller_start;
- controller->controller.stop = ux500_dma_controller_stop;
controller->controller.channel_alloc = ux500_dma_channel_allocate;
controller->controller.channel_release = ux500_dma_channel_release;
controller->controller.channel_program = ux500_dma_channel_program;
controller->controller.channel_abort = ux500_dma_channel_abort;
controller->controller.is_compatible = ux500_dma_is_compatible;
+ ret = ux500_dma_controller_start(controller);
+ if (ret)
+ goto plat_get_fail;
return &controller->controller;
plat_get_fail:
OpenPOWER on IntegriCloud