]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'usb-3.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 23 Feb 2014 18:40:22 +0000 (10:40 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 23 Feb 2014 18:40:22 +0000 (10:40 -0800)
Pull USB fixes from Greg KH:
 "Here are a number of USB fixes for reported issues for 3.14-rc4

  The majority of these are for USB gadget, phy, and musb driver issues.
  And there's a few new device ids thrown in for good measure"

* tag 'usb-3.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: chipidea: need to mask when writting endptflush and endptprime
  usb: musb: correct use of schedule_delayed_work()
  usb: phy: msm: fix compilation errors when !CONFIG_PM_SLEEP
  usb: gadget: fix NULL pointer dereference
  usb: gadget: printer: using gadget_is_otg to check otg support at runtime
  phy: let phy_provider_register be the last step in registering PHY
  phy-core: Don't allow building phy-core as a module
  phy-core: Don't propagate -ENOSUPP from phy_pm_runtime_get_sync to caller
  phy-core: phy_get: Leave error logging to the caller
  phy,phy-bcm-kona-usb2.c: Add dependency on HAS_IOMEM
  usb: musb: correct use of schedule_delayed_work()
  usb: musb: do not sleep in atomic context
  USB: serial: option: blacklist interface 4 for Cinterion PHS8 and PXS8
  USB: EHCI: add delay during suspend to prevent erroneous wakeups
  usb: gadget: bcm63xx_udc: fix build failure on DMA channel code
  usb: musb: do not sleep in atomic context
  usb: gadget: s3c2410_udc: Fix build error
  usb: musb: core: Fix remote-wakeup resume
  usb: musb: host: Fix SuperSpeed hub enumeration
  usb: musb: fix obex in g_nokia.ko causing kernel panic

19 files changed:
drivers/phy/Kconfig
drivers/phy/phy-core.c
drivers/phy/phy-exynos-dp-video.c
drivers/phy/phy-exynos-mipi-video.c
drivers/phy/phy-mvebu-sata.c
drivers/phy/phy-omap-usb2.c
drivers/phy/phy-twl4030-usb.c
drivers/usb/chipidea/udc.c
drivers/usb/gadget/bcm63xx_udc.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/printer.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/host/ehci-hub.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_host.c
drivers/usb/musb/musb_virthub.c
drivers/usb/musb/omap2430.c
drivers/usb/phy/phy-msm-usb.c
drivers/usb/serial/option.c

index afa2354f6600e72d904ea907ee92f775010ae8a9..c7a551c2d5f1b4d39b982d85222537ec3fbfb804 100644 (file)
@@ -5,7 +5,7 @@
 menu "PHY Subsystem"
 
 config GENERIC_PHY
-       tristate "PHY Core"
+       bool "PHY Core"
        help
          Generic PHY support.
 
@@ -61,6 +61,7 @@ config PHY_EXYNOS_DP_VIDEO
 config BCM_KONA_USB2_PHY
        tristate "Broadcom Kona USB2 PHY Driver"
        depends on GENERIC_PHY
+       depends on HAS_IOMEM
        help
          Enable this to support the Broadcom Kona USB 2.0 PHY.
 
index 5f5b0f4be5be3da4e3146f4479d416306f4de9e9..6c738376daff5110a791c3c3f6492ab818971165 100644 (file)
@@ -176,6 +176,8 @@ int phy_init(struct phy *phy)
                        dev_err(&phy->dev, "phy init failed --> %d\n", ret);
                        goto out;
                }
+       } else {
+               ret = 0; /* Override possible ret == -ENOTSUPP */
        }
        ++phy->init_count;
 
@@ -232,6 +234,8 @@ int phy_power_on(struct phy *phy)
                        dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
                        goto out;
                }
+       } else {
+               ret = 0; /* Override possible ret == -ENOTSUPP */
        }
        ++phy->power_count;
        mutex_unlock(&phy->mutex);
@@ -404,17 +408,11 @@ struct phy *phy_get(struct device *dev, const char *string)
                index = of_property_match_string(dev->of_node, "phy-names",
                        string);
                phy = of_phy_get(dev, index);
