Merge tag 'usb-for-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: usb: patches for v3.13 Final conversions to configfs for mass storage, acm_ms, and multi gadgets. MUSB should now work out of the box on AM335x-based boards (beagle bone white and black) with DMA thanks to Sebastian's work. We can now enable VERBOSE_DEBUG on builds of drivers/usb/gadget/ by selecting CONFIG_USB_GADGET_VERBOSE. s3c-hsotg got quite a few non-critical fixes but also learned a few new tricks (isochronous transfers, multi count support). The Marvel USB3 Controller driver got a memory leak fix. devm_usb_get_phy() learned not to return NULL, ever. Other than these patches, we have the usual set of cleanups ranging from removal of unnecessary *_set_drvdata() to using SIMPLE_DEV_PM_OPS. Signed-of-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
@@ -91,7 +91,7 @@ config USB_MUSB_BLACKFIN
|
||||
depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523)
|
||||
|
||||
config USB_MUSB_UX500
|
||||
tristate "U8500 and U5500"
|
||||
tristate "Ux500 platforms"
|
||||
|
||||
endchoice
|
||||
|
||||
@@ -113,7 +113,7 @@ choice
|
||||
allow using DMA on multiplatform kernels.
|
||||
|
||||
config USB_UX500_DMA
|
||||
bool 'ST Ericsson U8500 and U5500'
|
||||
bool 'ST Ericsson Ux500'
|
||||
depends on USB_MUSB_UX500
|
||||
help
|
||||
Enable DMA transfers on UX500 platforms.
|
||||
|
@@ -89,7 +89,6 @@ 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
|
||||
@@ -452,14 +451,18 @@ static const struct musb_platform_ops am35x_ops = {
|
||||
.set_vbus = am35x_musb_set_vbus,
|
||||
};
|
||||
|
||||
static u64 am35x_dmamask = DMA_BIT_MASK(32);
|
||||
static const struct platform_device_info am35x_dev_info = {
|
||||
.name = "musb-hdrc",
|
||||
.id = PLATFORM_DEVID_AUTO,
|
||||
.dma_mask = 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;
|
||||
|
||||
@@ -471,12 +474,6 @@ 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");
|
||||
@@ -503,12 +500,7 @@ 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;
|
||||
|
||||
@@ -516,22 +508,17 @@ static int am35x_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, glue);
|
||||
|
||||
ret = platform_device_add_resources(musb, pdev->resource,
|
||||
pdev->num_resources);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to add resources\n");
|
||||
goto err7;
|
||||
}
|
||||
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);
|
||||
|
||||
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");
|
||||
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);
|
||||
goto err7;
|
||||
}
|
||||
|
||||
@@ -550,9 +537,6 @@ err4:
|
||||
clk_put(phy_clk);
|
||||
|
||||
err3:
|
||||
platform_device_put(musb);
|
||||
|
||||
err1:
|
||||
kfree(glue);
|
||||
|
||||
err0:
|
||||
@@ -615,23 +599,16 @@ static int am35x_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 SIMPLE_DEV_PM_OPS(am35x_pm_ops, am35x_suspend, am35x_resume);
|
||||
|
||||
static struct platform_driver am35x_driver = {
|
||||
.probe = am35x_probe,
|
||||
.remove = am35x_remove,
|
||||
.driver = {
|
||||
.name = "musb-am35x",
|
||||
.pm = DEV_PM_OPS,
|
||||
.pm = &am35x_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -561,23 +561,16 @@ static int bfin_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 SIMPLE_DEV_PM_OPS(bfin_pm_ops, bfin_suspend, bfin_resume);
|
||||
|
||||
static struct platform_driver bfin_driver = {
|
||||
.probe = bfin_probe,
|
||||
.remove = __exit_p(bfin_remove),
|
||||
.driver = {
|
||||
.name = "musb-blackfin",
|
||||
.pm = DEV_PM_OPS,
|
||||
.pm = &bfin_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -472,7 +472,11 @@ static const struct musb_platform_ops da8xx_ops = {
|
||||
.set_vbus = da8xx_musb_set_vbus,
|
||||
};
|
||||
|
||||
static u64 da8xx_dmamask = DMA_BIT_MASK(32);
|
||||
static const struct platform_device_info da8xx_dev_info = {
|
||||
.name = "musb-hdrc",
|
||||
.id = PLATFORM_DEVID_AUTO,
|
||||
.dma_mask = DMA_BIT_MASK(32),
|
||||
};
|
||||
|
||||
static int da8xx_probe(struct platform_device *pdev)
|
||||
{
|
||||
@@ -480,7 +484,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;
|
||||
@@ -491,12 +495,6 @@ 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");
|
||||
@@ -510,12 +508,7 @@ 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;
|
||||
@@ -535,22 +528,17 @@ static int da8xx_probe(struct platform_device *pdev)
|
||||
musb_resources[1].end = pdev->resource[1].end;
|
||||
musb_resources[1].flags = pdev->resource[1].flags;
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
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");
|
||||
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);
|
||||
goto err5;
|
||||
}
|
||||
|
||||
@@ -563,9 +551,6 @@ err4:
|
||||
clk_put(clk);
|
||||
|
||||
err3:
|
||||
platform_device_put(musb);
|
||||
|
||||
err1:
|
||||
kfree(glue);
|
||||
|
||||
err0:
|
||||
|
@@ -505,14 +505,19 @@ static const struct musb_platform_ops davinci_ops = {
|
||||
.set_vbus = davinci_musb_set_vbus,
|
||||
};
|
||||
|
||||
static u64 davinci_dmamask = DMA_BIT_MASK(32);
|
||||
static const struct platform_device_info davinci_dev_info = {
|
||||
.name = "musb-hdrc",
|
||||
.id = PLATFORM_DEVID_AUTO,
|
||||
.dma_mask = DMA_BIT_MASK(32),
|
||||
};
|
||||
|
||||
static int davinci_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource musb_resources[2];
|
||||
struct resource musb_resources[3];
|
||||
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;
|
||||
@@ -523,12 +528,6 @@ 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");
|
||||
@@ -542,12 +541,7 @@ 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;
|
||||
@@ -567,22 +561,26 @@ static int davinci_probe(struct platform_device *pdev)
|
||||
musb_resources[1].end = pdev->resource[1].end;
|
||||
musb_resources[1].flags = pdev->resource[1].flags;
|
||||
|
||||
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;
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
|
||||
ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to add platform_data\n");
|
||||
goto err5;
|
||||
}
|
||||
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);
|
||||
|
||||
ret = platform_device_add(musb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register musb device\n");
|
||||
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);
|
||||
goto err5;
|
||||
}
|
||||
|
||||
@@ -595,9 +593,6 @@ err4:
|
||||
clk_put(clk);
|
||||
|
||||
err3:
|
||||
platform_device_put(musb);
|
||||
|
||||
err1:
|
||||
kfree(glue);
|
||||
|
||||
err0:
|
||||
|
@@ -46,7 +46,7 @@ static struct platform_driver am335x_child_driver = {
|
||||
.remove = am335x_child_remove,
|
||||
.driver = {
|
||||
.name = "am335x-usb-childs",
|
||||
.of_match_table = of_match_ptr(am335x_child_of_match),
|
||||
.of_match_table = am335x_child_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -1809,8 +1809,7 @@ 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);
|
||||
cancel_work_sync(&musb->irq_work);
|
||||
|
||||
musb_host_free(musb);
|
||||
}
|
||||
@@ -1885,8 +1884,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);
|
||||
@@ -1946,6 +1950,8 @@ 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);
|
||||
@@ -1972,10 +1978,12 @@ fail5:
|
||||
|
||||
fail4:
|
||||
musb_gadget_cleanup(musb);
|
||||
musb_host_cleanup(musb);
|
||||
|
||||
fail3:
|
||||
if (musb->dma_controller)
|
||||
dma_controller_destroy(musb->dma_controller);
|
||||
fail2_5:
|
||||
pm_runtime_put_sync(musb->controller);
|
||||
|
||||
fail2:
|
||||
@@ -2032,6 +2040,9 @@ 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);
|
||||
|
||||
musb_free(musb);
|
||||
device_init_wakeup(dev, 0);
|
||||
return 0;
|
||||
|
@@ -484,6 +484,7 @@ 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)
|
||||
@@ -503,6 +504,7 @@ 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;
|
||||
@@ -510,7 +512,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
|
||||
return 0;
|
||||
err:
|
||||
cppi41_release_all_dma_chans(controller);
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dma_controller_destroy(struct dma_controller *c)
|
||||
@@ -526,7 +528,7 @@ struct dma_controller *dma_controller_create(struct musb *musb,
|
||||
void __iomem *base)
|
||||
{
|
||||
struct cppi41_dma_controller *controller;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!musb->controller->of_node) {
|
||||
dev_err(musb->controller, "Need DT for the DMA engine.\n");
|
||||
@@ -553,5 +555,7 @@ 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;
|
||||
}
|
||||
|
@@ -121,6 +121,43 @@ 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
|
||||
*/
|
||||
@@ -143,6 +180,7 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,6 +209,7 @@ 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
|
||||
@@ -183,10 +222,12 @@ static void otg_timer(unsigned long _musb)
|
||||
spin_lock_irqsave(&musb->lock, flags);
|
||||
switch (musb->xceiv->state) {
|
||||
case OTG_STATE_A_WAIT_BCON:
|
||||
devctl &= ~MUSB_DEVCTL_SESSION;
|
||||
dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
|
||||
dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
|
||||
skip_session = 1;
|
||||
/* fall */
|
||||
|
||||
devctl = dsps_readb(musb->mregs, MUSB_DEVCTL);
|
||||
case OTG_STATE_A_IDLE:
|
||||
case OTG_STATE_B_IDLE:
|
||||
if (devctl & MUSB_DEVCTL_BDEVICE) {
|
||||
musb->xceiv->state = OTG_STATE_B_IDLE;
|
||||
MUSB_DEV_MODE(musb);
|
||||
@@ -194,60 +235,21 @@ 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;
|
||||
@@ -631,7 +633,7 @@ static struct platform_driver dsps_usbss_driver = {
|
||||
.remove = dsps_remove,
|
||||
.driver = {
|
||||
.name = "musb-dsps",
|
||||
.of_match_table = of_match_ptr(musb_dsps_of_match),
|
||||
.of_match_table = musb_dsps_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -220,6 +220,23 @@ 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,
|
||||
@@ -362,7 +379,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)
|
||||
if (!hcd->self.is_b_host && musb_has_gadget(musb))
|
||||
musb_start(musb);
|
||||
break;
|
||||
case USB_PORT_FEAT_RESET:
|
||||
|
@@ -306,6 +306,9 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1152,7 +1152,11 @@ static const struct musb_platform_ops tusb_ops = {
|
||||
.set_vbus = tusb_musb_set_vbus,
|
||||
};
|
||||
|
||||
static u64 tusb_dmamask = DMA_BIT_MASK(32);
|
||||
static const struct platform_device_info tusb_dev_info = {
|
||||
.name = "musb-hdrc",
|
||||
.id = PLATFORM_DEVID_AUTO,
|
||||
.dma_mask = DMA_BIT_MASK(32),
|
||||
};
|
||||
|
||||
static int tusb_probe(struct platform_device *pdev)
|
||||
{
|
||||
@@ -1160,7 +1164,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);
|
||||
@@ -1169,18 +1173,7 @@ 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;
|
||||
|
||||
@@ -1204,31 +1197,23 @@ static int tusb_probe(struct platform_device *pdev)
|
||||
musb_resources[2].end = pdev->resource[2].end;
|
||||
musb_resources[2].flags = pdev->resource[2].flags;
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
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");
|
||||
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);
|
||||
goto err3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err3:
|
||||
platform_device_put(musb);
|
||||
|
||||
err1:
|
||||
kfree(glue);
|
||||
|
||||
err0:
|
||||
|
@@ -376,17 +376,10 @@ static int ux500_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 SIMPLE_DEV_PM_OPS(ux500_pm_ops, ux500_suspend, ux500_resume);
|
||||
|
||||
static const struct of_device_id ux500_match[] = {
|
||||
{ .compatible = "stericsson,db8500-musb", },
|
||||
{}
|
||||
@@ -397,7 +390,7 @@ static struct platform_driver ux500_driver = {
|
||||
.remove = ux500_remove,
|
||||
.driver = {
|
||||
.name = "musb-ux500",
|
||||
.pm = DEV_PM_OPS,
|
||||
.pm = &ux500_pm_ops,
|
||||
.of_match_table = ux500_match,
|
||||
},
|
||||
};
|
||||
|
Reference in New Issue
Block a user