of: Always use 'struct device.of_node' to get device node pointer.
[safe/jmp/linux-2.6] / drivers / usb / host / ohci-ppc-of.c
index 50e55db..003aea2 100644 (file)
@@ -14,8 +14,8 @@
  */
 
 #include <linux/signal.h>
+#include <linux/of_platform.h>
 
-#include <asm/of_platform.h>
 #include <asm/prom.h>
 
 
@@ -83,7 +83,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = {
 static int __devinit
 ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct device_node *dn = op->node;
+       struct device_node *dn = op->dev.of_node;
        struct usb_hcd *hcd;
        struct ohci_hcd *ohci;
        struct resource res;
@@ -91,6 +91,7 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
 
        int rv;
        int is_bigendian;
+       struct device_node *np;
 
        if (usb_disabled())
                return -ENODEV;
@@ -113,21 +114,21 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
        hcd->rsrc_len = res.end - res.start + 1;
 
        if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-               printk(KERN_ERR __FILE__ ": request_mem_region failed\n");
+               printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__);
                rv = -EBUSY;
                goto err_rmr;
        }
 
        irq = irq_of_parse_and_map(dn, 0);
        if (irq == NO_IRQ) {
-               printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n");
+               printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__);
                rv = -EBUSY;
                goto err_irq;
        }
 
        hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
        if (!hcd->regs) {
-               printk(KERN_ERR __FILE__ ": ioremap failed\n");
+               printk(KERN_ERR "%s: ioremap failed\n", __FILE__);
                rv = -ENOMEM;
                goto err_ioremap;
        }
@@ -147,6 +148,30 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
        if (rv == 0)
                return 0;
 
+       /* by now, 440epx is known to show usb_23 erratum */
+       np = of_find_compatible_node(NULL, NULL, "ibm,usb-ehci-440epx");
+
+       /* Work around - At this point ohci_run has executed, the
+       * controller is running, everything, the root ports, etc., is
+       * set up.  If the ehci driver is loaded, put the ohci core in
+       * the suspended state.  The ehci driver will bring it out of
+       * suspended state when / if a non-high speed USB device is
+       * attached to the USB Host port.  If the ehci driver is not
+       * loaded, do nothing. request_mem_region is used to test if
+       * the ehci driver is loaded.
+       */
+       if (np !=  NULL) {
+               if (!of_address_to_resource(np, 0, &res)) {
+                       if (!request_mem_region(res.start, 0x4, hcd_name)) {
+                               writel_be((readl_be(&ohci->regs->control) |
+                                       OHCI_USB_SUSPEND), &ohci->regs->control);
+                                       (void) readl_be(&ohci->regs->control);
+                       } else
+                               release_mem_region(res.start, 0x4);
+               } else
+                       pr_debug("%s: cannot get ehci offset from fdt\n", __FILE__);
+       }
+
        iounmap(hcd->regs);
 err_ioremap:
        irq_dispose_mapping(irq);
@@ -187,7 +212,7 @@ static int ohci_hcd_ppc_of_shutdown(struct of_device *op)
 }
 
 
-static struct of_device_id ohci_hcd_ppc_of_match[] = {
+static const struct of_device_id ohci_hcd_ppc_of_match[] = {
 #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE
        {
                .name = "usb",