-               if (IS_ERR(phy)) {
-                       dev_err(dev, "unable to find phy\n");
-                       return phy;
-               }
        } else {
                phy = phy_lookup(dev, string);
-               if (IS_ERR(phy)) {
-                       dev_err(dev, "unable to find phy\n");
-                       return phy;
-               }
        }
+       if (IS_ERR(phy))
+               return phy;
 
        if (!try_module_get(phy->ops->owner))
                return ERR_PTR(-EPROBE_DEFER);
index 1dbe6ce7b2ce795e0a81ec3a632a8b6d6927f2bc..0786fef842e7fd878507d4342074db65b942c47b 100644 (file)
@@ -76,10 +76,6 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
        if (IS_ERR(state->regs))
                return PTR_ERR(state->regs);
 
-       phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-       if (IS_ERR(phy_provider))
-               return PTR_ERR(phy_provider);
-
        phy = devm_phy_create(dev, &exynos_dp_video_phy_ops, NULL);
        if (IS_ERR(phy)) {
                dev_err(dev, "failed to create Display Port PHY\n");
@@ -87,6 +83,10 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
        }
        phy_set_drvdata(phy, state);
 
+       phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
+
        return 0;
 }
 
index 0c5efab11af18a5b2b7367014747e0b34984b585..7f139326a6424e8b38d5fdd9049f26d85e679e6c 100644 (file)
@@ -134,11 +134,6 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
        dev_set_drvdata(dev, state);
        spin_lock_init(&state->slock);
 
-       phy_provider = devm_of_phy_provider_register(dev,
-                                       exynos_mipi_video_phy_xlate);
-       if (IS_ERR(phy_provider))
-               return PTR_ERR(phy_provider);
-
        for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
                struct phy *phy = devm_phy_create(dev,
                                        &exynos_mipi_video_phy_ops, NULL);
@@ -152,6 +147,11 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
                phy_set_drvdata(phy, &state->phys[i]);
        }
 
+       phy_provider = devm_of_phy_provider_register(dev,
+                                       exynos_mipi_video_phy_xlate);
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
+
        return 0;
 }
 
index d43786f6243742ed378fb1b7d3c6756fd111381d..d70ecd6a1b3f51e60077559159912e2564e6b1a1 100644 (file)
@@ -99,17 +99,17 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev)
        if (IS_ERR(priv->clk))
                return PTR_ERR(priv->clk);
 
-       phy_provider = devm_of_phy_provider_register(&pdev->dev,
-                                                    of_phy_simple_xlate);
-       if (IS_ERR(phy_provider))
-               return PTR_ERR(phy_provider);
-
        phy = devm_phy_create(&pdev->dev, &phy_mvebu_sata_ops, NULL);
        if (IS_ERR(phy))
                return PTR_ERR(phy);
 
        phy_set_drvdata(phy, priv);
 
+       phy_provider = devm_of_phy_provider_register(&pdev->dev,
+                                                    of_phy_simple_xlate);
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
+
        /* The boot loader may of left it on. Turn it off. */
        phy_mvebu_sata_power_off(phy);
 
index bfc5c337f99a8178278d9aa8f0b9b7be74f41889..7699752fba11bfbfa8acff589d794262d2882cc4 100644 (file)
@@ -177,11 +177,6 @@ static int omap_usb2_probe(struct platform_device *pdev)
        phy->phy.otg            = otg;
        phy->phy.type           = USB_PHY_TYPE_USB2;
 
