aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/Kconfig4
-rw-r--r--drivers/usb/host/uhci-hcd.c73
-rw-r--r--drivers/usb/host/uhci-hcd.h65
3 files changed, 142 insertions, 0 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7dd4c44fabb..8045988f57a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -410,6 +410,10 @@ config USB_UHCI_HCD
410 To compile this driver as a module, choose M here: the 410 To compile this driver as a module, choose M here: the
411 module will be called uhci-hcd. 411 module will be called uhci-hcd.
412 412
413config USB_UHCI_SUPPORT_NON_PCI_HC
414 bool
415 depends on USB_UHCI_HCD
416
413config USB_FHCI_HCD 417config USB_FHCI_HCD
414 tristate "Freescale QE USB Host Controller support" 418 tristate "Freescale QE USB Host Controller support"
415 depends on USB && OF_GPIO && QE_GPIO && QUICC_ENGINE 419 depends on USB && OF_GPIO && QE_GPIO && QUICC_ENGINE
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 5176c537b95..cd482fcc05d 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -167,6 +167,79 @@ static void check_and_reset_hc(struct uhci_hcd *uhci)
167 finish_reset(uhci); 167 finish_reset(uhci);
168} 168}
169 169
170#if defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC)
171/*
172 * The two functions below are generic reset functions that are used on systems
173 * that do not have keyboard and mouse legacy support. We assume that we are
174 * running on such a system if CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC is defined.
175 */
176
177/*
178 * Make sure the controller is completely inactive, unable to
179 * generate interrupts or do DMA.
180 */
181static void uhci_generic_reset_hc(struct uhci_hcd *uhci)
182{
183 /* Reset the HC - this will force us to get a
184 * new notification of any already connected
185 * ports due to the virtual disconnect that it
186 * implies.
187 */
188 uhci_writew(uhci, USBCMD_HCRESET, USBCMD);
189 mb();
190 udelay(5);
191 if (uhci_readw(uhci, USBCMD) & USBCMD_HCRESET)
192 dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n");
193
194 /* Just to be safe, disable interrupt requests and
195 * make sure the controller is stopped.
196 */
197 uhci_writew(uhci, 0, USBINTR);
198 uhci_writew(uhci, 0, USBCMD);
199}
200
201/*
202 * Initialize a controller that was newly discovered or has just been
203 * resumed. In either case we can't be sure of its previous state.
204 *
205 * Returns: 1 if the controller was reset, 0 otherwise.
206 */
207static int uhci_generic_check_and_reset_hc(struct uhci_hcd *uhci)
208{
209 unsigned int cmd, intr;
210
211 /*
212 * When restarting a suspended controller, we expect all the
213 * settings to be the same as we left them:
214 *
215 * Controller is stopped and configured with EGSM set;
216 * No interrupts enabled except possibly Resume Detect.
217 *
218 * If any of these conditions are violated we do a complete reset.
219 */
220
221 cmd = uhci_readw(uhci, USBCMD);
222 if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) {
223 dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n",
224 __func__, cmd);
225 goto reset_needed;
226 }
227
228 intr = uhci_readw(uhci, USBINTR);
229 if (intr & (~USBINTR_RESUME)) {
230 dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n",
231 __func__, intr);
232 goto reset_needed;
233 }
234 return 0;
235
236reset_needed:
237 dev_dbg(uhci_dev(uhci), "Performing full reset\n");
238 uhci_generic_reset_hc(uhci);
239 return 1;
240}
241#endif /* CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC */
242
170/* 243/*
171 * Store the basic register settings needed by the controller. 244 * Store the basic register settings needed by the controller.
172 */ 245 */
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index a6de241bf96..a4e64d08f02 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -380,6 +380,9 @@ struct uhci_hcd {
380 /* Grabbed from PCI */ 380 /* Grabbed from PCI */
381 unsigned long io_addr; 381 unsigned long io_addr;
382 382
383 /* Used when registers are memory mapped */
384 void __iomem *regs;
385
383 struct dma_pool *qh_pool; 386 struct dma_pool *qh_pool;
384 struct dma_pool *td_pool; 387 struct dma_pool *td_pool;
385 388
@@ -481,6 +484,14 @@ struct urb_priv {
481#define PCI_VENDOR_ID_GENESYS 0x17a0 484#define PCI_VENDOR_ID_GENESYS 0x17a0
482#define PCI_DEVICE_ID_GL880S_UHCI 0x8083 485#define PCI_DEVICE_ID_GL880S_UHCI 0x8083
483 486
487/*
488 * Functions used to access controller registers. The UCHI spec says that host
489 * controller I/O registers are mapped into PCI I/O space. For non-PCI hosts
490 * we use memory mapped registers.
491 */
492
493#if !defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC)
494/* Support PCI only */
484static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg) 495static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg)
485{ 496{
486 return inl(uhci->io_addr + reg); 497 return inl(uhci->io_addr + reg);
@@ -511,4 +522,58 @@ static inline void uhci_writeb(struct uhci_hcd *uhci, u8 val, int reg)
511 outb(val, uhci->io_addr + reg); 522 outb(val, uhci->io_addr + reg);
512} 523}
513 524
525#else
526/* Support PCI and non-PCI host controllers */
527
528#define uhci_has_pci_registers(u) ((u)->io_addr != 0)
529
530static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg)
531{
532 if (uhci_has_pci_registers(uhci))
533 return inl(uhci->io_addr + reg);
534 else
535 return readl(uhci->regs + reg);
536}
537
538static inline void uhci_writel(struct uhci_hcd *uhci, u32 val, int reg)
539{
540 if (uhci_has_pci_registers(uhci))
541 outl(val, uhci->io_addr + reg);
542 else
543 writel(val, uhci->regs + reg);
544}
545
546static inline u16 uhci_readw(struct uhci_hcd *uhci, int reg)
547{
548 if (uhci_has_pci_registers(uhci))
549 return inw(uhci->io_addr + reg);
550 else
551 return readw(uhci->regs + reg);
552}
553
554static inline void uhci_writew(struct uhci_hcd *uhci, u16 val, int reg)
555{
556 if (uhci_has_pci_registers(uhci))
557 outw(val, uhci->io_addr + reg);
558 else
559 writew(val, uhci->regs + reg);
560}
561
562static inline u8 uhci_readb(struct uhci_hcd *uhci, int reg)
563{
564 if (uhci_has_pci_registers(uhci))
565 return inb(uhci->io_addr + reg);
566 else
567 return readb(uhci->regs + reg);
568}
569
570static inline void uhci_writeb(struct uhci_hcd *uhci, u8 val, int reg)
571{
572 if (uhci_has_pci_registers(uhci))
573 outb(val, uhci->io_addr + reg);
574 else
575 writeb(val, uhci->regs + reg);
576}
577#endif /* !defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC) */
578
514#endif 579#endif