diff options
Diffstat (limited to 'drivers/usb/host/ehci-ppc-of.c')
-rw-r--r-- | drivers/usb/host/ehci-ppc-of.c | 45 |
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); |
182 | err_irq: | 198 | err_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); | ||
184 | err_rmr: | 203 | err_rmr: |
185 | usb_put_hcd(hcd); | 204 | usb_put_hcd(hcd); |
186 | 205 | ||
@@ -191,6 +210,11 @@ err_rmr: | |||
191 | static int ehci_hcd_ppc_of_remove(struct of_device *op) | 210 | static 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; |