-       phy_provider = devm_of_phy_provider_register(phy->dev,
-                       of_phy_simple_xlate);
-       if (IS_ERR(phy_provider))
-               return PTR_ERR(phy_provider);
-
        control_node = of_parse_phandle(node, "ctrl-module", 0);
        if (!control_node) {
                dev_err(&pdev->dev, "Failed to get control device phandle\n");
@@ -214,6 +209,11 @@ static int omap_usb2_probe(struct platform_device *pdev)
 
        phy_set_drvdata(generic_phy, phy);
 
+       phy_provider = devm_of_phy_provider_register(phy->dev,
+                       of_phy_simple_xlate);
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
+
        phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
        if (IS_ERR(phy->wkupclk)) {
                dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
index daf65e68aaab53c663847e05d2dcf1fbdb035544..c3ace1db8136eedef379691bc6fa532b4ff5d67c 100644 (file)
@@ -695,11 +695,6 @@ static int twl4030_usb_probe(struct platform_device *pdev)
        otg->set_host           = twl4030_set_host;
        otg->set_peripheral     = twl4030_set_peripheral;
 
-       phy_provider = devm_of_phy_provider_register(twl->dev,
-               of_phy_simple_xlate);
-       if (IS_ERR(phy_provider))
-               return PTR_ERR(phy_provider);
-
        phy = devm_phy_create(twl->dev, &ops, init_data);
        if (IS_ERR(phy)) {
                dev_dbg(&pdev->dev, "Failed to create PHY\n");
@@ -708,6 +703,11 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 
        phy_set_drvdata(phy, twl);
 
+       phy_provider = devm_of_phy_provider_register(twl->dev,
+               of_phy_simple_xlate);
+       if (IS_ERR(phy_provider))
+               return PTR_ERR(phy_provider);
+
        /* init spinlock for workqueue */
        spin_lock_init(&twl->lock);
 
index 80de2f88ed2c7852fdd38bec785e6d5681cbe310..4ab2cb62dfce4c1b3dfe140ef83f20d4633b9ff0 100644 (file)
@@ -105,7 +105,7 @@ static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir)
 
        do {
                /* flush any pending transfer */
-               hw_write(ci, OP_ENDPTFLUSH, BIT(n), BIT(n));
+               hw_write(ci, OP_ENDPTFLUSH, ~0, BIT(n));
                while (hw_read(ci, OP_ENDPTFLUSH, BIT(n)))
                        cpu_relax();
        } while (hw_read(ci, OP_ENDPTSTAT, BIT(n)));
@@ -205,7 +205,7 @@ static int hw_ep_prime(struct ci_hdrc *ci, int num, int dir, int is_ctrl)
        if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num)))
                return -EAGAIN;
 
-       hw_write(ci, OP_ENDPTPRIME, BIT(n), BIT(n));
+       hw_write(ci, OP_ENDPTPRIME, ~0, BIT(n));
 
        while (hw_read(ci, OP_ENDPTPRIME, BIT(n)))
                cpu_relax();
index 888fbb43b338ecebcaf7cf8cb267fb2de35cc240..e969eb809a853dbb38093a0f5d3d39f57f931bb7 100644 (file)
@@ -360,24 +360,30 @@ static inline void usb_dma_writel(struct bcm63xx_udc *udc, u32 val, u32 off)
        bcm_writel(val, udc->iudma_regs + off);
 }
 
-static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off)
+static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off, int chan)
 {
-       return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off);
+       return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off +
+                       (ENETDMA_CHAN_WIDTH * chan));
 }
 
-static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off)
+static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off,
+                                       int chan)
 {
-       bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off);
+       bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off +
+                       (ENETDMA_CHAN_WIDTH * chan));
 }
 
-static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off)
+static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off, int chan)
 {
-       return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off);
+       return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off +
+                       (ENETDMA_CHAN_WIDTH * chan));
 }
 
-static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off)
+static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off,
+                                       int chan)
 {
-       bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off);
+       bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off +
+                       (ENETDMA_CHAN_WIDTH * chan));
 }
 
 static inline void set_clocks(struct bcm63xx_udc *udc, bool is_enabled)
@@ -638,7 +644,7 @@ static void iudma_write(struct bcm63xx_udc *udc, struct iudma_ch *iudma,
        } while (!last_bd);
 
        usb_dmac_writel(udc, ENETDMAC_CHANCFG_EN_MASK,
-                       ENETDMAC_CHANCFG_REG(iudma->ch_idx));
+                       ENETDMAC_CHANCFG_REG, iudma->ch_idx);
 }
 
 /**
@@ -694,9 +700,9 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma)
                bcm63xx_fifo_reset_ep(udc, max(0, iudma->ep_num));
 
        /* stop DMA, then wait for the hardware to wrap up */
