📄 usb_host.patch
字号:
++ ehci_dbg (ehci, "clean up %s transceiver\n",+ ehci->transceiver->label);+ if (ehci->transceiver) {+ ehci->transceiver->host = NULL;+ ehci->transceiver->set_host(ehci->transceiver, NULL);+ }+ ehci->transceiver = NULL;+ ehci->power_budget = 0;+ hcd->self.otg_port = 0;+}+#endif++/*-------------------------------------------------------------------------*/++#if defined(CONFIG_PCI) && !defined(CONFIG_SOC_AU1X00)+ static const struct hc_driver ehci_driver = { .description = hcd_name, .product_desc = "EHCI Host Controller",@@ -1176,14 +1245,17 @@ .hub_control = ehci_hub_control, .hub_suspend = ehci_hub_suspend, .hub_resume = ehci_hub_resume,+ .start_port_reset = ehci_start_port_reset,+#if defined(CONFIG_USB_OTG_HIGHSPEED) && defined(CONFIG_USB_PORT_AMD5536OTG)+ .start_otg = ehci_start_otg,+ .stop_otg = ehci_stop_otg,+#endif }; /*-------------------------------------------------------------------------*/ /* EHCI 1.0 doesn't require PCI */ -#ifdef CONFIG_PCI- /* PCI driver selection metadata; PCI hotplugging uses this */ static const struct pci_device_id pci_ids [] = { { /* handle any USB 2.0 EHCI controller */@@ -1210,13 +1282,17 @@ #endif /* PCI */ - #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC MODULE_DESCRIPTION (DRIVER_INFO); MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_LICENSE ("GPL"); +#ifdef CONFIG_SOC_AU1X00+#include "ehci-au1xxx.c"+#else+#ifdef CONFIG_PCI+ static int __init init (void) { if (usb_disabled())@@ -1236,3 +1312,11 @@ pci_unregister_driver (&ehci_pci_driver); } module_exit (cleanup);++#endif /* PCI */+#endif++#if !(defined(CONFIG_PCI) \+ || defined(CONFIG_SOC_AU1X00))+#error "missing bus glue for ehci-hcd"+#endifdiff -Nru linux26-cvs/drivers/usb/host/ehci-hub.c linux26-amd/drivers/usb/host/ehci-hub.c--- linux26-cvs/drivers/usb/host/ehci-hub.c 2005-03-23 13:53:13.000000000 +0100+++ linux26-amd/drivers/usb/host/ehci-hub.c 2005-06-15 16:14:15.800269000 +0200@@ -192,6 +192,16 @@ port_status |= PORT_OWNER; writel (port_status, &ehci->regs->port_status [index]); +#if defined(CONFIG_USB_OTG_HIGHSPEED) && defined(CONFIG_USB_PORT_AMD5536OTG)++ if (ehci->transceiver &&+ ((index + 1) == ehci_to_hcd(ehci)->self.otg_port) &&+ (ehci->transceiver->companion)) {+ ehci->transceiver->companion->hand_over = 1;+ usb_bus_start_enum (ehci->transceiver->companion,+ ehci->transceiver->companion->otg_port);+ }+#endif } else ehci_dbg (ehci, "port %d high speed\n", index + 1); @@ -291,6 +301,59 @@ /*-------------------------------------------------------------------------*/ +#ifdef CONFIG_USB_OTG_HIGHSPEED++static int ehci_start_port_reset (struct usb_hcd *hcd, unsigned port)+{+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);+ u32 status;++ if (!port)+ return -EINVAL;+ port--;++ /* start port reset before HNP protocol times out */+ status = readl (&ehci->regs->port_status [port]);+ if (status & PORT_RESUME)+ return -EINVAL;++ if (!(status & PORT_CONNECT))+ return -ENODEV;++ status |= PORT_RESET;+ status &= ~(PORT_PE | PORT_CSC); /* PORT_CSC for khubd notification */+ ehci->reset_done [port] = jiffies + msecs_to_jiffies (50);+ writel (status, &ehci->regs->port_status [port]);+ return 0;+}++#ifdef CONFIG_USB_PORT_AMD5536OTG++static void start_hnp (struct ehci_hcd *ehci)+{+ const unsigned port = ehci_to_hcd(ehci)->self.otg_port - 1;+ unsigned long flags;+ u32 status;++ otg_start_hnp (ehci->transceiver);+ local_irq_save (flags);+ status = readl (&ehci->regs->port_status [port]);+ if (!(status & PORT_OWNER) && (status & PORT_PE))+ writel (status | PORT_SUSPEND, &ehci->regs->port_status [port]);+ local_irq_restore (flags);+}+#endif++static void start_hnp (struct ehci_hcd *ehci);++#else++#define ehci_start_port_reset NULL++#endif++/*-------------------------------------------------------------------------*/+ #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) static int ehci_hub_control (@@ -499,10 +562,19 @@ if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) goto error;+#ifdef CONFIG_USB_OTG_HIGHSPEED+ if (hcd->self.otg_port == (wIndex + 1)+ && hcd->self.b_hnp_enable)+ start_hnp(ehci);+ else {+#endif if (hcd->remote_wakeup) temp |= PORT_WAKE_BITS; writel (temp | PORT_SUSPEND, &ehci->regs->port_status [wIndex]);+#ifdef CONFIG_USB_OTG_HIGHSPEED+ }+#endif break; case USB_PORT_FEAT_POWER: if (HCS_PPC (ehci->hcs_params))diff -Nru linux26-cvs/drivers/usb/host/Kconfig linux26-amd/drivers/usb/host/Kconfig--- linux26-cvs/drivers/usb/host/Kconfig 2005-03-23 13:53:08.000000000 +0100+++ linux26-amd/drivers/usb/host/Kconfig 2005-07-19 16:56:46.000000000 +0200@@ -3,13 +3,20 @@ # NOTE: SL-811 option should be board-specific ... config USB_ARCH_HAS_HCD boolean- default y if USB_ARCH_HAS_OHCI+ default y if USB_ARCH_HAS_EHCI || USB_ARCH_HAS_OHCI default y if ARM # SL-811 default PCI +# some non-PCI hcds implement EHCI+config USB_ARCH_HAS_EHCI+ boolean+ default y if SOC_AU1200+ default PCI+ # many non-PCI hcds implement OHCI config USB_ARCH_HAS_OHCI boolean+ default y if SOC_AU1100 || SOC_AU1200 || SOC_AU1500 || SOC_AU1550 default y if SA1111 default y if ARCH_OMAP default y if ARCH_LH7A404@@ -24,7 +31,7 @@ config USB_EHCI_HCD tristate "EHCI HCD (USB 2.0) support"- depends on USB && PCI+ depends on USB && USB_ARCH_HAS_EHCI ---help--- The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.diff -Nru linux26-cvs/drivers/usb/host/ohci-au1xxx.c linux26-amd/drivers/usb/host/ohci-au1xxx.c--- linux26-cvs/drivers/usb/host/ohci-au1xxx.c 2005-03-23 13:53:14.000000000 +0100+++ linux26-amd/drivers/usb/host/ohci-au1xxx.c 2005-08-02 16:45:31.171007000 +0200@@ -20,6 +20,8 @@ #include <asm/mach-au1x00/au1000.h> +#ifndef CONFIG_SOC_AU1200+ #define USBH_ENABLE_BE (1<<0) #define USBH_ENABLE_C (1<<1) #define USBH_ENABLE_E (1<<2)@@ -34,16 +36,45 @@ #error not byte order defined #endif +#else /* Au1200 */++#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG)+#define USB_MCFG_PFEN (1<<31)+#define USB_MCFG_RDCOMB (1<<30)+#define USB_MCFG_SSDEN (1<<23)+#define USB_MCFG_OHCCLKEN (1<<16)+#define USB_MCFG_UCAM (1<<7)+#define USB_MCFG_OBMEN (1<<1)+#define USB_MCFG_OMEMEN (1<<0)++#define USBH_ENABLE_CE USB_MCFG_OHCCLKEN+#ifdef CONFIG_DMA_COHERENT+#define USBH_ENABLE_INIT (USB_MCFG_OHCCLKEN \+ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \+ | USB_MCFG_SSDEN | USB_MCFG_UCAM \+ | USB_MCFG_OBMEN | USB_MCFG_OMEMEN)+#else+#define USBH_ENABLE_INIT (USB_MCFG_OHCCLKEN \+ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \+ | USB_MCFG_SSDEN \+ | USB_MCFG_OBMEN | USB_MCFG_OMEMEN)+#endif+#define USBH_DISABLE (USB_MCFG_OBMEN | USB_MCFG_OMEMEN)++#endif /* Au1200 */+ extern int usb_disabled(void); /*-------------------------------------------------------------------------*/ -static void au1xxx_start_hc(struct platform_device *dev)+static void au1xxx_start_ohc(struct platform_device *dev) {- printk(KERN_DEBUG __FILE__- ": starting Au1xxx OHCI USB Controller\n");+ pr_debug (__FILE__ ": starting Au1xxx OHCI USB Controller\n"); /* enable host controller */++#ifndef CONFIG_SOC_AU1200+ au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG); udelay(1000); au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);@@ -54,24 +85,51 @@ !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) udelay(1000); - printk(KERN_DEBUG __FILE__- ": Clock to USB host has been enabled \n");+#else /* Au1200 */++ /* write HW defaults again in case Yamon cleared them */+ if (au_readl(USB_HOST_CONFIG) == 0) {+ au_writel(0x00d02000, USB_HOST_CONFIG);+ au_readl(USB_HOST_CONFIG);+ udelay(1000);+ }+ au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);+ au_readl(USB_HOST_CONFIG);+ udelay(1000);+ au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);+ au_readl(USB_HOST_CONFIG);+ udelay(1000);++#endif /* Au1200 */++ pr_debug (__FILE__ ": Clock to USB host has been enabled\n"); } -static void au1xxx_stop_hc(struct platform_device *dev)+static void au1xxx_stop_ohc(struct platform_device *dev) {- printk(KERN_DEBUG __FILE__- ": stopping Au1xxx OHCI USB Controller\n");+ pr_debug (__FILE__ ": stopping Au1xxx OHCI USB Controller\n");++#ifndef CONFIG_SOC_AU1200 /* Disable clock */ au_writel(readl((void *)USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);++#else /* Au1200 */++ /* Disable mem */+ au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);+ udelay(1000);+ /* Disable clock */+ au_writel(~USBH_ENABLE_CE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);+ au_readl(USB_HOST_CONFIG);+#endif /* Au1200 */ } /*-------------------------------------------------------------------------*/ -static irqreturn_t usb_hcd_au1xxx_hcim_irq (int irq, void *__hcd,+static irqreturn_t usb_ohci_au1xxx_hcim_irq (int irq, void *__hcd, struct pt_regs * r) { struct usb_hcd *hcd = __hcd;@@ -81,7 +139,7 @@ /*-------------------------------------------------------------------------*/ -void usb_hcd_au1xxx_remove (struct usb_hcd *, struct platform_device *);+void usb_ohci_au1xxx_remove (struct usb_hcd *, struct platform_device *); /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */@@ -96,7 +154,7 @@ * through the hotplug entry's driver_data. * */-int usb_hcd_au1xxx_probe (const struct hc_driver *driver,+int usb_ohci_au1xxx_probe (const struct hc_driver *driver, struct usb_hcd **hcd_out, struct platform_device *dev) {@@ -105,33 +163,42 @@ unsigned int *addr = NULL; +#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)++ /* Au1200 AB USB does not support coherent memory */+ if (!(read_c0_prid() & 0xff)) {+ pr_info ("Au1200 ohci: !!! This is chip revision AB !!!\n");+ pr_info (" !!! update your board or re-configure the kernel !!!\n");+ return -ENODEV;+ }+#endif if (!request_mem_region(dev->resource[0].start,- dev->resource[0].end- - dev->resource[0].start + 1, hcd_name)) {- pr_debug("request_mem_region failed");+ dev->resource[0].end + 1+ - dev->resource[0].start, hcd_name)) {+ pr_debug ("request_mem_region failed\n"); return -EBUSY; } - au1xxx_start_hc(dev);+ au1xxx_start_ohc(dev); addr = ioremap(dev->resource[0].start,- dev->resource[0].end- - dev->resource[0].start + 1);+ dev->resource[0].end + 1+ - dev->resource[0].start); if (!addr) {- pr_debug("ioremap failed");+ pr_debug ("ioremap failed\n"); retval = -ENOMEM; goto err1; } if(dev->resource[1].flags != IORESOURCE_IRQ) {- pr_debug ("resource[1] is not IORESOURCE_IRQ");+ pr_debug ("resource[1] is not IORESOURCE_IRQ\n"); retval = -ENOMEM; goto err1; } hcd = usb_create_hcd(driver); if (hcd == NULL) {- pr_debug ("usb_create_hcd failed");+ pr_debug ("usb_create_hcd failed\n"); retval = -ENOMEM; goto err1; }@@ -143,29 +210,40 @@ retval = hcd_buffer_create (hcd); if (retval != 0) {- pr_debug ("pool alloc fail");+ pr_debug ("pool alloc fail\n"); goto err2; } - retval = request_irq (hcd->irq, usb_hcd_au1xxx_hcim_irq, SA_INTERRUPT,+#ifdef CONFIG_SOC_AU1200+ retval = request_irq (hcd->irq, usb_ohci_au1xxx_hcim_irq,+ SA_SHIRQ | SA_INTERRUPT, hcd->driver->description, hcd);+#else+ retval = request_irq (hcd->irq, usb_ohci_au1xxx_hcim_irq, SA_INTERRUPT,+ hcd->driver->description, hcd);+#endif if (retval != 0) {- pr_debug("request_irq failed");+ pr_debug ("request_irq failed\n"); retval = -EBUSY; goto err3; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -