aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r--drivers/usb/host/ohci-hcd.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index ce05e5f7bed6..44717fab7435 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -35,6 +35,7 @@
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/dmapool.h> 36#include <linux/dmapool.h>
37#include <linux/reboot.h> 37#include <linux/reboot.h>
38#include <linux/workqueue.h>
38 39
39#include <asm/io.h> 40#include <asm/io.h>
40#include <asm/irq.h> 41#include <asm/irq.h>
@@ -82,6 +83,8 @@ static const char hcd_name [] = "ohci_hcd";
82static void ohci_dump (struct ohci_hcd *ohci, int verbose); 83static void ohci_dump (struct ohci_hcd *ohci, int verbose);
83static int ohci_init (struct ohci_hcd *ohci); 84static int ohci_init (struct ohci_hcd *ohci);
84static void ohci_stop (struct usb_hcd *hcd); 85static void ohci_stop (struct usb_hcd *hcd);
86static int ohci_restart (struct ohci_hcd *ohci);
87static void ohci_quirk_nec_worker (struct work_struct *work);
85 88
86#include "ohci-hub.c" 89#include "ohci-hub.c"
87#include "ohci-dbg.c" 90#include "ohci-dbg.c"
@@ -651,9 +654,20 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
651 } 654 }
652 655
653 if (ints & OHCI_INTR_UE) { 656 if (ints & OHCI_INTR_UE) {
654 disable (ohci);
655 ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
656 // e.g. due to PCI Master/Target Abort 657 // e.g. due to PCI Master/Target Abort
658 if (ohci->flags & OHCI_QUIRK_NEC) {
659 /* Workaround for a silicon bug in some NEC chips used
660 * in Apple's PowerBooks. Adapted from Darwin code.
661 */
662 ohci_err (ohci, "OHCI Unrecoverable Error, scheduling NEC chip restart\n");
663
664 ohci_writel (ohci, OHCI_INTR_UE, &regs->intrdisable);
665
666 schedule_work (&ohci->nec_work);
667 } else {
668 disable (ohci);
669 ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
670 }
657 671
658 ohci_dump (ohci, 1); 672 ohci_dump (ohci, 1);
659 ohci_usb_reset (ohci); 673 ohci_usb_reset (ohci);
@@ -755,23 +769,16 @@ static void ohci_stop (struct usb_hcd *hcd)
755/*-------------------------------------------------------------------------*/ 769/*-------------------------------------------------------------------------*/
756 770
757/* must not be called from interrupt context */ 771/* must not be called from interrupt context */
758
759#ifdef CONFIG_PM
760
761static int ohci_restart (struct ohci_hcd *ohci) 772static int ohci_restart (struct ohci_hcd *ohci)
762{ 773{
763 int temp; 774 int temp;
764 int i; 775 int i;
765 struct urb_priv *priv; 776 struct urb_priv *priv;
766 777
767 /* mark any devices gone, so they do nothing till khubd disconnects.
768 * recycle any "live" eds/tds (and urbs) right away.
769 * later, khubd disconnect processing will recycle the other state,
770 * (either as disconnect/reconnect, or maybe someday as a reset).
771 */
772 spin_lock_irq(&ohci->lock); 778 spin_lock_irq(&ohci->lock);
773 disable (ohci); 779 disable (ohci);
774 usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub); 780
781 /* Recycle any "live" eds/tds (and urbs). */
775 if (!list_empty (&ohci->pending)) 782 if (!list_empty (&ohci->pending))
776 ohci_dbg(ohci, "abort schedule...\n"); 783 ohci_dbg(ohci, "abort schedule...\n");
777 list_for_each_entry (priv, &ohci->pending, pending) { 784 list_for_each_entry (priv, &ohci->pending, pending) {
@@ -822,7 +829,27 @@ static int ohci_restart (struct ohci_hcd *ohci)
822 ohci_dbg(ohci, "restart complete\n"); 829 ohci_dbg(ohci, "restart complete\n");
823 return 0; 830 return 0;
824} 831}
825#endif 832
833/*-------------------------------------------------------------------------*/
834
835/* NEC workaround */
836static void ohci_quirk_nec_worker(struct work_struct *work)
837{
838 struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work);
839 int status;
840
841 status = ohci_init(ohci);
842 if (status != 0) {
843 ohci_err(ohci, "Restarting NEC controller failed "
844 "in ohci_init, %d\n", status);
845 return;
846 }
847
848 status = ohci_restart(ohci);
849 if (status != 0)
850 ohci_err(ohci, "Restarting NEC controller failed "
851 "in ohci_restart, %d\n", status);
852}
826 853
827/*-------------------------------------------------------------------------*/ 854/*-------------------------------------------------------------------------*/
828 855