-       usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG(ch_idx));
+       usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG, ch_idx);
 
-       while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)) &
+       while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx) &
                                   ENETDMAC_CHANCFG_EN_MASK) {
                udelay(1);
 
@@ -713,10 +719,10 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma)
                        dev_warn(udc->dev, "forcibly halting IUDMA channel %d\n",
                                 ch_idx);
                        usb_dmac_writel(udc, ENETDMAC_CHANCFG_BUFHALT_MASK,
-                                       ENETDMAC_CHANCFG_REG(ch_idx));
+                                       ENETDMAC_CHANCFG_REG, ch_idx);
                }
        }
-       usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG(ch_idx));
+       usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG, ch_idx);
 
        /* don't leave "live" HW-owned entries for the next guy to step on */
        for (d = iudma->bd_ring; d <= iudma->end_bd; d++)
@@ -728,11 +734,11 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma)
 
        /* set up IRQs, UBUS burst size, and BD base for this channel */
        usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK,
-                       ENETDMAC_IRMASK_REG(ch_idx));
-       usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG(ch_idx));
+                       ENETDMAC_IRMASK_REG, ch_idx);
+       usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG, ch_idx);
 
-       usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG(ch_idx));
-       usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG(ch_idx));
+       usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG, ch_idx);
+       usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG, ch_idx);
 }
 
 /**
@@ -2035,7 +2041,7 @@ static irqreturn_t bcm63xx_udc_data_isr(int irq, void *dev_id)
        spin_lock(&udc->lock);
 
        usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK,
-                       ENETDMAC_IR_REG(iudma->ch_idx));
+                       ENETDMAC_IR_REG, iudma->ch_idx);
        bep = iudma->bep;
        rc = iudma_read(udc, iudma);
 
@@ -2175,18 +2181,18 @@ static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p)
                seq_printf(s, " [ep%d]:\n",
                           max_t(int, iudma_defaults[ch_idx].ep_num, 0));
                seq_printf(s, "  cfg: %08x; irqstat: %08x; irqmask: %08x; maxburst: %08x\n",
-                          usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)),
-                          usb_dmac_readl(udc, ENETDMAC_IR_REG(ch_idx)),
-                          usb_dmac_readl(udc, ENETDMAC_IRMASK_REG(ch_idx)),
-                          usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG(ch_idx)));
+                          usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx),
+                          usb_dmac_readl(udc, ENETDMAC_IR_REG, ch_idx),
+                          usb_dmac_readl(udc, ENETDMAC_IRMASK_REG, ch_idx),
+                          usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG, ch_idx));
 
-               sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG(ch_idx));
-               sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG(ch_idx));
+               sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG, ch_idx);
+               sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG, ch_idx);
                seq_printf(s, "  base: %08x; index: %04x_%04x; desc: %04x_%04x %08x\n",
-                          usb_dmas_readl(udc, ENETDMAS_RSTART_REG(ch_idx)),
+                          usb_dmas_readl(udc, ENETDMAS_RSTART_REG, ch_idx),
                           sram2 >> 16, sram2 & 0xffff,
                           sram3 >> 16, sram3 & 0xffff,
-                          usb_dmas_readl(udc, ENETDMAS_SRAM4_REG(ch_idx)));
+                          usb_dmas_readl(udc, ENETDMAS_SRAM4_REG, ch_idx));
                seq_printf(s, "  desc: %d/%d used", iudma->n_bds_used,
                           iudma->n_bds);
 
index 306a2b52125c8e7ee2eba91bcf1156e689ae133e..2b43343940766251ee5f274b807b882273f09008 100644 (file)
@@ -585,7 +585,6 @@ static ssize_t ffs_epfile_io(struct file *file,
                             char __user *buf, size_t len, int read)
 {
        struct ffs_epfile *epfile = file->private_data;
-       struct usb_gadget *gadget = epfile->ffs->gadget;
        struct ffs_ep *ep;
        char *data = NULL;
        ssize_t ret, data_len;
@@ -621,6 +620,12 @@ static ssize_t ffs_epfile_io(struct file *file,
 
        /* Allocate & copy */
        if (!halt) {
+               /*
+                * if we _do_ wait above, the epfile->ffs->gadget might be NULL
+                * before the waiting completes, so do not assign to 'gadget' earlier
+                */
+               struct usb_gadget *gadget = epfile->ffs->gadget;
+
                /*
                 * Controller may require buffer size to be aligned to
                 * maxpacketsize of an out endpoint.
index bf7a56b6d48ac2c3ebb3acf8920c70d79900d307..69b76efd11e9bea3f11d9d2effe293c04045f01c 100644 (file)
@@ -1157,7 +1157,7 @@ static int __init printer_bind_config(struct usb_configuration *c)
 
        usb_gadget_set_selfpowered(gadget);
 
-       if (gadget->is_otg) {
+       if (gadget_is_otg(gadget)) {
                otg_descriptor.bmAttributes |= USB_OTG_HNP;
                printer_cfg_driver.descriptors = otg_desc;
                printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
index f04b2c3154dea73b0fa2c1d93322bdbf1c5930bc..dd9678f85c586a591b2a6514ba71034895d1769d 100644 (file)
@@ -1629,7 +1629,7 @@ static void s3c2410_udc_reinit(struct s3c2410_udc *dev)
                ep->ep.desc = NULL;
                ep->halted = 0;
                INIT_LIST_HEAD(&ep->queue);
-               usb_ep_set_maxpacket_limit(&ep->ep, &ep->ep.maxpacket);
+               usb_ep_set_maxpacket_limit(&ep->ep, ep->ep.maxpacket);
        }
 }
 
index 47b858fc50b2ee484c035cef8fe8b27c669009b5..7ae0c4d517417d46dbc2dd8f51993728fa839c3a 100644 (file)
@@ -238,6 +238,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        int                     port;
        int                     mask;
        int                     changed;
+       bool                    fs_idle_delay;
 
        ehci_dbg(ehci, "suspend root hub\n");
 
@@ -272,6 +273,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        ehci->bus_suspended = 0;
        ehci->owned_ports = 0;
        changed = 0;
+       fs_idle_delay = false;
        port = HCS_N_PORTS(ehci->hcs_params);
        while (port--) {
                u32 __iomem     *reg = &ehci->regs->port_status [port];
@@ -300,16 +302,32 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
                }
 
                if (t1 != t2) {
+                       /*
+                        * On some controllers, Wake-On-Disconnect will
+                        * generate false wakeup signals until the bus
+                        * switches over to full-speed idle.  For their
+                        * sake, add a delay if we need one.
+                        */
+                       if ((t2 & PORT_WKDISC_E) &&
+                                       ehci_port_speed(ehci, t2) ==
+                                               USB_PORT_STAT_HIGH_SPEED)
+                               fs_idle_delay = true;
                        ehci_writel(ehci, t2, reg);
                        changed = 1;
                }
        }
