summaryrefslogtreecommitdiff
path: root/drivers/usb/musb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/Kconfig5
-rw-r--r--drivers/usb/musb/am35x.c63
-rw-r--r--drivers/usb/musb/blackfin.c13
-rw-r--r--drivers/usb/musb/da8xx.c49
-rw-r--r--drivers/usb/musb/davinci.c59
-rw-r--r--drivers/usb/musb/musb_am335x.c2
-rw-r--r--drivers/usb/musb/musb_core.c26
-rw-r--r--drivers/usb/musb/musb_core.h2
-rw-r--r--drivers/usb/musb/musb_cppi41.c172
-rw-r--r--drivers/usb/musb/musb_dsps.c96
-rw-r--r--drivers/usb/musb/musb_gadget.c6
-rw-r--r--drivers/usb/musb/musb_host.c2
-rw-r--r--drivers/usb/musb/musb_virthub.c19
-rw-r--r--drivers/usb/musb/omap2430.c54
-rw-r--r--drivers/usb/musb/tusb6010.c49
-rw-r--r--drivers/usb/musb/ux500.c15
16 files changed, 263 insertions, 369 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 57dfc0c..c258a97 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -75,7 +75,6 @@ config USB_MUSB_TUSB6010
config USB_MUSB_OMAP2PLUS
tristate "OMAP2430 and onwards"
depends on ARCH_OMAP2PLUS
- select GENERIC_PHY
config USB_MUSB_AM35X
tristate "AM35x"
@@ -91,7 +90,7 @@ config USB_MUSB_BLACKFIN
depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523)
config USB_MUSB_UX500
- tristate "Ux500 platforms"
+ tristate "U8500 and U5500"
endchoice
@@ -113,7 +112,7 @@ choice
allow using DMA on multiplatform kernels.
config USB_UX500_DMA
- bool 'ST Ericsson Ux500'
+ bool 'ST Ericsson U8500 and U5500'
depends on USB_MUSB_UX500
help
Enable DMA transfers on UX500 platforms.
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index ca45b39..5c310c6 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -89,6 +89,7 @@ struct am35x_glue {
struct clk *phy_clk;
struct clk *clk;
};
+#define glue_to_musb(g) platform_get_drvdata(g->musb)
/*
* am35x_musb_enable - enable interrupts
@@ -451,18 +452,14 @@ static const struct musb_platform_ops am35x_ops = {
.set_vbus = am35x_musb_set_vbus,
};
-static const struct platform_device_info am35x_dev_info = {
- .name = "musb-hdrc",
- .id = PLATFORM_DEVID_AUTO,
- .dma_mask = DMA_BIT_MASK(32),
-};
+static u64 am35x_dmamask = DMA_BIT_MASK(32);
static int am35x_probe(struct platform_device *pdev)
{
struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct am35x_glue *glue;
- struct platform_device_info pinfo;
+
struct clk *phy_clk;
struct clk *clk;
@@ -474,6 +471,12 @@ static int am35x_probe(struct platform_device *pdev)
goto err0;
}
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
+ if (!musb) {
+ dev_err(&pdev->dev, "failed to allocate musb device\n");
+ goto err1;
+ }
+
phy_clk = clk_get(&pdev->dev, "fck");
if (IS_ERR(phy_clk)) {
dev_err(&pdev->dev, "failed to get PHY clock\n");
@@ -500,7 +503,12 @@ static int am35x_probe(struct platform_device *pdev)
goto err6;
}
+ musb->dev.parent = &pdev->dev;
+ musb->dev.dma_mask = &am35x_dmamask;
+ musb->dev.coherent_dma_mask = am35x_dmamask;
+
glue->dev = &pdev->dev;
+ glue->musb = musb;
glue->phy_clk = phy_clk;
glue->clk = clk;
@@ -508,17 +516,22 @@ static int am35x_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, glue);
- pinfo = am35x_dev_info;
- pinfo.parent = &pdev->dev;
- pinfo.res = pdev->resource;
- pinfo.num_res = pdev->num_resources;
- pinfo.data = pdata;
- pinfo.size_data = sizeof(*pdata);
-
- glue->musb = musb = platform_device_register_full(&pinfo);
- if (IS_ERR(musb)) {
- ret = PTR_ERR(musb);
- dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
+ ret = platform_device_add_resources(musb, pdev->resource,
+ pdev->num_resources);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add resources\n");
+ goto err7;
+ }
+
+ ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add platform_data\n");
+ goto err7;
+ }
+
+ ret = platform_device_add(musb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register musb device\n");
goto err7;
}
@@ -537,6 +550,9 @@ err4:
clk_put(phy_clk);
err3:
+ platform_device_put(musb);
+
+err1:
kfree(glue);
err0:
@@ -599,16 +615,23 @@ static int am35x_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(am35x_pm_ops, am35x_suspend, am35x_resume);
+static struct dev_pm_ops am35x_pm_ops = {
+ .suspend = am35x_suspend,
+ .resume = am35x_resume,
+};
+
+#define DEV_PM_OPS &am35x_pm_ops
+#else
+#define DEV_PM_OPS NULL
+#endif
static struct platform_driver am35x_driver = {
.probe = am35x_probe,
.remove = am35x_remove,
.driver = {
.name = "musb-am35x",
- .pm = &am35x_pm_ops,
+ .pm = DEV_PM_OPS,
},
};
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index d9692f7..72e2056 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -561,16 +561,23 @@ static int bfin_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(bfin_pm_ops, bfin_suspend, bfin_resume);
+static struct dev_pm_ops bfin_pm_ops = {
+ .suspend = bfin_suspend,
+ .resume = bfin_resume,
+};
+
+#define DEV_PM_OPS &bfin_pm_ops
+#else
+#define DEV_PM_OPS NULL
+#endif
static struct platform_driver bfin_driver = {
.probe = bfin_probe,
.remove = __exit_p(bfin_remove),
.driver = {
.name = "musb-blackfin",
- .pm = &bfin_pm_ops,
+ .pm = DEV_PM_OPS,
},
};
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
index 2f2c1cb..d9ddf41 100644
--- a/drivers/usb/musb/da8xx.c
+++ b/drivers/usb/musb/da8xx.c
@@ -472,11 +472,7 @@ static const struct musb_platform_ops da8xx_ops = {
.set_vbus = da8xx_musb_set_vbus,
};
-static const struct platform_device_info da8xx_dev_info = {
- .name = "musb-hdrc",
- .id = PLATFORM_DEVID_AUTO,
- .dma_mask = DMA_BIT_MASK(32),
-};
+static u64 da8xx_dmamask = DMA_BIT_MASK(32);
static int da8xx_probe(struct platform_device *pdev)
{
@@ -484,7 +480,7 @@ static int da8xx_probe(struct platform_device *pdev)
struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct da8xx_glue *glue;
- struct platform_device_info pinfo;
+
struct clk *clk;
int ret = -ENOMEM;
@@ -495,6 +491,12 @@ static int da8xx_probe(struct platform_device *pdev)
goto err0;
}
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
+ if (!musb) {
+ dev_err(&pdev->dev, "failed to allocate musb device\n");
+ goto err1;
+ }
+
clk = clk_get(&pdev->dev, "usb20");
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -508,7 +510,12 @@ static int da8xx_probe(struct platform_device *pdev)
goto err4;
}
+ musb->dev.parent = &pdev->dev;
+ musb->dev.dma_mask = &da8xx_dmamask;
+ musb->dev.coherent_dma_mask = da8xx_dmamask;
+
glue->dev = &pdev->dev;
+ glue->musb = musb;
glue->clk = clk;
pdata->platform_ops = &da8xx_ops;
@@ -528,17 +535,22 @@ static int da8xx_probe(struct platform_device *pdev)
musb_resources[1].end = pdev->resource[1].end;
musb_resources[1].flags = pdev->resource[1].flags;
- pinfo = da8xx_dev_info;
- pinfo.parent = &pdev->dev;
- pinfo.res = musb_resources;
- pinfo.num_res = ARRAY_SIZE(musb_resources);
- pinfo.data = pdata;
- pinfo.size_data = sizeof(*pdata);
-
- glue->musb = musb = platform_device_register_full(&pinfo);
- if (IS_ERR(musb)) {
- ret = PTR_ERR(musb);
- dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
+ ret = platform_device_add_resources(musb, musb_resources,
+ ARRAY_SIZE(musb_resources));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add resources\n");
+ goto err5;
+ }
+
+ ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add platform_data\n");
+ goto err5;
+ }
+
+ ret = platform_device_add(musb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register musb device\n");
goto err5;
}
@@ -551,6 +563,9 @@ err4:
clk_put(clk);
err3:
+ platform_device_put(musb);
+
+err1:
kfree(glue);
err0:
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 1121fd7..ed0834e 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -505,19 +505,14 @@ static const struct musb_platform_ops davinci_ops = {
.set_vbus = davinci_musb_set_vbus,
};
-static const struct platform_device_info davinci_dev_info = {
- .name = "musb-hdrc",
- .id = PLATFORM_DEVID_AUTO,
- .dma_mask = DMA_BIT_MASK(32),
-};
+static u64 davinci_dmamask = DMA_BIT_MASK(32);
static int davinci_probe(struct platform_device *pdev)
{
- struct resource musb_resources[3];
+ struct resource musb_resources[2];
struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct davinci_glue *glue;
- struct platform_device_info pinfo;
struct clk *clk;
int ret = -ENOMEM;
@@ -528,6 +523,12 @@ static int davinci_probe(struct platform_device *pdev)
goto err0;
}
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
+ if (!musb) {
+ dev_err(&pdev->dev, "failed to allocate musb device\n");
+ goto err1;
+ }
+
clk = clk_get(&pdev->dev, "usb");
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -541,7 +542,12 @@ static int davinci_probe(struct platform_device *pdev)
goto err4;
}
+ musb->dev.parent = &pdev->dev;
+ musb->dev.dma_mask = &davinci_dmamask;
+ musb->dev.coherent_dma_mask = davinci_dmamask;
+
glue->dev = &pdev->dev;
+ glue->musb = musb;
glue->clk = clk;
pdata->platform_ops = &davinci_ops;
@@ -561,26 +567,22 @@ static int davinci_probe(struct platform_device *pdev)
musb_resources[1].end = pdev->resource[1].end;
musb_resources[1].flags = pdev->resource[1].flags;
- /*
- * For DM6467 3 resources are passed. A placeholder for the 3rd
- * resource is always there, so it's safe to always copy it...
- */
- musb_resources[2].name = pdev->resource[2].name;
- musb_resources[2].start = pdev->resource[2].start;
- musb_resources[2].end = pdev->resource[2].end;
- musb_resources[2].flags = pdev->resource[2].flags;
-
- pinfo = davinci_dev_info;
- pinfo.parent = &pdev->dev;
- pinfo.res = musb_resources;
- pinfo.num_res = ARRAY_SIZE(musb_resources);
- pinfo.data = pdata;
- pinfo.size_data = sizeof(*pdata);
-
- glue->musb = musb = platform_device_register_full(&pinfo);
- if (IS_ERR(musb)) {
- ret = PTR_ERR(musb);
- dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
+ ret = platform_device_add_resources(musb, musb_resources,
+ ARRAY_SIZE(musb_resources));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add resources\n");
+ goto err5;
+ }
+
+ ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add platform_data\n");
+ goto err5;
+ }
+
+ ret = platform_device_add(musb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register musb device\n");
goto err5;
}
@@ -593,6 +595,9 @@ err4:
clk_put(clk);
err3:
+ platform_device_put(musb);
+
+err1:
kfree(glue);
err0:
diff --git a/drivers/usb/musb/musb_am335x.c b/drivers/usb/musb/musb_am335x.c
index 8be9b02..41ac5b5 100644
--- a/drivers/usb/musb/musb_am335x.c
+++ b/drivers/usb/musb/musb_am335x.c
@@ -46,7 +46,7 @@ static struct platform_driver am335x_child_driver = {
.remove = am335x_child_remove,
.driver = {
.name = "am335x-usb-childs",
- .of_match_table = am335x_child_of_match,
+ .of_match_table = of_match_ptr(am335x_child_of_match),
},
};
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 4d4499b..cd70cc8 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -617,7 +617,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
/* case 3 << MUSB_DEVCTL_VBUS_SHIFT: */
default:
s = "VALID"; break;
- } s; }),
+ }; s; }),
VBUSERR_RETRY_COUNT - musb->vbuserr_retry,
musb->port1_status);
@@ -1809,6 +1809,8 @@ static void musb_free(struct musb *musb)
disable_irq_wake(musb->nIrq);
free_irq(musb->nIrq, musb);
}
+ if (musb->dma_controller)
+ dma_controller_destroy(musb->dma_controller);
musb_host_free(musb);
}
@@ -1883,21 +1885,13 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
pm_runtime_get_sync(musb->controller);
- if (use_dma && dev->dma_mask) {
+ if (use_dma && dev->dma_mask)
musb->dma_controller = dma_controller_create(musb, musb->mregs);
- if (IS_ERR(musb->dma_controller)) {
- status = PTR_ERR(musb->dma_controller);
- goto fail2_5;
- }
- }
/* be sure interrupts are disabled before connecting ISR */
musb_platform_disable(musb);
musb_generic_disable(musb);
- /* Init IRQ workqueue before request_irq */
- INIT_WORK(&musb->irq_work, musb_irq_work);
-
/* setup musb parts of the core (especially endpoints) */
status = musb_core_init(plat->config->multipoint
? MUSB_CONTROLLER_MHDRC
@@ -1907,6 +1901,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
+ /* Init IRQ workqueue before request_irq */
+ INIT_WORK(&musb->irq_work, musb_irq_work);
+
/* attach to the IRQ */
if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) {
dev_err(dev, "request_irq %d failed!\n", nIrq);
@@ -1949,8 +1946,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
if (status < 0)
goto fail3;
status = musb_gadget_setup(musb);
- if (status)
- musb_host_cleanup(musb);
break;
default:
dev_err(dev, "unsupported port mode %d\n", musb->port_mode);
@@ -1977,13 +1972,10 @@ fail5:
fail4:
musb_gadget_cleanup(musb);
- musb_host_cleanup(musb);
fail3:
- cancel_work_sync(&musb->irq_work);
if (musb->dma_controller)
dma_controller_destroy(musb->dma_controller);
-fail2_5:
pm_runtime_put_sync(musb->controller);
fail2:
@@ -2040,10 +2032,6 @@ static int musb_remove(struct platform_device *pdev)
musb_exit_debugfs(musb);
musb_shutdown(pdev);
- if (musb->dma_controller)
- dma_controller_destroy(musb->dma_controller);
-
- cancel_work_sync(&musb->irq_work);
musb_free(musb);
device_init_wakeup(dev, 0);
return 0;
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 29f7cd7..1c5bf75 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -46,7 +46,6 @@
#include <linux/usb.h>
#include <linux/usb/otg.h>
#include <linux/usb/musb.h>
-#include <linux/phy/phy.h>
struct musb;
struct musb_hw_ep;
@@ -342,7 +341,6 @@ struct musb {
u16 int_tx;
struct usb_phy *xceiv;
- struct phy *phy;
int nIrq;
unsigned irq_wake:1;
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index a12bd30..ae95974 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -38,7 +38,6 @@ struct cppi41_dma_channel {
u32 prog_len;
u32 transferred;
u32 packet_sz;
- struct list_head tx_check;
};
#define MUSB_DMA_NUM_CHANNELS 15
@@ -48,8 +47,6 @@ struct cppi41_dma_controller {
struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS];
struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS];
struct musb *musb;
- struct hrtimer early_tx;
- struct list_head early_tx_list;
u32 rx_mode;
u32 tx_mode;
u32 auto_req;
@@ -99,27 +96,31 @@ static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
cppi41_channel->usb_toggle = toggle;
}
-static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep)
+static void cppi41_dma_callback(void *private_data)
{
- u8 epnum = hw_ep->epnum;
- struct musb *musb = hw_ep->musb;
- void __iomem *epio = musb->endpoints[epnum].regs;
- u16 csr;
+ 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;
- csr = musb_readw(epio, MUSB_TXCSR);
- if (csr & MUSB_TXCSR_TXPKTRDY)
- return false;
- return true;
-}
+ spin_lock_irqsave(&musb->lock, flags);
-static void cppi41_dma_callback(void *private_data);
+ dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
+ &txstate);
+ transferred = cppi41_channel->prog_len - txstate.residue;
+ cppi41_channel->transferred += transferred;
-static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
-{
- struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
- struct musb *musb = hw_ep->musb;
+ 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->prog_len) {
+ if (cppi41_channel->transferred == cppi41_channel->total_len ||
+ transferred < cppi41_channel->packet_sz) {
/* done, complete */
cppi41_channel->channel.actual_len =
@@ -149,11 +150,13 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
remain_bytes,
direction,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- if (WARN_ON(!dma_desc))
+ if (WARN_ON(!dma_desc)) {
+ spin_unlock_irqrestore(&musb->lock, flags);
return;
+ }
dma_desc->callback = cppi41_dma_callback;
- dma_desc->callback_param = &cppi41_channel->channel;
+ dma_desc->callback_param = channel;
cppi41_channel->cookie = dma_desc->tx_submit(dma_desc);
dma_async_issue_pending(dc);
@@ -163,117 +166,6 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
musb_writew(epio, MUSB_RXCSR, csr);
}
}
-}
-
-static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer)
-{
- struct cppi41_dma_controller *controller;
- struct cppi41_dma_channel *cppi41_channel, *n;
- struct musb *musb;
- unsigned long flags;
- enum hrtimer_restart ret = HRTIMER_NORESTART;
-
- controller = container_of(timer, struct cppi41_dma_controller,
- early_tx);
- musb = controller->musb;
-
- spin_lock_irqsave(&musb->lock, flags);
- list_for_each_entry_safe(cppi41_channel, n, &controller->early_tx_list,
- tx_check) {
- bool empty;
- struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
-
- empty = musb_is_tx_fifo_empty(hw_ep);
- if (empty) {
- list_del_init(&cppi41_channel->tx_check);
- cppi41_trans_done(cppi41_channel);
- }
- }
-
- if (!list_empty(&controller->early_tx_list)) {
- ret = HRTIMER_RESTART;
- hrtimer_forward_now(&controller->early_tx,
- ktime_set(0, 150 * NSEC_PER_USEC));
- }
-
- spin_unlock_irqrestore(&musb->lock, flags);
- return ret;
-}
-
-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;
- bool empty;
-
- 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)
- cppi41_channel->prog_len = 0;
-
- empty = musb_is_tx_fifo_empty(hw_ep);
- if (empty) {
- cppi41_trans_done(cppi41_channel);
- } else {
- struct cppi41_dma_controller *controller;
- /*
- * On AM335x it has been observed that the TX interrupt fires
- * too early that means the TXFIFO is not yet empty but the DMA
- * engine says that it is done with the transfer. We don't
- * receive a FIFO empty interrupt so the only thing we can do is
- * to poll for the bit. On HS it usually takes 2us, on FS around
- * 110us - 150us depending on the transfer size.
- * We spin on HS (no longer than than 25us and setup a timer on
- * FS to check for the bit and complete the transfer.
- */
- controller = cppi41_channel->controller;
-
- if (musb->g.speed == USB_SPEED_HIGH) {
- unsigned wait = 25;
-
- do {
- empty = musb_is_tx_fifo_empty(hw_ep);
- if (empty)
- break;
- wait--;
- if (!wait)
- break;
- udelay(1);
- } while (1);
-
- empty = musb_is_tx_fifo_empty(hw_ep);
- if (empty) {
- cppi41_trans_done(cppi41_channel);
- goto out;
- }
- }
- list_add_tail(&cppi41_channel->tx_check,
- &controller->early_tx_list);
- if (!hrtimer_active(&controller->early_tx)) {
- hrtimer_start_range_ns(&controller->early_tx,
- ktime_set(0, 140 * NSEC_PER_USEC),
- 40 * NSEC_PER_USEC,
- HRTIMER_MODE_REL);
- }
- }
-out:
spin_unlock_irqrestore(&musb->lock, flags);
}
@@ -472,8 +364,6 @@ static int cppi41_is_compatible(struct dma_channel *channel, u16 maxpacket,
WARN_ON(1);
return 1;
}
- if (cppi41_channel->hw_ep->ep_in.type != USB_ENDPOINT_XFER_BULK)
- return 0;
if (cppi41_channel->is_tx)
return 1;
/* AM335x Advisory 1.0.13. No workaround for device RX mode */
@@ -498,7 +388,6 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel)
if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)
return 0;
- list_del_init(&cppi41_channel->tx_check);
if (is_tx) {
csr = musb_readw(epio, MUSB_TXCSR);
csr &= ~MUSB_TXCSR_DMAENAB;
@@ -595,7 +484,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
if (ret)
goto err;
- ret = -EINVAL;
if (port > MUSB_DMA_NUM_CHANNELS || !port)
goto err;
if (is_tx)
@@ -606,7 +494,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
cppi41_channel->controller = controller;
cppi41_channel->port_num = port;
cppi41_channel->is_tx = is_tx;
- INIT_LIST_HEAD(&cppi41_channel->tx_check);
musb_dma = &cppi41_channel->channel;
musb_dma->private_data = cppi41_channel;
@@ -616,7 +503,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
dc = dma_request_slave_channel(dev, str);
if (!dc) {
dev_err(dev, "Falied to request %s.\n", str);
- ret = -EPROBE_DEFER;
goto err;
}
cppi41_channel->dc = dc;
@@ -624,7 +510,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
return 0;
err:
cppi41_release_all_dma_chans(controller);
- return ret;
+ return -EINVAL;
}
void dma_controller_destroy(struct dma_controller *c)
@@ -632,7 +518,6 @@ void dma_controller_destroy(struct dma_controller *c)
struct cppi41_dma_controller *controller = container_of(c,
struct cppi41_dma_controller, controller);
- hrtimer_cancel(&controller->early_tx);
cppi41_dma_controller_stop(controller);
kfree(controller);
}
@@ -641,7 +526,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,
void __iomem *base)
{
struct cppi41_dma_controller *controller;
- int ret = 0;
+ int ret;
if (!musb->controller->of_node) {
dev_err(musb->controller, "Need DT for the DMA engine.\n");
@@ -652,9 +537,6 @@ struct dma_controller *dma_controller_create(struct musb *musb,
if (!controller)
goto kzalloc_fail;
- hrtimer_init(&controller->early_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- controller->early_tx.function = cppi41_recheck_tx_req;
- INIT_LIST_HEAD(&controller->early_tx_list);
controller->musb = musb;
controller->controller.channel_alloc = cppi41_dma_channel_allocate;
@@ -671,7 +553,5 @@ struct dma_controller *dma_controller_create(struct musb *musb,
plat_get_fail:
kfree(controller);
kzalloc_fail:
- if (ret == -EPROBE_DEFER)
- return ERR_PTR(ret);
return NULL;
}
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 1901f6f..bd4138d 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -121,43 +121,6 @@ struct dsps_glue {
unsigned long last_timer; /* last timer data for each instance */
};
-static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
-{
- struct device *dev = musb->controller;
- struct dsps_glue *glue = dev_get_drvdata(dev->parent);
-
- if (timeout == 0)
- timeout = jiffies + msecs_to_jiffies(3);
-
- /* Never idle if active, or when VBUS timeout is not set as host */
- if (musb->is_active || (musb->a_wait_bcon == 0 &&
- 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);
- glue->last_timer = jiffies;
- return;
- }
- if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE)
- return;
-
- if (!musb->g.dev.driver)
- return;
-
- 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 = 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, timeout);
-}
-
/**
* dsps_musb_enable - enable interrupts
*/
@@ -180,7 +143,6 @@ static void dsps_musb_enable(struct musb *musb)
/* Force the DRVVBUS IRQ so we can start polling for ID change. */
dsps_writel(reg_base, wrp->coreintr_set,
(1 << wrp->drvvbus) << wrp->usb_shift);
- dsps_musb_try_idle(musb, 0);
}
/**
@@ -209,7 +171,6 @@ static void otg_timer(unsigned long _musb)
const struct dsps_musb_wrapper *wrp = glue->wrp;
u8 devctl;
unsigned long flags;
- int skip_session = 0;
/*
* We poll because DSPS IP's won't expose several OTG-critical
@@ -222,12 +183,10 @@ static void otg_timer(unsigned long _musb)
spin_lock_irqsave(&musb->lock, flags);
switch (musb->xceiv->state) {
case OTG_STATE_A_WAIT_BCON:
- dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
- skip_session = 1;
- /* fall */
+ devctl &= ~MUSB_DEVCTL_SESSION;
+ dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
- case OTG_STATE_A_IDLE:
- case OTG_STATE_B_IDLE:
+ devctl = dsps_readb(musb->mregs, MUSB_DEVCTL);
if (devctl & MUSB_DEVCTL_BDEVICE) {
musb->xceiv->state = OTG_STATE_B_IDLE;
MUSB_DEV_MODE(musb);
@@ -235,21 +194,60 @@ static void otg_timer(unsigned long _musb)
musb->xceiv->state = OTG_STATE_A_IDLE;
MUSB_HST_MODE(musb);
}
- if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session)
- dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
- mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
break;
case OTG_STATE_A_WAIT_VFALL:
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
dsps_writel(musb->ctrl_base, wrp->coreintr_set,
MUSB_INTR_VBUSERROR << wrp->usb_shift);
break;
+ case OTG_STATE_B_IDLE:
+ devctl = dsps_readb(mregs, MUSB_DEVCTL);
+ if (devctl & MUSB_DEVCTL_BDEVICE)
+ mod_timer(&glue->timer,
+ jiffies + wrp->poll_seconds * HZ);
+ else
+ musb->xceiv->state = OTG_STATE_A_IDLE;
+ break;
default:
break;
}
spin_unlock_irqrestore(&musb->lock, flags);
}
+static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
+{
+ struct device *dev = musb->controller;
+ struct dsps_glue *glue = dev_get_drvdata(dev->parent);
+
+ if (timeout == 0)
+ timeout = jiffies + msecs_to_jiffies(3);
+
+ /* Never idle if active, or when VBUS timeout is not set as host */
+ if (musb->is_active || (musb->a_wait_bcon == 0 &&
+ 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);
+ glue->last_timer = jiffies;
+ return;
+ }
+ if (musb->port_mode == MUSB_PORT_MODE_HOST)
+ return;
+
+ 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 = 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, timeout);
+}
+
static irqreturn_t dsps_interrupt(int irq, void *hci)
{
struct musb *musb = hci;
@@ -445,7 +443,7 @@ static int get_musb_port_mode(struct device *dev)
case USB_DR_MODE_OTG:
default:
return MUSB_PORT_MODE_DUAL_ROLE;
- }
+ };
}
static int dsps_create_musb_pdev(struct dsps_glue *glue,
@@ -633,7 +631,7 @@ static struct platform_driver dsps_usbss_driver = {
.remove = dsps_remove,
.driver = {
.name = "musb-dsps",
- .of_match_table = musb_dsps_of_match,
+ .of_match_table = of_match_ptr(musb_dsps_of_match),
},
};
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 32fb057..3671898 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1121,7 +1121,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
case USB_ENDPOINT_XFER_BULK: s = "bulk"; break;
case USB_ENDPOINT_XFER_INT: s = "int"; break;
default: s = "iso"; break;
- } s; }),
+ }; s; }),
musb_ep->is_in ? "IN" : "OUT",
musb_ep->dma ? "dma, " : "",
musb_ep->packet_sz);
@@ -1796,11 +1796,7 @@ int musb_gadget_setup(struct musb *musb)
/* this "gadget" abstracts/virtualizes the controller */
musb->g.name = musb_driver_name;
-#if IS_ENABLED(CONFIG_USB_MUSB_DUAL_ROLE)
musb->g.is_otg = 1;
-#elif IS_ENABLED(CONFIG_USB_MUSB_GADGET)
- musb->g.is_otg = 0;
-#endif
musb_g_init_endpoints(musb);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 6582a20..9a2b8c8 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -253,7 +253,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
case USB_ENDPOINT_XFER_BULK: s = "-bulk"; break;
case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break;
default: s = "-intr"; break;
- } s; }),
+ }; s; }),
epnum, buf + offset, len);
/* Configure endpoint */
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
index 9af6bba..d1d6b83 100644
--- a/drivers/usb/musb/musb_virthub.c
+++ b/drivers/usb/musb/musb_virthub.c
@@ -220,23 +220,6 @@ int musb_hub_status_data(struct usb_hcd *hcd, char *buf)
return retval;
}
-static int musb_has_gadget(struct musb *musb)
-{
- /*
- * In host-only mode we start a connection right away. In OTG mode
- * we have to wait until we loaded a gadget. We don't really need a
- * gadget if we operate as a host but we should not start a session
- * as a device without a gadget or else we explode.
- */
-#ifdef CONFIG_USB_MUSB_HOST
- return 1;
-#else
- if (musb->port_mode == MUSB_PORT_MODE_HOST)
- return 1;
- return musb->g.dev.driver != NULL;
-#endif
-}
-
int musb_hub_control(
struct usb_hcd *hcd,
u16 typeReq,
@@ -379,7 +362,7 @@ int musb_hub_control(
* initialization logic, e.g. for OTG, or change any
* logic relating to VBUS power-up.
*/
- if (!hcd->self.is_b_host && musb_has_gadget(musb))
+ if (!hcd->self.is_b_host)
musb_start(musb);
break;
case USB_PORT_FEAT_RESET:
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 2a408cd..59d2245 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -38,7 +38,6 @@
#include <linux/delay.h>
#include <linux/usb/musb-omap.h>
#include <linux/usb/omap_control_usb.h>
-#include <linux/of_platform.h>
#include "musb_core.h"
#include "omap2430.h"
@@ -306,9 +305,6 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
default:
dev_dbg(dev, "ID float\n");
}
-
- atomic_notifier_call_chain(&musb->xceiv->notifier,
- musb->xceiv->last_event, NULL);
}
@@ -352,21 +348,11 @@ static int omap2430_musb_init(struct musb *musb)
* up through ULPI. TWL4030-family PMICs include one,
* which needs a driver, drivers aren't always needed.
*/
- if (dev->parent->of_node) {
- musb->phy = devm_phy_get(dev->parent, "usb2-phy");
-
- /* We can't totally remove musb->xceiv as of now because
- * musb core uses xceiv.state and xceiv.otg. Once we have
- * a separate state machine to handle otg, these can be moved
- * out of xceiv and then we can start using the generic PHY
- * framework
- */
+ if (dev->parent->of_node)
musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent,
"usb-phy", 0);
- } else {
+ else
musb->xceiv = devm_usb_get_phy_dev(dev, 0);
- musb->phy = devm_phy_get(dev, "usb");
- }
if (IS_ERR(musb->xceiv)) {
status = PTR_ERR(musb->xceiv);
@@ -378,10 +364,6 @@ static int omap2430_musb_init(struct musb *musb)
return -EPROBE_DEFER;
}
- if (IS_ERR(musb->phy)) {
- pr_err("HS USB OTG: no PHY configured\n");
- return PTR_ERR(musb->phy);
- }
musb->isr = omap2430_musb_interrupt;
status = pm_runtime_get_sync(dev);
@@ -415,7 +397,7 @@ static int omap2430_musb_init(struct musb *musb)
if (glue->status != OMAP_MUSB_UNKNOWN)
omap_musb_set_mailbox(glue);
- phy_init(musb->phy);
+ usb_phy_init(musb->xceiv);
pm_runtime_put_noidle(musb->controller);
return 0;
@@ -478,7 +460,6 @@ static int omap2430_musb_exit(struct musb *musb)
del_timer_sync(&musb_idle_timer);
omap2430_low_level_exit(musb);
- phy_exit(musb->phy);
return 0;
}
@@ -528,12 +509,8 @@ static int omap2430_probe(struct platform_device *pdev)
glue->dev = &pdev->dev;
glue->musb = musb;
glue->status = OMAP_MUSB_UNKNOWN;
- glue->control_otghs = ERR_PTR(-ENODEV);
if (np) {
- struct device_node *control_node;
- struct platform_device *control_pdev;
-
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
dev_err(&pdev->dev,
@@ -562,20 +539,22 @@ static int omap2430_probe(struct platform_device *pdev)
of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
of_property_read_u32(np, "power", (u32 *)&pdata->power);
config->multipoint = of_property_read_bool(np, "multipoint");
+ pdata->has_mailbox = of_property_read_bool(np,
+ "ti,has-mailbox");
pdata->board_data = data;
pdata->config = config;
+ }
- control_node = of_parse_phandle(np, "ctrl-module", 0);
- if (control_node) {
- control_pdev = of_find_device_by_node(control_node);
- if (!control_pdev) {
- dev_err(&pdev->dev, "Failed to get control device\n");
- ret = -EINVAL;
- goto err2;
- }
- glue->control_otghs = &control_pdev->dev;
+ if (pdata->has_mailbox) {
+ glue->control_otghs = omap_get_control_dev();
+ if (IS_ERR(glue->control_otghs)) {
+ dev_vdbg(&pdev->dev, "Failed to get control device\n");
+ ret = PTR_ERR(glue->control_otghs);
+ goto err2;
}
+ } else {
+ glue->control_otghs = ERR_PTR(-ENODEV);
}
pdata->platform_ops = &omap2430_ops;
@@ -659,7 +638,7 @@ static int omap2430_runtime_suspend(struct device *dev)
OTG_INTERFSEL);
omap2430_low_level_exit(musb);
- phy_power_off(musb->phy);
+ usb_phy_set_suspend(musb->xceiv, 1);
}
return 0;
@@ -674,7 +653,8 @@ static int omap2430_runtime_resume(struct device *dev)
omap2430_low_level_init(musb);
musb_writel(musb->mregs, OTG_INTERFSEL,
musb->context.otg_interfsel);
- phy_power_on(musb->phy);
+
+ usb_phy_set_suspend(musb->xceiv, 0);
}
return 0;
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 4432314..b3b3ed7 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -1152,11 +1152,7 @@ static const struct musb_platform_ops tusb_ops = {
.set_vbus = tusb_musb_set_vbus,
};
-static const struct platform_device_info tusb_dev_info = {
- .name = "musb-hdrc",
- .id = PLATFORM_DEVID_AUTO,
- .dma_mask = DMA_BIT_MASK(32),
-};
+static u64 tusb_dmamask = DMA_BIT_MASK(32);
static int tusb_probe(struct platform_device *pdev)
{
@@ -1164,7 +1160,7 @@ static int tusb_probe(struct platform_device *pdev)
struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct tusb6010_glue *glue;
- struct platform_device_info pinfo;
+
int ret = -ENOMEM;
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
@@ -1173,7 +1169,18 @@ static int tusb_probe(struct platform_device *pdev)
goto err0;
}
+ musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
+ if (!musb) {
+ dev_err(&pdev->dev, "failed to allocate musb device\n");
+ goto err1;
+ }
+
+ musb->dev.parent = &pdev->dev;
+ musb->dev.dma_mask = &tusb_dmamask;
+ musb->dev.coherent_dma_mask = tusb_dmamask;
+
glue->dev = &pdev->dev;
+ glue->musb = musb;
pdata->platform_ops = &tusb_ops;
@@ -1197,23 +1204,31 @@ static int tusb_probe(struct platform_device *pdev)
musb_resources[2].end = pdev->resource[2].end;
musb_resources[2].flags = pdev->resource[2].flags;
- pinfo = tusb_dev_info;
- pinfo.parent = &pdev->dev;
- pinfo.res = musb_resources;
- pinfo.num_res = ARRAY_SIZE(musb_resources);
- pinfo.data = pdata;
- pinfo.size_data = sizeof(*pdata);
-
- glue->musb = musb = platform_device_register_full(&pinfo);
- if (IS_ERR(musb)) {
- ret = PTR_ERR(musb);
- dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
+ ret = platform_device_add_resources(musb, musb_resources,
+ ARRAY_SIZE(musb_resources));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add resources\n");
+ goto err3;
+ }
+
+ ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add platform_data\n");
+ goto err3;
+ }
+
+ ret = platform_device_add(musb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register musb device\n");
goto err3;
}
return 0;
err3:
+ platform_device_put(musb);
+
+err1:
kfree(glue);
err0:
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c
index 122446b..59256b1 100644
--- a/drivers/usb/musb/ux500.c
+++ b/drivers/usb/musb/ux500.c
@@ -259,7 +259,7 @@ static int ux500_probe(struct platform_device *pdev)
goto err1;
}
- clk = clk_get(&pdev->dev, NULL);
+ clk = clk_get(&pdev->dev, "usb");
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
ret = PTR_ERR(clk);
@@ -376,9 +376,16 @@ static int ux500_resume(struct device *dev)
return 0;
}
-#endif
-static SIMPLE_DEV_PM_OPS(ux500_pm_ops, ux500_suspend, ux500_resume);
+static const struct dev_pm_ops ux500_pm_ops = {
+ .suspend = ux500_suspend,
+ .resume = ux500_resume,
+};
+
+#define DEV_PM_OPS (&ux500_pm_ops)
+#else
+#define DEV_PM_OPS NULL
+#endif
static const struct of_device_id ux500_match[] = {
{ .compatible = "stericsson,db8500-musb", },
@@ -390,7 +397,7 @@ static struct platform_driver ux500_driver = {
.remove = ux500_remove,
.driver = {
.name = "musb-ux500",
- .pm = &ux500_pm_ops,
+ .pm = DEV_PM_OPS,
.of_match_table = ux500_match,
},
};