]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Apr 2012 18:13:50 +0000 (11:13 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Apr 2012 18:13:50 +0000 (11:13 -0700)
added patches:
usb-gadget-pch_udc-fix-disconnect-issue.patch
usb-gadget-pch_udc-fix-usb-gadget-pch_udc-fix-ether.patch
usb-gadget-pch_udc-fix-usb-suspend-issue.patch
usb-gadget-pch_udc-fix-wrong-return-value.patch
usb-gadget-pch_udc-reduce-redundant-interrupt.patch

queue-3.3/series
queue-3.3/usb-gadget-pch_udc-fix-disconnect-issue.patch [new file with mode: 0644]
queue-3.3/usb-gadget-pch_udc-fix-usb-gadget-pch_udc-fix-ether.patch [new file with mode: 0644]
queue-3.3/usb-gadget-pch_udc-fix-usb-suspend-issue.patch [new file with mode: 0644]
queue-3.3/usb-gadget-pch_udc-fix-wrong-return-value.patch [new file with mode: 0644]
queue-3.3/usb-gadget-pch_udc-reduce-redundant-interrupt.patch [new file with mode: 0644]

index 6569d8e833788718269372dab06fe9f8911bcb96..d4bb679fb5c6c160a8ecff5b4bbe5de77ca1710b 100644 (file)
@@ -59,3 +59,8 @@ serial-pl011-clear-pending-interrupts.patch
 serial-pl011-move-interrupt-clearing.patch
 fcaps-clear-the-same-personality-flags-as-suid-when-fcaps-are-used.patch
 xhci-fix-register-save-restore-order.patch
+usb-gadget-pch_udc-fix-disconnect-issue.patch
+usb-gadget-pch_udc-fix-wrong-return-value.patch
+usb-gadget-pch_udc-fix-usb-suspend-issue.patch
+usb-gadget-pch_udc-fix-usb-gadget-pch_udc-fix-ether.patch
+usb-gadget-pch_udc-reduce-redundant-interrupt.patch
diff --git a/queue-3.3/usb-gadget-pch_udc-fix-disconnect-issue.patch b/queue-3.3/usb-gadget-pch_udc-fix-disconnect-issue.patch
new file mode 100644 (file)
index 0000000..499d869
--- /dev/null
@@ -0,0 +1,40 @@
+From c50a3bff0edb0acd49d8033a12ea4668e09a31ad Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Date: Thu, 12 Jan 2012 11:27:05 +0900
+Subject: usb: gadget: pch_udc: Fix disconnect issue
+
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+
+commit c50a3bff0edb0acd49d8033a12ea4668e09a31ad upstream.
+
+ISSUE:
+When the driver notifies a gadget of a disconnect event, a system
+rarely freezes.
+
+CAUSE:
+When the driver calls dev->driver->disconnect(), it is not calling
+spin_unlock().
+
+Signed-off-by: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/pch_udc.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/pch_udc.c
++++ b/drivers/usb/gadget/pch_udc.c
+@@ -2336,8 +2336,11 @@ static void pch_udc_svc_ur_interrupt(str
+               /* Complete request queue */
+               empty_req_queue(ep);
+       }
+-      if (dev->driver && dev->driver->disconnect)
++      if (dev->driver && dev->driver->disconnect) {
++              spin_unlock(&dev->lock);
+               dev->driver->disconnect(&dev->gadget);
++              spin_lock(&dev->lock);
++      }
+ }
+ /**
diff --git a/queue-3.3/usb-gadget-pch_udc-fix-usb-gadget-pch_udc-fix-ether.patch b/queue-3.3/usb-gadget-pch_udc-fix-usb-gadget-pch_udc-fix-ether.patch
new file mode 100644 (file)
index 0000000..f09fa87
--- /dev/null
@@ -0,0 +1,150 @@
+From 1c575d2d2e3ff2a7cb3c2e2165064199cfd8ad32 Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Date: Thu, 12 Jan 2012 11:27:08 +0900
+Subject: usb: gadget: pch_udc: Fix usb/gadget/pch_udc: Fix ether gadget connect/disconnect issue
+
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+
+commit 1c575d2d2e3ff2a7cb3c2e2165064199cfd8ad32 upstream.
+
+ISSUE:
+After a USB cable is connect/disconnected, the system rarely freezes.
+
+CAUSE:
+Since the USB device controller cannot know to disconnect the USB cable, when
+it is used without detecting VBUS by GPIO, the UDC driver does not notify to
+USB Gadget.
+
+Since USB Gadget cannot know to disconnect, a false setting occurred when the
+USB cable is connected/disconnect repeatedly.
+
+Signed-off-by: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/pch_udc.c |   70 ++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 66 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/gadget/pch_udc.c
++++ b/drivers/usb/gadget/pch_udc.c
+@@ -311,6 +311,7 @@ struct pch_udc_ep {
+  * @registered:               driver regsitered with system
+  * @suspended:                driver in suspended state
+  * @connected:                gadget driver associated
++ * @vbus_session:     required vbus_session state
+  * @set_cfg_not_acked:        pending acknowledgement 4 setup
+  * @waiting_zlp_ack:  pending acknowledgement 4 ZLP
+  * @data_requests:    DMA pool for data requests
+@@ -337,6 +338,7 @@ struct pch_udc_dev {
+                       registered:1,
+                       suspended:1,
+                       connected:1,
++                      vbus_session:1,
+                       set_cfg_not_acked:1,
+                       waiting_zlp_ack:1;
+       struct pci_pool         *data_requests;
+@@ -554,6 +556,31 @@ static void pch_udc_clear_disconnect(str
+ }
+ /**
++ * pch_udc_reconnect() - This API initializes usb device controller,
++ *                                            and clear the disconnect status.
++ * @dev:              Reference to pch_udc_regs structure
++ */
++static void pch_udc_init(struct pch_udc_dev *dev);
++static void pch_udc_reconnect(struct pch_udc_dev *dev)
++{
++      pch_udc_init(dev);
++
++      /* enable device interrupts */
++      /* pch_udc_enable_interrupts() */
++      pch_udc_bit_clr(dev, UDC_DEVIRQMSK_ADDR,
++                      UDC_DEVINT_UR | UDC_DEVINT_US |
++                      UDC_DEVINT_ENUM |
++                      UDC_DEVINT_SI | UDC_DEVINT_SC);
++
++      /* Clear the disconnect */
++      pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES);
++      pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_SD);
++      mdelay(1);
++      /* Resume USB signalling */
++      pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES);
++}
++
++/**
+  * pch_udc_vbus_session() - set or clearr the disconnect status.
+  * @dev:      Reference to pch_udc_regs structure
+  * @is_active:        Parameter specifying the action
+@@ -563,10 +590,18 @@ static void pch_udc_clear_disconnect(str
+ static inline void pch_udc_vbus_session(struct pch_udc_dev *dev,
+                                         int is_active)
+ {
+-      if (is_active)
+-              pch_udc_clear_disconnect(dev);
+-      else
++      if (is_active) {
++              pch_udc_reconnect(dev);
++              dev->vbus_session = 1;
++      } else {
++              if (dev->driver && dev->driver->disconnect) {
++                      spin_unlock(&dev->lock);
++                      dev->driver->disconnect(&dev->gadget);
++                      spin_lock(&dev->lock);
++              }
+               pch_udc_set_disconnect(dev);
++              dev->vbus_session = 0;
++      }
+ }
+ /**
+@@ -1126,7 +1161,17 @@ static int pch_udc_pcd_pullup(struct usb
+       if (!gadget)
+               return -EINVAL;
+       dev = container_of(gadget, struct pch_udc_dev, gadget);
+-      pch_udc_vbus_session(dev, is_on);
++      if (is_on) {
++              pch_udc_reconnect(dev);
++      } else {
++              if (dev->driver && dev->driver->disconnect) {
++                      spin_unlock(&dev->lock);
++                      dev->driver->disconnect(&dev->gadget);
++                      spin_lock(&dev->lock);
++              }
++              pch_udc_set_disconnect(dev);
++      }
++
+       return 0;
+ }
+@@ -2483,6 +2528,15 @@ static void pch_udc_dev_isr(struct pch_u
+                       dev->driver->suspend(&dev->gadget);
+                       spin_lock(&dev->lock);
+               }
++
++              if (dev->vbus_session == 0) {
++                      if (dev->driver && dev->driver->disconnect) {
++                              spin_unlock(&dev->lock);
++                              dev->driver->disconnect(&dev->gadget);
++                              spin_lock(&dev->lock);
++                      }
++                      pch_udc_reconnect(dev);
++              }
+               dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n");
+       }
+       /* Clear the SOF interrupt, if enabled */
+@@ -2510,6 +2564,14 @@ static irqreturn_t pch_udc_isr(int irq,
+       dev_intr = pch_udc_read_device_interrupts(dev);
+       ep_intr = pch_udc_read_ep_interrupts(dev);
++      /* For a hot plug, this find that the controller is hung up. */
++      if (dev_intr == ep_intr)
++              if (dev_intr == pch_udc_readl(dev, UDC_DEVCFG_ADDR)) {
++                      dev_dbg(&dev->pdev->dev, "UDC: Hung up\n");
++                      /* The controller is reset */
++                      pch_udc_writel(dev, UDC_SRST, UDC_SRST_ADDR);
++                      return IRQ_HANDLED;
++              }
+       if (dev_intr)
+               /* Clear device interrupts */
+               pch_udc_write_device_interrupts(dev, dev_intr);
diff --git a/queue-3.3/usb-gadget-pch_udc-fix-usb-suspend-issue.patch b/queue-3.3/usb-gadget-pch_udc-fix-usb-suspend-issue.patch
new file mode 100644 (file)
index 0000000..ac91d87
--- /dev/null
@@ -0,0 +1,43 @@
+From 84566abba058b2aae8d603dfa90b5a3778a6714f Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Date: Thu, 12 Jan 2012 11:27:07 +0900
+Subject: usb: gadget: pch_udc: Fix USB suspend issue
+
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+
+commit 84566abba058b2aae8d603dfa90b5a3778a6714f upstream.
+
+ISSUE:
+After USB Suspend, a system rarely freezes.
+
+CAUSE:
+When USB Suspend occurred, the driver is not notifying
+a gadget of the event.
+
+Signed-off-by: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/pch_udc.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/pch_udc.c
++++ b/drivers/usb/gadget/pch_udc.c
+@@ -2476,8 +2476,15 @@ static void pch_udc_dev_isr(struct pch_u
+       if (dev_intr & UDC_DEVINT_SC)
+               pch_udc_svc_cfg_interrupt(dev);
+       /* USB Suspend interrupt */
+-      if (dev_intr & UDC_DEVINT_US)
++      if (dev_intr & UDC_DEVINT_US) {
++              if (dev->driver
++                      && dev->driver->suspend) {
++                      spin_unlock(&dev->lock);
++                      dev->driver->suspend(&dev->gadget);
++                      spin_lock(&dev->lock);
++              }
+               dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n");
++      }
+       /* Clear the SOF interrupt, if enabled */
+       if (dev_intr & UDC_DEVINT_SOF)
+               dev_dbg(&dev->pdev->dev, "SOF\n");
diff --git a/queue-3.3/usb-gadget-pch_udc-fix-wrong-return-value.patch b/queue-3.3/usb-gadget-pch_udc-fix-wrong-return-value.patch
new file mode 100644 (file)
index 0000000..682a360
--- /dev/null
@@ -0,0 +1,40 @@
+From c802672cd36cd063bfd54d54c8c34825ab5b2357 Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Date: Thu, 12 Jan 2012 11:27:06 +0900
+Subject: usb: gadget: pch_udc: Fix wrong return value
+
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+
+commit c802672cd36cd063bfd54d54c8c34825ab5b2357 upstream.
+
+ISSUE:
+If the return value of pch_udc_pcd_init() is False, the return value of
+this function is unsettled.
+Since pch_udc_pcd_init() always returns 0, there is not actually the issue.
+
+CAUSE:
+If pch_udc_pcd_init() is True, the variable, retval, is not set for an
+appropriate value.
+
+Signed-off-by: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/pch_udc.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/pch_udc.c
++++ b/drivers/usb/gadget/pch_udc.c
+@@ -2916,8 +2916,10 @@ static int pch_udc_probe(struct pci_dev
+       }
+       pch_udc = dev;
+       /* initialize the hardware */
+-      if (pch_udc_pcd_init(dev))
++      if (pch_udc_pcd_init(dev)) {
++              retval = -ENODEV;
+               goto finished;
++      }
+       if (request_irq(pdev->irq, pch_udc_isr, IRQF_SHARED, KBUILD_MODNAME,
+                       dev)) {
+               dev_err(&pdev->dev, "%s: request_irq(%d) fail\n", __func__,
diff --git a/queue-3.3/usb-gadget-pch_udc-reduce-redundant-interrupt.patch b/queue-3.3/usb-gadget-pch_udc-reduce-redundant-interrupt.patch
new file mode 100644 (file)
index 0000000..01e94a0
--- /dev/null
@@ -0,0 +1,53 @@
+From 833310402c54ad9b676b465fc53ad276b13d36be Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Date: Thu, 12 Jan 2012 11:27:09 +0900
+Subject: usb: gadget: pch_udc: Reduce redundant interrupt
+
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+
+commit 833310402c54ad9b676b465fc53ad276b13d36be upstream.
+
+ISSUE:
+USB Suspend interrupts occur frequently.
+
+CAUSE:
+When it is called pch_udc_reconnect() in USB Suspend, it repeats reset and
+Suspend.
+
+SOLUTION:
+pch_udc_reconnect() does not enable all interrupts.  When an enumeration event
+occurred the driver enables all interrupts.
+
+Signed-off-by: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/pch_udc.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/gadget/pch_udc.c
++++ b/drivers/usb/gadget/pch_udc.c
+@@ -568,9 +568,7 @@ static void pch_udc_reconnect(struct pch
+       /* enable device interrupts */
+       /* pch_udc_enable_interrupts() */
+       pch_udc_bit_clr(dev, UDC_DEVIRQMSK_ADDR,
+-                      UDC_DEVINT_UR | UDC_DEVINT_US |
+-                      UDC_DEVINT_ENUM |
+-                      UDC_DEVINT_SI | UDC_DEVINT_SC);
++                      UDC_DEVINT_UR | UDC_DEVINT_ENUM);
+       /* Clear the disconnect */
+       pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES);
+@@ -2420,6 +2418,11 @@ static void pch_udc_svc_enum_interrupt(s
+       pch_udc_set_dma(dev, DMA_DIR_TX);
+       pch_udc_set_dma(dev, DMA_DIR_RX);
+       pch_udc_ep_set_rrdy(&(dev->ep[UDC_EP0OUT_IDX]));
++
++      /* enable device interrupts */
++      pch_udc_enable_interrupts(dev, UDC_DEVINT_UR | UDC_DEVINT_US |
++                                      UDC_DEVINT_ES | UDC_DEVINT_ENUM |
++                                      UDC_DEVINT_SI | UDC_DEVINT_SC);
+ }
+ /**