+       spin_unlock_irq(&ehci->lock);
+
+       if ((changed && ehci->has_tdi_phy_lpm) || fs_idle_delay) {
+               /*
+                * Wait for HCD to enter low-power mode or for the bus
+                * to switch to full-speed idle.
+                */
+               usleep_range(5000, 5500);
+       }
 
        if (changed && ehci->has_tdi_phy_lpm) {
-               spin_unlock_irq(&ehci->lock);
-               msleep(5);      /* 5 ms for HCD to enter low-power mode */
                spin_lock_irq(&ehci->lock);
-
                port = HCS_N_PORTS(ehci->hcs_params);
                while (port--) {
                        u32 __iomem     *hostpc_reg = &ehci->regs->hostpc[port];
@@ -322,8 +340,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
                                        port, (t3 & HOSTPC_PHCD) ?
                                        "succeeded" : "failed");
                }
+               spin_unlock_irq(&ehci->lock);
        }
-       spin_unlock_irq(&ehci->lock);
 
        /* Apparently some devices need a >= 1-uframe delay here */
        if (ehci->bus_suspended)
index fc192ad9cc6a60eb4a7f00d124eb0a0d1bca73fe..239ad0b1ceb6d15ddff5fa3741ca97796e70e067 100644 (file)
@@ -477,8 +477,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
                                musb->port1_status |=
                                                (USB_PORT_STAT_C_SUSPEND << 16)
                                                | MUSB_PORT_STAT_RESUME;
