d975302e671637e7241b510b69547f14d210aa1d
[openwrt.git] / target / linux / brcm47xx / patches-3.0 / 023-usb_ehci_ohci.patch
1 --- a/drivers/usb/host/ohci-ssb.c
2 +++ b/drivers/usb/host/ohci-ssb.c
3 @@ -17,6 +17,8 @@
4   */
5  #include <linux/ssb/ssb.h>
6  
7 +extern int ssb_ehci_attach(struct ssb_device *dev, struct usb_hcd **hcd);
8 +extern void ssb_ehci_detach(struct ssb_device *dev, struct usb_hcd *hcd);
9  
10  #define SSB_OHCI_TMSLOW_HOSTMODE       (1 << 29)
11  
12 @@ -24,6 +26,9 @@ struct ssb_ohci_device {
13         struct ohci_hcd ohci; /* _must_ be at the beginning. */
14  
15         u32 enable_flags;
16 +#ifdef CONFIG_USB_EHCI_HCD_SSB
17 +       struct usb_hcd *ehci_hcd;
18 +#endif
19  };
20  
21  static inline
22 @@ -92,6 +97,9 @@ static const struct hc_driver ssb_ohci_h
23  static void ssb_ohci_detach(struct ssb_device *dev)
24  {
25         struct usb_hcd *hcd = ssb_get_drvdata(dev);
26 +#ifdef CONFIG_USB_EHCI_HCD_SSB
27 +       struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
28 +#endif
29  
30         if (hcd->driver->shutdown)
31                 hcd->driver->shutdown(hcd);
32 @@ -99,6 +107,14 @@ static void ssb_ohci_detach(struct ssb_d
33         iounmap(hcd->regs);
34         release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
35         usb_put_hcd(hcd);
36 +
37 +#ifdef CONFIG_USB_EHCI_HCD_SSB
38 +       /*
39 +        * Also detach ehci function
40 +        */
41 +       if (dev->id.coreid == SSB_DEV_USB20_HOST)
42 +               ssb_ehci_detach(dev, ohcidev->ehci_hcd);
43 +#endif
44         ssb_device_disable(dev, 0);
45  }
46  
47 @@ -121,6 +137,9 @@ static int ssb_ohci_attach(struct ssb_de
48                 /*
49                  * USB 2.0 special considerations:
50                  *
51 +                * Since the core supports both OHCI and EHCI functions, 
52 +                * it must only be reset once.
53 +                *
54                  * In addition to the standard SSB reset sequence, the Host
55                  * Control Register must be programmed to bring the USB core
56                  * and various phy components out of reset.
57 @@ -175,6 +194,14 @@ static int ssb_ohci_attach(struct ssb_de
58  
59         ssb_set_drvdata(dev, hcd);
60  
61 +#ifdef CONFIG_USB_EHCI_HCD_SSB
62 +       /*
63 +        *  attach ehci function in this core
64 +        */
65 +       if (dev->id.coreid == SSB_DEV_USB20_HOST)
66 +               err = ssb_ehci_attach(dev, &(ohcidev->ehci_hcd));
67 +#endif
68 +
69         return err;
70  
71  err_iounmap:
72 --- a/drivers/usb/host/ehci-ssb.c
73 +++ b/drivers/usb/host/ehci-ssb.c
74 @@ -106,10 +106,18 @@ static void ssb_ehci_detach(struct ssb_d
75         iounmap(hcd->regs);
76         release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
77         usb_put_hcd(hcd);
78 +#ifndef CONFIG_USB_OHCI_HCD_SSB
79 +       ssb_device_disable(dev, 0);
80 +#endif
81         ssb_device_disable(dev, 0);
82  }
83 +EXPORT_SYMBOL_GPL(ssb_ehci_detach);
84  
85 +#ifndef CONFIG_USB_OHCI_HCD_SSB
86  static int ssb_ehci_attach(struct ssb_device *dev)
87 +#else
88 +static int ssb_ehci_attach(struct ssb_device *dev, struct usb_hcd **ehci_hcd)
89 +#endif
90  {
91         struct ssb_ehci_device *ehcidev;
92         struct usb_hcd *hcd;
93 @@ -120,6 +128,7 @@ static int ssb_ehci_attach(struct ssb_de
94             dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
95                 return -EOPNOTSUPP;
96  
97 +#ifndef CONFIG_USB_OHCI_HCD_SSB
98         /*
99          * USB 2.0 special considerations:
100          *
101 @@ -155,6 +164,7 @@ static int ssb_ehci_attach(struct ssb_de
102                 tmp |= 0x1;
103                 ssb_write32(dev, 0x89c, tmp);
104         }
105 +#endif
106  
107         hcd = usb_create_hcd(&ssb_ehci_hc_driver, dev->dev,
108                              dev_name(dev->dev));
109 @@ -175,7 +185,11 @@ static int ssb_ehci_attach(struct ssb_de
110         if (err)
111                 goto err_iounmap;
112  
113 +#ifndef CONFIG_USB_OHCI_HCD_SSB
114         ssb_set_drvdata(dev, hcd);
115 +#else
116 +       *ehci_hcd = hcd;
117 +#endif
118  
119         return err;
120  
121 @@ -187,7 +201,9 @@ err_dev_disable:
122         ssb_device_disable(dev, 0);
123         return err;
124  }
125 +EXPORT_SYMBOL_GPL(ssb_ehci_attach);
126  
127 +#ifndef CONFIG_USB_OHCI_HCD_SSB
128  static int ssb_ehci_probe(struct ssb_device *dev,
129                 const struct ssb_device_id *id)
130  {
131 @@ -238,6 +254,7 @@ static int ssb_ehci_resume(struct ssb_de
132  #define ssb_ehci_suspend       NULL
133  #define ssb_ehci_resume        NULL
134  #endif /* CONFIG_PM */
135 +#endif /* !CONFIG_USB_OHCI_HCD_SSB */
136  
137  static const struct ssb_device_id ssb_ehci_table[] = {
138         SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
139 @@ -245,6 +262,8 @@ static const struct ssb_device_id ssb_eh
140  };
141  MODULE_DEVICE_TABLE(ssb, ssb_ehci_table);
142  
143 +
144 +#ifndef CONFIG_USB_OHCI_HCD_SSB
145  static struct ssb_driver ssb_ehci_driver = {
146         .name           = KBUILD_MODNAME,
147         .id_table       = ssb_ehci_table,
148 @@ -253,3 +272,4 @@ static struct ssb_driver ssb_ehci_driver
149         .suspend        = ssb_ehci_suspend,
150         .resume         = ssb_ehci_resume,
151  };
152 +#endif
153 --- a/drivers/usb/host/ehci-hcd.c
154 +++ b/drivers/usb/host/ehci-hcd.c
155 @@ -1350,17 +1350,21 @@ static int __init ehci_hcd_init(void)
156                 goto clean4;
157  #endif
158  
159 +#ifndef CONFIG_USB_OHCI_HCD_SSB
160  #ifdef SSB_EHCI_DRIVER
161         retval = ssb_driver_register(&SSB_EHCI_DRIVER);
162         if (retval < 0)
163                 goto clean5;
164  #endif
165 +#endif /* !CONFIG_USB_OHCI_HCD_SSB */
166         return retval;
167  
168 +#ifndef CONFIG_USB_OHCI_HCD_SSB
169  #ifdef SSB_EHCI_DRIVER
170         /* ssb_driver_unregister(&SSB_EHCI_DRIVER); */
171  clean5:
172  #endif
173 +#endif /* !CONFIG_USB_OHCI_HCD_SSB */
174  #ifdef XILINX_OF_PLATFORM_DRIVER
175         platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER);
176  clean4:
177 @@ -1393,9 +1397,11 @@ module_init(ehci_hcd_init);
178  
179  static void __exit ehci_hcd_cleanup(void)
180  {
181 +#ifndef CONFIG_USB_OHCI_HCD_SSB
182  #ifdef SSB_EHCI_DRIVER
183         ssb_driver_unregister(&SSB_EHCI_DRIVER);
184  #endif
185 +#endif /* !CONFIG_USB_OHCI_HCD_SSB */
186  #ifdef XILINX_OF_PLATFORM_DRIVER
187         platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER);
188  #endif