USB EHCI: reset root hub
Some of multi-function USB controllers (e.g. ISP1562) allow root hub resetting only via EHCI registers. So, this patch adds the corresponding kind of reset to OHCI's hc_reset() if the newly introduced CONFIG_PCI_EHCI_DEVNO option is set (e.g. for Socrates board). Signed-off-by: Yuri Tikhonov <yur@emcraft.com> Acked-by: Markus Klotzbuecher <mk@denx.de>
This commit is contained in:
parent
5875d358f0
commit
e90fb6afab
@ -109,6 +109,14 @@ static struct pci_device_id ohci_pci_ids[] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCI_EHCI_DEVNO
|
||||||
|
static struct pci_device_id ehci_pci_ids[] = {
|
||||||
|
{0x1131, 0x1562}, /* Philips 1562 PCI EHCI module ids */
|
||||||
|
/* Please add supported PCI EHCI controller ids here */
|
||||||
|
{0, 0}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
|
#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
|
||||||
#else
|
#else
|
||||||
@ -1572,11 +1580,38 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||||||
|
|
||||||
static int hc_reset (ohci_t *ohci)
|
static int hc_reset (ohci_t *ohci)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_PCI_EHCI_DEVNO
|
||||||
|
pci_dev_t pdev;
|
||||||
|
#endif
|
||||||
int timeout = 30;
|
int timeout = 30;
|
||||||
int smm_timeout = 50; /* 0,5 sec */
|
int smm_timeout = 50; /* 0,5 sec */
|
||||||
|
|
||||||
dbg("%s\n", __FUNCTION__);
|
dbg("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCI_EHCI_DEVNO
|
||||||
|
/*
|
||||||
|
* Some multi-function controllers (e.g. ISP1562) allow root hub
|
||||||
|
* resetting via EHCI registers only.
|
||||||
|
*/
|
||||||
|
pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVNO);
|
||||||
|
if (pdev != -1) {
|
||||||
|
u32 base;
|
||||||
|
int timeout = 1000;
|
||||||
|
|
||||||
|
pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &base);
|
||||||
|
writel (readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET,
|
||||||
|
base + EHCI_USBCMD_OFF);
|
||||||
|
|
||||||
|
while (readl(base + EHCI_USBCMD_OFF) & EHCI_USBCMD_HCRESET) {
|
||||||
|
if (timeout-- <= 0) {
|
||||||
|
printf("USB RootHub reset timed out!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
udelay(1);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
printf("No EHCI func at %d index!\n", CONFIG_PCI_EHCI_DEVNO);
|
||||||
|
#endif
|
||||||
if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
|
if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
|
||||||
writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
|
writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
|
||||||
info("USB HC TakeOver from SMM");
|
info("USB HC TakeOver from SMM");
|
||||||
|
@ -195,6 +195,9 @@ struct ohci_regs {
|
|||||||
} roothub;
|
} roothub;
|
||||||
} __attribute((aligned(32)));
|
} __attribute((aligned(32)));
|
||||||
|
|
||||||
|
/* Some EHCI controls */
|
||||||
|
#define EHCI_USBCMD_OFF 0x20
|
||||||
|
#define EHCI_USBCMD_HCRESET (1 << 1)
|
||||||
|
|
||||||
/* OHCI CONTROL AND STATUS REGISTER MASKS */
|
/* OHCI CONTROL AND STATUS REGISTER MASKS */
|
||||||
|
|
||||||
|
@ -410,6 +410,7 @@
|
|||||||
#define CONFIG_USB_OHCI_NEW 1
|
#define CONFIG_USB_OHCI_NEW 1
|
||||||
#define CONFIG_PCI_OHCI 1
|
#define CONFIG_PCI_OHCI 1
|
||||||
#define CONFIG_PCI_OHCI_DEVNO 3 /* Number in PCI list */
|
#define CONFIG_PCI_OHCI_DEVNO 3 /* Number in PCI list */
|
||||||
|
#define CONFIG_PCI_EHCI_DEVNO (CONFIG_PCI_OHCI_DEVNO / 2)
|
||||||
#define CFG_USB_OHCI_MAX_ROOT_PORTS 15
|
#define CFG_USB_OHCI_MAX_ROOT_PORTS 15
|
||||||
#define CFG_USB_OHCI_SLOT_NAME "ohci_pci"
|
#define CFG_USB_OHCI_SLOT_NAME "ohci_pci"
|
||||||
#define CFG_OHCI_SWAP_REG_ACCESS 1
|
#define CFG_OHCI_SWAP_REG_ACCESS 1
|
||||||
|
Loading…
Reference in New Issue
Block a user