aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-ppc-of.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-ppc-of.c')
-rw-r--r--drivers/usb/host/ehci-ppc-of.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
index b018deed2e8f..ef732b704f53 100644
--- a/drivers/usb/host/ehci-ppc-of.c
+++ b/drivers/usb/host/ehci-ppc-of.c
@@ -107,11 +107,13 @@ ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
107{ 107{
108 struct device_node *dn = op->node; 108 struct device_node *dn = op->node;
109 struct usb_hcd *hcd; 109 struct usb_hcd *hcd;
110 struct ehci_hcd *ehci; 110 struct ehci_hcd *ehci = NULL;
111 struct resource res; 111 struct resource res;
112 int irq; 112 int irq;
113 int rv; 113 int rv;
114 114
115 struct device_node *np;
116
115 if (usb_disabled()) 117 if (usb_disabled())
116 return -ENODEV; 118 return -ENODEV;
117 119
@@ -149,6 +151,20 @@ ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
149 } 151 }
150 152
151 ehci = hcd_to_ehci(hcd); 153 ehci = hcd_to_ehci(hcd);
154 np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx");
155 if (np != NULL) {
156 /* claim we really affected by usb23 erratum */
157 if (!of_address_to_resource(np, 0, &res))
158 ehci->ohci_hcctrl_reg = ioremap(res.start +
159 OHCI_HCCTRL_OFFSET, OHCI_HCCTRL_LEN);
160 else
161 pr_debug(__FILE__ ": no ohci offset in fdt\n");
162 if (!ehci->ohci_hcctrl_reg) {
163 pr_debug(__FILE__ ": ioremap for ohci hcctrl failed\n");
164 } else {
165 ehci->has_amcc_usb23 = 1;
166 }
167 }
152 168
153 if (of_get_property(dn, "big-endian", NULL)) { 169 if (of_get_property(dn, "big-endian", NULL)) {
154 ehci->big_endian_mmio = 1; 170 ehci->big_endian_mmio = 1;
@@ -181,6 +197,9 @@ err_ioremap:
181 irq_dispose_mapping(irq); 197 irq_dispose_mapping(irq);
182err_irq: 198err_irq:
183 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 199 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
200
201 if (ehci->has_amcc_usb23)
202 iounmap(ehci->ohci_hcctrl_reg);
184err_rmr: 203err_rmr:
185 usb_put_hcd(hcd); 204 usb_put_hcd(hcd);
186 205
@@ -191,6 +210,11 @@ err_rmr:
191static int ehci_hcd_ppc_of_remove(struct of_device *op) 210static int ehci_hcd_ppc_of_remove(struct of_device *op)
192{ 211{
193 struct usb_hcd *hcd = dev_get_drvdata(&op->dev); 212 struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
213 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
214
215 struct device_node *np;
216 struct resource res;
217
194 dev_set_drvdata(&op->dev, NULL); 218 dev_set_drvdata(&op->dev, NULL);
195 219
196 dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n"); 220 dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n");
@@ -201,6 +225,25 @@ static int ehci_hcd_ppc_of_remove(struct of_device *op)
201 irq_dispose_mapping(hcd->irq); 225 irq_dispose_mapping(hcd->irq);
202 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 226 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
203 227
228 /* use request_mem_region to test if the ohci driver is loaded. if so
229 * ensure the ohci core is operational.
230 */
231 if (ehci->has_amcc_usb23) {
232 np = of_find_compatible_node(NULL, NULL, "ibm,usb-ohci-440epx");
233 if (np != NULL) {
234 if (!of_address_to_resource(np, 0, &res))
235 if (!request_mem_region(res.start,
236 0x4, hcd_name))
237 set_ohci_hcfs(ehci, 1);
238 else
239 release_mem_region(res.start, 0x4);
240 else
241 pr_debug(__FILE__ ": no ohci offset in fdt\n");
242 of_node_put(np);
243 }
244
245 iounmap(ehci->ohci_hcctrl_reg);
246 }
204 usb_put_hcd(hcd); 247 usb_put_hcd(hcd);
205 248
206 return 0; 249 return 0;