aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/host/ehci-hcd.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c135
1 files changed, 112 insertions, 23 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 34a928d3b7d2..f8030ee928e8 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1,4 +1,8 @@
1/* 1/*
2 * Enhanced Host Controller Interface (EHCI) driver for USB.
3 *
4 * Maintainer: Alan Stern <stern@rowland.harvard.edu>
5 *
2 * Copyright (c) 2000-2004 by David Brownell 6 * Copyright (c) 2000-2004 by David Brownell
3 * 7 *
4 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
@@ -118,6 +122,7 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us\n");
118 122
119#include "ehci.h" 123#include "ehci.h"
120#include "ehci-dbg.c" 124#include "ehci-dbg.c"
125#include "pci-quirks.h"
121 126
122/*-------------------------------------------------------------------------*/ 127/*-------------------------------------------------------------------------*/
123 128
@@ -194,6 +199,17 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
194 return -ETIMEDOUT; 199 return -ETIMEDOUT;
195} 200}
196 201
202/* check TDI/ARC silicon is in host mode */
203static int tdi_in_host_mode (struct ehci_hcd *ehci)
204{
205 u32 __iomem *reg_ptr;
206 u32 tmp;
207
208 reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
209 tmp = ehci_readl(ehci, reg_ptr);
210 return (tmp & 3) == USBMODE_CM_HC;
211}
212
197/* force HC to halt state from unknown (EHCI spec section 2.3) */ 213/* force HC to halt state from unknown (EHCI spec section 2.3) */
198static int ehci_halt (struct ehci_hcd *ehci) 214static int ehci_halt (struct ehci_hcd *ehci)
199{ 215{
@@ -202,6 +218,10 @@ static int ehci_halt (struct ehci_hcd *ehci)
202 /* disable any irqs left enabled by previous code */ 218 /* disable any irqs left enabled by previous code */
203 ehci_writel(ehci, 0, &ehci->regs->intr_enable); 219 ehci_writel(ehci, 0, &ehci->regs->intr_enable);
204 220
221 if (ehci_is_TDI(ehci) && tdi_in_host_mode(ehci) == 0) {
222 return 0;
223 }
224
205 if ((temp & STS_HALT) != 0) 225 if ((temp & STS_HALT) != 0)
206 return 0; 226 return 0;
207 227
@@ -514,6 +534,9 @@ static void ehci_stop (struct usb_hcd *hcd)
514 spin_unlock_irq (&ehci->lock); 534 spin_unlock_irq (&ehci->lock);
515 ehci_mem_cleanup (ehci); 535 ehci_mem_cleanup (ehci);
516 536
537 if (ehci->amd_pll_fix == 1)
538 usb_amd_dev_put();
539
517#ifdef EHCI_STATS 540#ifdef EHCI_STATS
518 ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", 541 ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
519 ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, 542 ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
@@ -549,6 +572,8 @@ static int ehci_init(struct usb_hcd *hcd)
549 ehci->iaa_watchdog.function = ehci_iaa_watchdog; 572 ehci->iaa_watchdog.function = ehci_iaa_watchdog;
550 ehci->iaa_watchdog.data = (unsigned long) ehci; 573 ehci->iaa_watchdog.data = (unsigned long) ehci;
551 574
575 hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
576
552 /* 577 /*
553 * hw default: 1K periodic list heads, one per frame. 578 * hw default: 1K periodic list heads, one per frame.
554 * periodic_size can shrink by USBCMD update if hcc_params allows. 579 * periodic_size can shrink by USBCMD update if hcc_params allows.
@@ -556,11 +581,20 @@ static int ehci_init(struct usb_hcd *hcd)
556 ehci->periodic_size = DEFAULT_I_TDPS; 581 ehci->periodic_size = DEFAULT_I_TDPS;
557 INIT_LIST_HEAD(&ehci->cached_itd_list); 582 INIT_LIST_HEAD(&ehci->cached_itd_list);
558 INIT_LIST_HEAD(&ehci->cached_sitd_list); 583 INIT_LIST_HEAD(&ehci->cached_sitd_list);
584
585 if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
586 /* periodic schedule size can be smaller than default */
587 switch (EHCI_TUNE_FLS) {
588 case 0: ehci->periodic_size = 1024; break;
589 case 1: ehci->periodic_size = 512; break;
590 case 2: ehci->periodic_size = 256; break;
591 default: BUG();
592 }
593 }
559 if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) 594 if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
560 return retval; 595 return retval;
561 596
562 /* controllers may cache some of the periodic schedule ... */ 597 /* controllers may cache some of the periodic schedule ... */
563 hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
564 if (HCC_ISOC_CACHE(hcc_params)) // full frame cache 598 if (HCC_ISOC_CACHE(hcc_params)) // full frame cache
565 ehci->i_thresh = 2 + 8; 599 ehci->i_thresh = 2 + 8;
566 else // N microframes cached 600 else // N microframes cached
@@ -614,12 +648,6 @@ static int ehci_init(struct usb_hcd *hcd)
614 /* periodic schedule size can be smaller than default */ 648 /* periodic schedule size can be smaller than default */
615 temp &= ~(3 << 2); 649 temp &= ~(3 << 2);
616 temp |= (EHCI_TUNE_FLS << 2); 650 temp |= (EHCI_TUNE_FLS << 2);
617 switch (EHCI_TUNE_FLS) {
618 case 0: ehci->periodic_size = 1024; break;
619 case 1: ehci->periodic_size = 512; break;
620 case 2: ehci->periodic_size = 256; break;
621 default: BUG();
622 }
623 } 651 }
624 if (HCC_LPM(hcc_params)) { 652 if (HCC_LPM(hcc_params)) {
625 /* support link power management EHCI 1.1 addendum */ 653 /* support link power management EHCI 1.1 addendum */
@@ -651,7 +679,12 @@ static int ehci_run (struct usb_hcd *hcd)
651 hcd->uses_new_polling = 1; 679 hcd->uses_new_polling = 1;
652 680
653 /* EHCI spec section 4.1 */ 681 /* EHCI spec section 4.1 */
654 if ((retval = ehci_reset(ehci)) != 0) { 682 /*
683 * TDI driver does the ehci_reset in their reset callback.
684 * Don't reset here, because configuration settings will
685 * vanish.
686 */
687 if (!ehci_is_TDI(ehci) && (retval = ehci_reset(ehci)) != 0) {
655 ehci_mem_cleanup(ehci); 688 ehci_mem_cleanup(ehci);
656 return retval; 689 return retval;
657 } 690 }
@@ -710,7 +743,7 @@ static int ehci_run (struct usb_hcd *hcd)
710 up_write(&ehci_cf_port_reset_rwsem); 743 up_write(&ehci_cf_port_reset_rwsem);
711 ehci->last_periodic_enable = ktime_get_real(); 744 ehci->last_periodic_enable = ktime_get_real();
712 745
713 temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); 746 temp = HC_VERSION(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
714 ehci_info (ehci, 747 ehci_info (ehci,
715 "USB %x.%x started, EHCI %x.%02x%s\n", 748 "USB %x.%x started, EHCI %x.%02x%s\n",
716 ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), 749 ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
@@ -748,8 +781,9 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
748 goto dead; 781 goto dead;
749 } 782 }
750 783
784 /* Shared IRQ? */
751 masked_status = status & INTR_MASK; 785 masked_status = status & INTR_MASK;
752 if (!masked_status) { /* irq sharing? */ 786 if (!masked_status || unlikely(hcd->state == HC_STATE_HALT)) {
753 spin_unlock(&ehci->lock); 787 spin_unlock(&ehci->lock);
754 return IRQ_NONE; 788 return IRQ_NONE;
755 } 789 }
@@ -844,6 +878,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
844dead: 878dead:
845 ehci_reset(ehci); 879 ehci_reset(ehci);
846 ehci_writel(ehci, 0, &ehci->regs->configured_flag); 880 ehci_writel(ehci, 0, &ehci->regs->configured_flag);
881 usb_hc_died(hcd);
847 /* generic layer kills/unlinks all urbs, then 882 /* generic layer kills/unlinks all urbs, then
848 * uses ehci_stop to clean up the rest 883 * uses ehci_stop to clean up the rest
849 */ 884 */
@@ -1048,10 +1083,11 @@ rescan:
1048 tmp && tmp != qh; 1083 tmp && tmp != qh;
1049 tmp = tmp->qh_next.qh) 1084 tmp = tmp->qh_next.qh)
1050 continue; 1085 continue;
1051 /* periodic qh self-unlinks on empty */ 1086 /* periodic qh self-unlinks on empty, and a COMPLETING qh
1052 if (!tmp) 1087 * may already be unlinked.
1053 goto nogood; 1088 */
1054 unlink_async (ehci, qh); 1089 if (tmp)
1090 unlink_async(ehci, qh);
1055 /* FALL THROUGH */ 1091 /* FALL THROUGH */
1056 case QH_STATE_UNLINK: /* wait for hw to finish? */ 1092 case QH_STATE_UNLINK: /* wait for hw to finish? */
1057 case QH_STATE_UNLINK_WAIT: 1093 case QH_STATE_UNLINK_WAIT:
@@ -1068,7 +1104,6 @@ idle_timeout:
1068 } 1104 }
1069 /* else FALL THROUGH */ 1105 /* else FALL THROUGH */
1070 default: 1106 default:
1071nogood:
1072 /* caller was supposed to have unlinked any requests; 1107 /* caller was supposed to have unlinked any requests;
1073 * that's not our job. just leak this memory. 1108 * that's not our job. just leak this memory.
1074 */ 1109 */
@@ -1080,7 +1115,6 @@ nogood:
1080 ep->hcpriv = NULL; 1115 ep->hcpriv = NULL;
1081done: 1116done:
1082 spin_unlock_irqrestore (&ehci->lock, flags); 1117 spin_unlock_irqrestore (&ehci->lock, flags);
1083 return;
1084} 1118}
1085 1119
1086static void 1120static void
@@ -1152,12 +1186,17 @@ MODULE_LICENSE ("GPL");
1152#define PLATFORM_DRIVER ehci_mxc_driver 1186#define PLATFORM_DRIVER ehci_mxc_driver
1153#endif 1187#endif
1154 1188
1189#ifdef CONFIG_USB_EHCI_SH
1190#include "ehci-sh.c"
1191#define PLATFORM_DRIVER ehci_hcd_sh_driver
1192#endif
1193
1155#ifdef CONFIG_SOC_AU1200 1194#ifdef CONFIG_SOC_AU1200
1156#include "ehci-au1xxx.c" 1195#include "ehci-au1xxx.c"
1157#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver 1196#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver
1158#endif 1197#endif
1159 1198
1160#ifdef CONFIG_ARCH_OMAP3 1199#ifdef CONFIG_USB_EHCI_HCD_OMAP
1161#include "ehci-omap.c" 1200#include "ehci-omap.c"
1162#define PLATFORM_DRIVER ehci_hcd_omap_driver 1201#define PLATFORM_DRIVER ehci_hcd_omap_driver
1163#endif 1202#endif
@@ -1197,6 +1236,56 @@ MODULE_LICENSE ("GPL");
1197#define PLATFORM_DRIVER ehci_atmel_driver 1236#define PLATFORM_DRIVER ehci_atmel_driver
1198#endif 1237#endif
1199 1238
1239#ifdef CONFIG_USB_OCTEON_EHCI
1240#include "ehci-octeon.c"
1241#define PLATFORM_DRIVER ehci_octeon_driver
1242#endif
1243
1244#ifdef CONFIG_USB_CNS3XXX_EHCI
1245#include "ehci-cns3xxx.c"
1246#define PLATFORM_DRIVER cns3xxx_ehci_driver
1247#endif
1248
1249#ifdef CONFIG_ARCH_VT8500
1250#include "ehci-vt8500.c"
1251#define PLATFORM_DRIVER vt8500_ehci_driver
1252#endif
1253
1254#ifdef CONFIG_PLAT_SPEAR
1255#include "ehci-spear.c"
1256#define PLATFORM_DRIVER spear_ehci_hcd_driver
1257#endif
1258
1259#ifdef CONFIG_USB_EHCI_MSM
1260#include "ehci-msm.c"
1261#define PLATFORM_DRIVER ehci_msm_driver
1262#endif
1263
1264#ifdef CONFIG_USB_EHCI_HCD_PMC_MSP
1265#include "ehci-pmcmsp.c"
1266#define PLATFORM_DRIVER ehci_hcd_msp_driver
1267#endif
1268
1269#ifdef CONFIG_USB_EHCI_TEGRA
1270#include "ehci-tegra.c"
1271#define PLATFORM_DRIVER tegra_ehci_driver
1272#endif
1273
1274#ifdef CONFIG_USB_EHCI_S5P
1275#include "ehci-s5p.c"
1276#define PLATFORM_DRIVER s5p_ehci_driver
1277#endif
1278
1279#ifdef CONFIG_USB_EHCI_ATH79
1280#include "ehci-ath79.c"
1281#define PLATFORM_DRIVER ehci_ath79_driver
1282#endif
1283
1284#ifdef CONFIG_SPARC_LEON
1285#include "ehci-grlib.c"
1286#define PLATFORM_DRIVER ehci_grlib_driver
1287#endif
1288
1200#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ 1289#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
1201 !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ 1290 !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
1202 !defined(XILINX_OF_PLATFORM_DRIVER) 1291 !defined(XILINX_OF_PLATFORM_DRIVER)
@@ -1249,24 +1338,24 @@ static int __init ehci_hcd_init(void)
1249#endif 1338#endif
1250 1339
1251#ifdef OF_PLATFORM_DRIVER 1340#ifdef OF_PLATFORM_DRIVER
1252 retval = of_register_platform_driver(&OF_PLATFORM_DRIVER); 1341 retval = platform_driver_register(&OF_PLATFORM_DRIVER);
1253 if (retval < 0) 1342 if (retval < 0)
1254 goto clean3; 1343 goto clean3;
1255#endif 1344#endif
1256 1345
1257#ifdef XILINX_OF_PLATFORM_DRIVER 1346#ifdef XILINX_OF_PLATFORM_DRIVER
1258 retval = of_register_platform_driver(&XILINX_OF_PLATFORM_DRIVER); 1347 retval = platform_driver_register(&XILINX_OF_PLATFORM_DRIVER);
1259 if (retval < 0) 1348 if (retval < 0)
1260 goto clean4; 1349 goto clean4;
1261#endif 1350#endif
1262 return retval; 1351 return retval;
1263 1352
1264#ifdef XILINX_OF_PLATFORM_DRIVER 1353#ifdef XILINX_OF_PLATFORM_DRIVER
1265 /* of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); */ 1354 /* platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER); */
1266clean4: 1355clean4:
1267#endif 1356#endif
1268#ifdef OF_PLATFORM_DRIVER 1357#ifdef OF_PLATFORM_DRIVER
1269 of_unregister_platform_driver(&OF_PLATFORM_DRIVER); 1358 platform_driver_unregister(&OF_PLATFORM_DRIVER);
1270clean3: 1359clean3:
1271#endif 1360#endif
1272#ifdef PS3_SYSTEM_BUS_DRIVER 1361#ifdef PS3_SYSTEM_BUS_DRIVER
@@ -1294,10 +1383,10 @@ module_init(ehci_hcd_init);
1294static void __exit ehci_hcd_cleanup(void) 1383static void __exit ehci_hcd_cleanup(void)
1295{ 1384{
1296#ifdef XILINX_OF_PLATFORM_DRIVER 1385#ifdef XILINX_OF_PLATFORM_DRIVER
1297 of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); 1386 platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER);
1298#endif 1387#endif
1299#ifdef OF_PLATFORM_DRIVER 1388#ifdef OF_PLATFORM_DRIVER
1300 of_unregister_platform_driver(&OF_PLATFORM_DRIVER); 1389 platform_driver_unregister(&OF_PLATFORM_DRIVER);
1301#endif 1390#endif
1302#ifdef PLATFORM_DRIVER 1391#ifdef PLATFORM_DRIVER
1303 platform_driver_unregister(&PLATFORM_DRIVER); 1392 platform_driver_unregister(&PLATFORM_DRIVER);