+                               musb->rh_timer = jiffies
+                                                + msecs_to_jiffies(20);
                                schedule_delayed_work(
-                                       &musb->finish_resume_work, 20);
+                                       &musb->finish_resume_work,
+                                       msecs_to_jiffies(20));
 
                                musb->xceiv->state = OTG_STATE_A_HOST;
                                musb->is_active = 1;
@@ -2157,11 +2160,19 @@ static void musb_restore_context(struct musb *musb)
        void __iomem *musb_base = musb->mregs;
        void __iomem *ep_target_regs;
        void __iomem *epio;
+       u8 power;
 
        musb_writew(musb_base, MUSB_FRAME, musb->context.frame);
        musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode);
        musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl);
-       musb_writeb(musb_base, MUSB_POWER, musb->context.power);
+
+       /* Don't affect SUSPENDM/RESUME bits in POWER reg */
+       power = musb_readb(musb_base, MUSB_POWER);
+       power &= MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME;
+       musb->context.power &= ~(MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME);
+       power |= musb->context.power;
+       musb_writeb(musb_base, MUSB_POWER, power);
+
        musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe);
        musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe);
        musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe);
index ed455724017b5767f6ad849961946d7ad7af3228..abb38c3833ef46a1f8041c8a5f95fa96138b1796 100644 (file)
@@ -1183,6 +1183,9 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
                                csr = MUSB_CSR0_H_STATUSPKT
                                        | MUSB_CSR0_TXPKTRDY;
 
+                       /* disable ping token in status phase */
+                       csr |= MUSB_CSR0_H_DIS_PING;
+
                        /* flag status stage */
                        musb->ep0_stage = MUSB_EP0_STATUS;
 
index eb634433ef095b631cd7e70df77453334cf48ddc..e2d2d8c9891bc1f7a4cf5f8a16048d58a3d4c630 100644 (file)
@@ -135,7 +135,8 @@ void musb_port_suspend(struct musb *musb, bool do_suspend)
 
                /* later, GetPortStatus will stop RESUME signaling */
                musb->port1_status |= MUSB_PORT_STAT_RESUME;
-               schedule_delayed_work(&musb->finish_resume_work, 20);
+               schedule_delayed_work(&musb->finish_resume_work,
+                                     msecs_to_jiffies(20));
        }
 }
 
@@ -158,7 +159,6 @@ void musb_port_reset(struct musb *musb, bool do_reset)
         */
        power = musb_readb(mbase, MUSB_POWER);
        if (do_reset) {
-
                /*
                 * If RESUME is set, we must make sure it stays minimum 20 ms.
                 * Then we must clear RESUME and wait a bit to let musb start
@@ -167,11 +167,22 @@ void musb_port_reset(struct musb *musb, bool do_reset)
                 * detected".
                 */
                if (power &  MUSB_POWER_RESUME) {
-                       while (time_before(jiffies, musb->rh_timer))
-                               msleep(1);
+                       long remain = (unsigned long) musb->rh_timer - jiffies;
+
+                       if (musb->rh_timer > 0 && remain > 0) {
+                               /* take into account the minimum delay after resume */
+                               schedule_delayed_work(
+                                       &musb->deassert_reset_work, remain);
+                               return;
+                       }
+
                        musb_writeb(mbase, MUSB_POWER,
-                               power & ~MUSB_POWER_RESUME);
-                       msleep(1);
+                                   power & ~MUSB_POWER_RESUME);
+
+                       /* Give the core 1 ms to clear MUSB_POWER_RESUME */
+                       schedule_delayed_work(&musb->deassert_reset_work,
+                                             msecs_to_jiffies(1));
+                       return;
                }
 
                power &= 0xf0;
