diff options
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/am35x.c | 1 | ||||
-rw-r--r-- | drivers/usb/musb/blackfin.c | 6 | ||||
-rw-r--r-- | drivers/usb/musb/da8xx.c | 36 | ||||
-rw-r--r-- | drivers/usb/musb/davinci.c | 1 | ||||
-rw-r--r-- | drivers/usb/musb/jz4740.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.c | 27 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 1 | ||||
-rw-r--r-- | drivers/usb/musb/musb_debugfs.c | 46 | ||||
-rw-r--r-- | drivers/usb/musb/musb_dsps.c | 123 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/sunxi.c | 49 | ||||
-rw-r--r-- | drivers/usb/musb/ux500.c | 2 |
12 files changed, 209 insertions, 87 deletions
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 50ca8052bc8e..02fbb4fe3745 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -121,7 +121,6 @@ static void am35x_musb_disable(struct musb *musb) musb_writel(reg_base, CORE_INTR_MASK_CLEAR_REG, AM35X_INTR_USB_MASK); musb_writel(reg_base, EP_INTR_MASK_CLEAR_REG, AM35X_TX_INTR_MASK | AM35X_RX_INTR_MASK); - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); musb_writel(reg_base, USB_END_OF_INTR_REG, 0); } diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 896798071817..4418574a36a1 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -581,8 +581,7 @@ static int bfin_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int bfin_suspend(struct device *dev) +static int __maybe_unused bfin_suspend(struct device *dev) { struct bfin_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); @@ -599,7 +598,7 @@ static int bfin_suspend(struct device *dev) return 0; } -static int bfin_resume(struct device *dev) +static int __maybe_unused bfin_resume(struct device *dev) { struct bfin_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); @@ -608,7 +607,6 @@ static int bfin_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(bfin_pm_ops, bfin_suspend, bfin_resume); diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index e89708d839e5..d79c288ccbf2 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -125,7 +125,6 @@ static void da8xx_musb_disable(struct musb *musb) musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG, DA8XX_INTR_USB_MASK | DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK); - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0); } @@ -458,15 +457,11 @@ static inline u8 get_vbus_power(struct device *dev) } static const struct musb_platform_ops da8xx_ops = { - .quirks = MUSB_DMA_CPPI | MUSB_INDEXED_EP, + .quirks = MUSB_INDEXED_EP | MUSB_PRESERVE_SESSION, .init = da8xx_musb_init, .exit = da8xx_musb_exit, .fifo_mode = 2, -#ifdef CONFIG_USB_TI_CPPI_DMA - .dma_init = cppi_dma_controller_create, - .dma_exit = cppi_dma_controller_destroy, -#endif .enable = da8xx_musb_enable, .disable = da8xx_musb_disable, @@ -578,6 +573,34 @@ static int da8xx_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int da8xx_suspend(struct device *dev) +{ + int ret; + struct da8xx_glue *glue = dev_get_drvdata(dev); + + ret = phy_power_off(glue->phy); + if (ret) + return ret; + clk_disable_unprepare(glue->clk); + + return 0; +} + +static int da8xx_resume(struct device *dev) +{ + int ret; + struct da8xx_glue *glue = dev_get_drvdata(dev); + + ret = clk_prepare_enable(glue->clk); + if (ret) + return ret; + return phy_power_on(glue->phy); +} +#endif + +static SIMPLE_DEV_PM_OPS(da8xx_pm_ops, da8xx_suspend, da8xx_resume); + #ifdef CONFIG_OF static const struct of_device_id da8xx_id_table[] = { { @@ -593,6 +616,7 @@ static struct platform_driver da8xx_driver = { .remove = da8xx_remove, .driver = { .name = "musb-da8xx", + .pm = &da8xx_pm_ops, .of_match_table = of_match_ptr(da8xx_id_table), }, }; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index cee61a51645e..52b491d3d5d8 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -133,7 +133,6 @@ static void davinci_musb_disable(struct musb *musb) DAVINCI_USB_USBINT_MASK | DAVINCI_USB_TXINT_MASK | DAVINCI_USB_RXINT_MASK); - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); musb_writel(musb->ctrl_base, DAVINCI_USB_EOI_REG, 0); if (is_dma_capable() && !dma_off) diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index bc8889956d17..40c68c23d553 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -63,7 +63,7 @@ static struct musb_fifo_cfg jz4740_musb_fifo_cfg[] = { { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 64, }, }; -static struct musb_hdrc_config jz4740_musb_config = { +static const struct musb_hdrc_config jz4740_musb_config = { /* Silicon does not implement USB OTG. */ .multipoint = 0, /* Max EPs scanned, driver will decide which EP can be used. */ diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 772f15821242..892088fe6e86 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1040,16 +1040,6 @@ static void musb_enable_interrupts(struct musb *musb) } -static void musb_generic_disable(struct musb *musb) -{ - void __iomem *mbase = musb->mregs; - - musb_disable_interrupts(musb); - - /* off */ - musb_writeb(mbase, MUSB_DEVCTL, 0); -} - /* * Program the HDRC to start (enable interrupts, dma, etc.). */ @@ -1106,8 +1096,8 @@ void musb_stop(struct musb *musb) { /* stop IRQs, timers, ... */ musb_platform_disable(musb); - musb_generic_disable(musb); - musb_dbg(musb, "HDRC disabled"); + musb_disable_interrupts(musb); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); /* FIXME * - mark host and/or peripheral drivers unusable/inactive @@ -2323,7 +2313,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) /* be sure interrupts are disabled before connecting ISR */ musb_platform_disable(musb); - musb_generic_disable(musb); + musb_disable_interrupts(musb); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); /* Init IRQ workqueue before request_irq */ INIT_DELAYED_WORK(&musb->irq_work, musb_irq_work); @@ -2497,11 +2488,13 @@ static int musb_remove(struct platform_device *pdev) pm_runtime_get_sync(musb->controller); musb_host_cleanup(musb); musb_gadget_cleanup(musb); + spin_lock_irqsave(&musb->lock, flags); musb_platform_disable(musb); - musb_generic_disable(musb); - spin_unlock_irqrestore(&musb->lock, flags); + musb_disable_interrupts(musb); musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + spin_unlock_irqrestore(&musb->lock, flags); + pm_runtime_dont_use_autosuspend(musb->controller); pm_runtime_put_sync(musb->controller); pm_runtime_disable(musb->controller); @@ -2676,7 +2669,9 @@ static int musb_suspend(struct device *dev) unsigned long flags; musb_platform_disable(musb); - musb_generic_disable(musb); + musb_disable_interrupts(musb); + if (!(musb->io.quirks & MUSB_PRESERVE_SESSION)) + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); WARN_ON(!list_empty(&musb->pending_list)); spin_lock_irqsave(&musb->lock, flags); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index ce5a18c98c6d..5b708be6d1d1 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -172,6 +172,7 @@ struct musb_io; */ struct musb_platform_ops { +#define MUSB_PRESERVE_SESSION BIT(7) #define MUSB_DMA_UX500 BIT(6) #define MUSB_DMA_CPPI41 BIT(5) #define MUSB_DMA_CPPI BIT(4) diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index dd70c88419d2..952733ceaac8 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -153,28 +153,34 @@ static int musb_test_mode_show(struct seq_file *s, void *unused) pm_runtime_mark_last_busy(musb->controller); pm_runtime_put_autosuspend(musb->controller); - if (test & MUSB_TEST_FORCE_HOST) + if (test == (MUSB_TEST_FORCE_HOST | MUSB_TEST_FORCE_FS)) + seq_printf(s, "force host full-speed\n"); + + else if (test == (MUSB_TEST_FORCE_HOST | MUSB_TEST_FORCE_HS)) + seq_printf(s, "force host high-speed\n"); + + else if (test == MUSB_TEST_FORCE_HOST) seq_printf(s, "force host\n"); - if (test & MUSB_TEST_FIFO_ACCESS) + else if (test == MUSB_TEST_FIFO_ACCESS) seq_printf(s, "fifo access\n"); - if (test & MUSB_TEST_FORCE_FS) + else if (test == MUSB_TEST_FORCE_FS) seq_printf(s, "force full-speed\n"); - if (test & MUSB_TEST_FORCE_HS) + else if (test == MUSB_TEST_FORCE_HS) seq_printf(s, "force high-speed\n"); - if (test & MUSB_TEST_PACKET) + else if (test == MUSB_TEST_PACKET) seq_printf(s, "test packet\n"); - if (test & MUSB_TEST_K) + else if (test == MUSB_TEST_K) seq_printf(s, "test K\n"); - if (test & MUSB_TEST_J) + else if (test == MUSB_TEST_J) seq_printf(s, "test J\n"); - if (test & MUSB_TEST_SE0_NAK) + else if (test == MUSB_TEST_SE0_NAK) seq_printf(s, "test SE0 NAK\n"); return 0; @@ -198,7 +204,7 @@ static ssize_t musb_test_mode_write(struct file *file, struct seq_file *s = file->private_data; struct musb *musb = s->private; u8 test; - char buf[18]; + char buf[24]; pm_runtime_get_sync(musb->controller); test = musb_readb(musb->mregs, MUSB_TESTMODE); @@ -213,30 +219,36 @@ static ssize_t musb_test_mode_write(struct file *file, if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) return -EFAULT; - if (strstarts(buf, "force host")) + if (strstarts(buf, "force host full-speed")) + test = MUSB_TEST_FORCE_HOST | MUSB_TEST_FORCE_FS; + + else if (strstarts(buf, "force host high-speed")) + test = MUSB_TEST_FORCE_HOST | MUSB_TEST_FORCE_HS; + + else if (strstarts(buf, "force host")) test = MUSB_TEST_FORCE_HOST; - if (strstarts(buf, "fifo access")) + else if (strstarts(buf, "fifo access")) test = MUSB_TEST_FIFO_ACCESS; - if (strstarts(buf, "force full-speed")) + else if (strstarts(buf, "force full-speed")) test = MUSB_TEST_FORCE_FS; - if (strstarts(buf, "force high-speed")) + else if (strstarts(buf, "force high-speed")) test = MUSB_TEST_FORCE_HS; - if (strstarts(buf, "test packet")) { + else if (strstarts(buf, "test packet")) { test = MUSB_TEST_PACKET; musb_load_testpacket(musb); } - if (strstarts(buf, "test K")) + else if (strstarts(buf, "test K")) test = MUSB_TEST_K; - if (strstarts(buf, "test J")) + else if (strstarts(buf, "test J")) test = MUSB_TEST_J; - if (strstarts(buf, "test SE0 NAK")) + else if (strstarts(buf, "test SE0 NAK")) test = MUSB_TEST_SE0_NAK; musb_writeb(musb->mregs, MUSB_TESTMODE, test); diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 9f125e179acd..c171a0f13bc3 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -118,6 +118,7 @@ struct dsps_glue { struct device *dev; struct platform_device *musb; /* child musb pdev */ const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ + int vbus_irq; /* optional vbus irq */ struct timer_list timer; /* otg_workaround timer */ unsigned long last_timer; /* last timer data for each instance */ bool sw_babble_enabled; @@ -145,6 +146,29 @@ static const struct debugfs_reg32 dsps_musb_regs[] = { { "mode", 0xe8 }, }; +static void dsps_mod_timer(struct dsps_glue *glue, int wait_ms) +{ + int wait; + + if (wait_ms < 0) + wait = msecs_to_jiffies(glue->wrp->poll_timeout); + else + wait = msecs_to_jiffies(wait_ms); + + mod_timer(&glue->timer, jiffies + wait); +} + +/* + * If no vbus irq from the PMIC is configured, we need to poll VBUS status. + */ +static void dsps_mod_timer_optional(struct dsps_glue *glue) +{ + if (glue->vbus_irq) + return; + + dsps_mod_timer(glue, -1); +} + /** * dsps_musb_enable - enable interrupts */ @@ -167,8 +191,7 @@ static void dsps_musb_enable(struct musb *musb) /* start polling for ID change in dual-role idle mode */ if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) - mod_timer(&glue->timer, jiffies + - msecs_to_jiffies(wrp->poll_timeout)); + dsps_mod_timer(glue, -1); } /** @@ -186,7 +209,6 @@ static void dsps_musb_disable(struct musb *musb) musb_writel(reg_base, wrp->epintr_clear, wrp->txep_bitmap | wrp->rxep_bitmap); del_timer_sync(&glue->timer); - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); } /* Caller must take musb->lock */ @@ -199,6 +221,9 @@ static int dsps_check_status(struct musb *musb, void *unused) u8 devctl; int skip_session = 0; + if (glue->vbus_irq) + del_timer(&glue->timer); + /* * We poll because DSPS IP's won't expose several OTG-critical * status change events (from the transceiver) otherwise. @@ -209,8 +234,7 @@ static int dsps_check_status(struct musb *musb, void *unused) switch (musb->xceiv->otg->state) { case OTG_STATE_A_WAIT_VRISE: - mod_timer(&glue->timer, jiffies + - msecs_to_jiffies(wrp->poll_timeout)); + dsps_mod_timer_optional(glue); break; case OTG_STATE_A_WAIT_BCON: musb_writeb(musb->mregs, MUSB_DEVCTL, 0); @@ -219,17 +243,19 @@ static int dsps_check_status(struct musb *musb, void *unused) case OTG_STATE_A_IDLE: case OTG_STATE_B_IDLE: - if (devctl & MUSB_DEVCTL_BDEVICE) { - musb->xceiv->otg->state = OTG_STATE_B_IDLE; - MUSB_DEV_MODE(musb); - } else { - musb->xceiv->otg->state = OTG_STATE_A_IDLE; - MUSB_HST_MODE(musb); + if (!glue->vbus_irq) { + if (devctl & MUSB_DEVCTL_BDEVICE) { + musb->xceiv->otg->state = OTG_STATE_B_IDLE; + MUSB_DEV_MODE(musb); + } else { + musb->xceiv->otg->state = OTG_STATE_A_IDLE; + MUSB_HST_MODE(musb); + } + if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) + musb_writeb(mregs, MUSB_DEVCTL, + MUSB_DEVCTL_SESSION); } - if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) - musb_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); - mod_timer(&glue->timer, jiffies + - msecs_to_jiffies(wrp->poll_timeout)); + dsps_mod_timer_optional(glue); break; case OTG_STATE_A_WAIT_VFALL: musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; @@ -267,7 +293,7 @@ static void otg_timer(unsigned long _musb) pm_runtime_put_autosuspend(dev); } -void dsps_musb_clear_ep_rxintr(struct musb *musb, int epnum) +static void dsps_musb_clear_ep_rxintr(struct musb *musb, int epnum) { u32 epintr; struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent); @@ -332,15 +358,13 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) */ musb->int_usb &= ~MUSB_INTR_VBUSERROR; musb->xceiv->otg->state = OTG_STATE_A_WAIT_VFALL; - mod_timer(&glue->timer, jiffies + - msecs_to_jiffies(wrp->poll_timeout)); + dsps_mod_timer_optional(glue); WARNING("VBUS error workaround (delay coming)\n"); } else if (drvvbus) { MUSB_HST_MODE(musb); musb->xceiv->otg->default_a = 1; musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; - mod_timer(&glue->timer, jiffies + - msecs_to_jiffies(wrp->poll_timeout)); + dsps_mod_timer_optional(glue); } else { musb->is_active = 0; MUSB_DEV_MODE(musb); @@ -364,8 +388,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) switch (musb->xceiv->otg->state) { case OTG_STATE_B_IDLE: case OTG_STATE_A_WAIT_BCON: - mod_timer(&glue->timer, jiffies + - msecs_to_jiffies(wrp->poll_timeout)); + dsps_mod_timer_optional(glue); break; default: break; @@ -469,8 +492,7 @@ static int dsps_musb_init(struct musb *musb) musb_writeb(musb->mregs, MUSB_BABBLE_CTL, val); } - mod_timer(&glue->timer, jiffies + - msecs_to_jiffies(glue->wrp->poll_timeout)); + dsps_mod_timer(glue, -1); return dsps_musb_dbg_init(musb, glue); } @@ -696,7 +718,8 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, resources[1] = *res; /* allocate the child platform device */ - musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); + musb = platform_device_alloc("musb-hdrc", + (resources[0].start & 0xFFF) == 0x400 ? 0 : 1); if (!musb) { dev_err(dev, "failed to allocate musb device\n"); return -ENOMEM; @@ -765,6 +788,47 @@ err: return ret; } +static irqreturn_t dsps_vbus_threaded_irq(int irq, void *priv) +{ + struct dsps_glue *glue = priv; + struct musb *musb = platform_get_drvdata(glue->musb); + + if (!musb) + return IRQ_NONE; + + dev_dbg(glue->dev, "VBUS interrupt\n"); + dsps_mod_timer(glue, 0); + + return IRQ_HANDLED; +} + +static int dsps_setup_optional_vbus_irq(struct platform_device *pdev, + struct dsps_glue *glue) +{ + int error; + + glue->vbus_irq = platform_get_irq_byname(pdev, "vbus"); + if (glue->vbus_irq == -EPROBE_DEFER) + return -EPROBE_DEFER; + + if (glue->vbus_irq <= 0) { + glue->vbus_irq = 0; + return 0; + } + + error = devm_request_threaded_irq(glue->dev, glue->vbus_irq, + NULL, dsps_vbus_threaded_irq, + IRQF_ONESHOT, + "vbus", glue); + if (error) { + glue->vbus_irq = 0; + return error; + } + dev_dbg(glue->dev, "VBUS irq %i configured\n", glue->vbus_irq); + + return 0; +} + static int dsps_probe(struct platform_device *pdev) { const struct of_device_id *match; @@ -793,6 +857,12 @@ static int dsps_probe(struct platform_device *pdev) glue->dev = &pdev->dev; glue->wrp = wrp; + if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) { + ret = dsps_setup_optional_vbus_irq(pdev, glue); + if (ret) + return ret; + } + platform_set_drvdata(pdev, glue); pm_runtime_enable(&pdev->dev); ret = dsps_create_musb_pdev(glue, pdev); @@ -903,8 +973,7 @@ static int dsps_resume(struct device *dev) musb_writel(mbase, wrp->rx_mode, glue->context.rx_mode); if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) - mod_timer(&glue->timer, jiffies + - msecs_to_jiffies(wrp->poll_timeout)); + dsps_mod_timer(glue, -1); return 0; } diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 8b73214a9ea3..456f3e6ecf03 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -575,7 +575,7 @@ static int omap2430_runtime_resume(struct device *dev) return 0; } -static struct dev_pm_ops omap2430_pm_ops = { +static const struct dev_pm_ops omap2430_pm_ops = { .runtime_suspend = omap2430_runtime_suspend, .runtime_resume = omap2430_runtime_resume, }; diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index d0be0eadd0d9..c9a09b5bb6e5 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c @@ -251,14 +251,14 @@ static int sunxi_musb_init(struct musb *musb) writeb(SUNXI_MUSB_VEND0_PIO_MODE, musb->mregs + SUNXI_MUSB_VEND0); /* Register notifier before calling phy_init() */ - ret = extcon_register_notifier(glue->extcon, EXTCON_USB_HOST, - &glue->host_nb); + ret = devm_extcon_register_notifier(glue->dev, glue->extcon, + EXTCON_USB_HOST, &glue->host_nb); if (ret) goto error_reset_assert; ret = phy_init(glue->phy); if (ret) - goto error_unregister_notifier; + goto error_reset_assert; musb->isr = sunxi_musb_interrupt; @@ -267,9 +267,6 @@ static int sunxi_musb_init(struct musb *musb) return 0; -error_unregister_notifier: - extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, - &glue->host_nb); error_reset_assert: if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) reset_control_assert(glue->rst); @@ -293,9 +290,6 @@ static int sunxi_musb_exit(struct musb *musb) phy_exit(glue->phy); - extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, - &glue->host_nb); - if (test_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags)) reset_control_assert(glue->rst); @@ -645,7 +639,21 @@ static struct musb_fifo_cfg sunxi_musb_mode_cfg[] = { MUSB_EP_FIFO_SINGLE(5, FIFO_RX, 512), }; -static struct musb_hdrc_config sunxi_musb_hdrc_config = { +/* H3/V3s OTG supports only 4 endpoints */ +#define SUNXI_MUSB_MAX_EP_NUM_H3 5 + +static struct musb_fifo_cfg sunxi_musb_mode_cfg_h3[] = { + MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(2, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(3, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(3, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(4, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(4, FIFO_RX, 512), +}; + +static const struct musb_hdrc_config sunxi_musb_hdrc_config = { .fifo_cfg = sunxi_musb_mode_cfg, .fifo_cfg_size = ARRAY_SIZE(sunxi_musb_mode_cfg), .multipoint = true, @@ -656,6 +664,18 @@ static struct musb_hdrc_config sunxi_musb_hdrc_config = { .dma = 0, }; +static struct musb_hdrc_config sunxi_musb_hdrc_config_h3 = { + .fifo_cfg = sunxi_musb_mode_cfg_h3, + .fifo_cfg_size = ARRAY_SIZE(sunxi_musb_mode_cfg_h3), + .multipoint = true, + .dyn_fifo = true, + .soft_con = true, + .num_eps = SUNXI_MUSB_MAX_EP_NUM_H3, + .ram_bits = SUNXI_MUSB_RAM_BITS, + .dma = 0, +}; + + static int sunxi_musb_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data pdata; @@ -698,7 +718,10 @@ static int sunxi_musb_probe(struct platform_device *pdev) return -EINVAL; } pdata.platform_ops = &sunxi_musb_ops; - pdata.config = &sunxi_musb_hdrc_config; + if (!of_device_is_compatible(np, "allwinner,sun8i-h3-musb")) + pdata.config = &sunxi_musb_hdrc_config; + else + pdata.config = &sunxi_musb_hdrc_config_h3; glue->dev = &pdev->dev; INIT_WORK(&glue->work, sunxi_musb_work); @@ -710,7 +733,8 @@ static int sunxi_musb_probe(struct platform_device *pdev) if (of_device_is_compatible(np, "allwinner,sun6i-a31-musb")) set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags); - if (of_device_is_compatible(np, "allwinner,sun8i-a33-musb")) { + if (of_device_is_compatible(np, "allwinner,sun8i-a33-musb") || + of_device_is_compatible(np, "allwinner,sun8i-h3-musb")) { set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags); set_bit(SUNXI_MUSB_FL_NO_CONFIGDATA, &glue->flags); } @@ -804,6 +828,7 @@ static const struct of_device_id sunxi_musb_match[] = { { .compatible = "allwinner,sun4i-a10-musb", }, { .compatible = "allwinner,sun6i-a31-musb", }, { .compatible = "allwinner,sun8i-a33-musb", }, + { .compatible = "allwinner,sun8i-h3-musb", }, {} }; MODULE_DEVICE_TABLE(of, sunxi_musb_match); diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 3eaa4ba6867d..5a572500c418 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -30,7 +30,7 @@ #include "musb_core.h" -static struct musb_hdrc_config ux500_musb_hdrc_config = { +static const struct musb_hdrc_config ux500_musb_hdrc_config = { .multipoint = true, .dyn_fifo = true, .num_eps = 16, |