@@ -180,7 +191,8 @@ void musb_port_reset(struct musb *musb, bool do_reset)
 
                musb->port1_status |= USB_PORT_STAT_RESET;
                musb->port1_status &= ~USB_PORT_STAT_ENABLE;
-               schedule_delayed_work(&musb->deassert_reset_work, 50);
+               schedule_delayed_work(&musb->deassert_reset_work,
+                                     msecs_to_jiffies(50));
        } else {
                dev_dbg(musb->controller, "root port reset stopped\n");
                musb_writeb(mbase, MUSB_POWER,
index 2a408cdaf7b2c7102098faac6d29727505f41c91..8aa59a2c5eb2485c823244012cc738ce5df7d127 100644 (file)
@@ -659,7 +659,6 @@ static int omap2430_runtime_suspend(struct device *dev)
                                OTG_INTERFSEL);
 
                omap2430_low_level_exit(musb);
-               phy_power_off(musb->phy);
        }
 
        return 0;
@@ -674,7 +673,6 @@ 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);
        }
 
        return 0;
index 8546c8dccd51b003fc9aba3038184cd2d0eedbea..d204f745ed05e652ef168940dece89e2e16a8269 100644 (file)
@@ -159,32 +159,6 @@ put_3p3:
        return rc;
 }
 
-#ifdef CONFIG_PM_SLEEP
-#define USB_PHY_SUSP_DIG_VOL  500000
-static int msm_hsusb_config_vddcx(int high)
-{
-       int max_vol = USB_PHY_VDD_DIG_VOL_MAX;
-       int min_vol;
-       int ret;
-
-       if (high)
-               min_vol = USB_PHY_VDD_DIG_VOL_MIN;
-       else
-               min_vol = USB_PHY_SUSP_DIG_VOL;
-
-       ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol);
-       if (ret) {
-               pr_err("%s: unable to set the voltage for regulator "
-                       "HSUSB_VDDCX\n", __func__);
-               return ret;
-       }
-
-       pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol);
-
-       return ret;
-}
-#endif
-
 static int msm_hsusb_ldo_set_mode(int on)
 {
        int ret = 0;
@@ -440,7 +414,32 @@ static int msm_otg_reset(struct usb_phy *phy)
 #define PHY_SUSPEND_TIMEOUT_USEC       (500 * 1000)
 #define PHY_RESUME_TIMEOUT_USEC        (100 * 1000)
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
+
+#define USB_PHY_SUSP_DIG_VOL  500000
+static int msm_hsusb_config_vddcx(int high)
+{
+       int max_vol = USB_PHY_VDD_DIG_VOL_MAX;
+       int min_vol;
+       int ret;
+
+       if (high)
+               min_vol = USB_PHY_VDD_DIG_VOL_MIN;
+       else
+               min_vol = USB_PHY_SUSP_DIG_VOL;
+
+       ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol);
+       if (ret) {
+               pr_err("%s: unable to set the voltage for regulator "
+                       "HSUSB_VDDCX\n", __func__);
+               return ret;
+       }
+
+       pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol);
+
+       return ret;
+}
+
 static int msm_otg_suspend(struct msm_otg *motg)
 {
        struct usb_phy *phy = &motg->phy;
@@ -1733,22 +1732,18 @@ static int msm_otg_pm_resume(struct device *dev)
 }
 #endif
 
-#ifdef CONFIG_PM
 static const struct dev_pm_ops msm_otg_dev_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume)
        SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume,
                                msm_otg_runtime_idle)
 };
-#endif
 
 static struct platform_driver msm_otg_driver = {
        .remove = msm_otg_remove,
        .driver = {
                .name = DRIVER_NAME,
                .owner = THIS_MODULE,
-#ifdef CONFIG_PM
                .pm = &msm_otg_dev_pm_ops,
-#endif
        },
 };
 
index 216d20affba82741e0430989e19da8a54a492037..68fc9fe65936e712ba08e9f6825de4773b4cc9a9 100644 (file)
@@ -1526,7 +1526,8 @@ static const struct usb_device_id option_ids[] = {
        /* Cinterion */
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
-       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8),
+               .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX),
                .driver_info = (kernel_ulong_t)&net_intf4_blacklist },