<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//DE"><HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii"><TITLE>Message</TITLE></HEAD><BODY>
          <pre>This patch use of_platform device to probe and install OHCI big endian HC.<br><br>PS: I did not success to properly inline the file using thrunderbird.<br><br>Signed-off-by: Nicolas DET &lt;nd@bplan-gmbh.de&gt; <br>---<br>--- a/drivers/usb/host/ohci-ppc-of.c        1970-01-01 01:00:00.000000000 +0100<br>+++ b/drivers/usb/host/ohci-ppc-of.c        2006-11-06 11:10:29.000000000 +0100<br>@@ -0,0 +1,283 @@<br>+/*<br>+ * OHCI HCD (Host Controller Driver) for USB.<br>+ *<br>+ * (C) Copyright 1999 Roman Weissgaerber &lt;weissg@vienna.at&gt;<br>+ * (C) Copyright 2000-2002 David Brownell &lt;dbrownell@users.sourceforge.net&gt;<br>+ * (C) Copyright 2002 Hewlett-Packard Company<br>+ * (C) Copyright 2003-2005 MontaVista Software Inc.<br>+ * <br>+ * Probe and init OHCI Big endian HC from OpenFirmware device tree<br>+ * Tested on Efika 5k2<br>+ *<br>+ * Modified by Dale Farnsworth &lt;dale@farnsworth.org&gt; from ohci-sa1111.c<br>+ *<br>+ * This file is licenced under the GPL.<br>+ */<br>+<br>+#include &lt;linux/signal.h&gt;<br>+<br>+#include &lt;asm/of_device.h&gt;<br>+#include &lt;asm/prom.h&gt;<br>+<br>+/* configure so an HC device and id are always provided */<br>+/* always called with process context; sleeping is OK */<br>+<br>+/*<br>+ * usb_hcd_ppc_of_probe - initialize On-Chip HCDs<br>+ * Context: !in_interrupt()<br>+ *<br>+ * Allocates basic resources for this USB host controller.<br>+ *<br>+ * Store this function in the HCD's struct pci_driver as probe().<br>+ */<br>+static int usb_hcd_ppc_of_probe(const struct hc_driver *driver,<br>+                          struct of_device *dev, int is_bigendian)<br>+{<br>+        int retval;<br>+        struct usb_hcd *hcd;<br>+        struct ohci_hcd        *ohci;<br>+        struct resource res;<br>+        int irq;<br>+        int ret;<br>+<br>+        pr_debug("initializing PPC-OF USB Controllern");<br>+<br>+        if ((ret = of_address_to_resource(dev-&gt;node, 0, &amp;res)) != 0)<br>+                return ret;<br>+<br>+        hcd = usb_create_hcd(driver, &amp;dev-&gt;dev, "PPC-OF USB");<br>+        if (!hcd)<br>+                return -ENOMEM;<br>+<br>+        hcd-&gt;rsrc_start = res.start;<br>+        hcd-&gt;rsrc_len = res.end - res.start + 1;<br>+<br>+        if (!request_mem_region(hcd-&gt;rsrc_start, hcd-&gt;rsrc_len, hcd_name)) {<br>+                pr_debug(__FILE__ ": request_mem_region failedn");<br>+                retval = -EBUSY;<br>+                goto err1;<br>+        }<br>+<br>+        irq = irq_of_parse_and_map(dev-&gt;node, 0);<br>+        if (irq == NO_IRQ) {<br>+                retval = -EBUSY;<br>+                goto err2;<br>+        }<br>+<br>+        hcd-&gt;regs = ioremap(hcd-&gt;rsrc_start, hcd-&gt;rsrc_len);<br>+        if (!hcd-&gt;regs) {<br>+                pr_debug(__FILE__ ": ioremap failedn");<br>+                retval = -ENOMEM;<br>+                goto err2;<br>+        }<br>+<br>+        ohci = hcd_to_ohci(hcd);<br>+        if (is_bigendian)<br>+                ohci-&gt;flags |= OHCI_BIG_ENDIAN;<br>+<br>+        ohci_hcd_init(ohci);<br>+<br>+        retval = usb_add_hcd(hcd, irq, 0);<br>+        if (retval == 0)<br>+                return retval;<br>+<br>+        pr_debug("Removing PPC-OF USB Controllern");<br>+<br>+        iounmap(hcd-&gt;regs);<br>+ err2:<br>+        release_mem_region(hcd-&gt;rsrc_start, hcd-&gt;rsrc_len);<br>+ err1:<br>+         usb_put_hcd(hcd);<br>+        return retval;<br>+}<br>+<br>+<br>+/* may be called without controller electrically present */<br>+/* may be called with controller, bus, and devices active */<br>+<br>+/*<br>+ * usb_hcd_ppc_of_remove - shutdown processing for On-Chip HCDs<br>+ * @pdev: USB Host Controller being removed<br>+ * Context: !in_interrupt()<br>+ *<br>+ * Reverses the effect of usb_hcd_ppc_of_probe().<br>+ * It is always called from a thread<br>+ * context, normally "rmmod", "apmd", or something similar.<br>+ *<br>+ */<br>+static void usb_hcd_ppc_of_remove(struct usb_hcd *hcd,<br>+                struct of_device *op)<br>+{<br>+        usb_remove_hcd(hcd);<br>+<br>+        pr_debug("stopping PPC-OF USB Controllern");<br>+<br>+        iounmap(hcd-&gt;regs);<br>+        release_mem_region(hcd-&gt;rsrc_start, hcd-&gt;rsrc_len);<br>+        usb_put_hcd(hcd);<br>+}<br>+<br>+static int __devinit<br>+ohci_ppc_of_start(struct usb_hcd *hcd)<br>+{<br>+        struct ohci_hcd        *ohci = hcd_to_ohci(hcd);<br>+        int                ret;<br>+<br>+        if ((ret = ohci_init(ohci)) &lt; 0)<br>+                return ret;<br>+<br>+        if ((ret = ohci_run(ohci)) &lt; 0) {<br>+                err("can't start %s", ohci_to_hcd(ohci)-&gt;self.bus_name);<br>+                ohci_stop(hcd);<br>+                return ret;<br>+        }<br>+<br>+        return 0;<br>+}<br>+<br>+static const struct hc_driver ohci_ppc_of_hc_driver = {<br>+        .description =                hcd_name,<br>+        .hcd_priv_size =        sizeof(struct ohci_hcd),<br>+<br>+        /*<br>+         * generic hardware linkage<br>+         */<br>+        .irq =                        ohci_irq,<br>+        .flags =                HCD_USB11 | HCD_MEMORY,<br>+<br>+        /*<br>+         * basic lifecycle operations<br>+         */<br>+        .start =                ohci_ppc_of_start,<br>+        .stop =                        ohci_stop,<br>+        .shutdown =                 ohci_shutdown,<br>+<br>+        /*<br>+         * managing i/o requests and associated device resources<br>+         */<br>+        .urb_enqueue =                ohci_urb_enqueue,<br>+        .urb_dequeue =                ohci_urb_dequeue,<br>+        .endpoint_disable =        ohci_endpoint_disable,<br>+<br>+        /*<br>+         * scheduling support<br>+         */<br>+        .get_frame_number =        ohci_get_frame,<br>+<br>+        /*<br>+         * root hub support<br>+         */<br>+        .hub_status_data =        ohci_hub_status_data,<br>+        .hub_control =                ohci_hub_control,<br>+        .hub_irq_enable =        ohci_rhsc_enable,<br>+#ifdef        CONFIG_PM<br>+        .bus_suspend =                ohci_bus_suspend,<br>+        .bus_resume =                ohci_bus_resume,<br>+#endif<br>+        .start_port_reset =        ohci_start_port_reset,<br>+};<br>+<br>+<br>+<br>+static int ohci_hcd_ppc_of_drv_remove(struct of_device *op)<br>+{<br>+        struct usb_hcd *hcd = dev_get_drvdata(&amp;op-&gt;dev);<br>+        dev_set_drvdata(&amp;op-&gt;dev, NULL);<br>+<br>+        usb_hcd_ppc_of_remove(hcd, op);<br>+        return 0;<br>+}<br>+<br>+static int ohci_hcd_ppc_of_drv_shutdown(struct of_device *op)<br>+{<br>+        struct usb_hcd *hcd = dev_get_drvdata(&amp;op-&gt;dev);<br>+<br>+        if (hcd-&gt;driver-&gt;shutdown)<br>+                hcd-&gt;driver-&gt;shutdown(hcd);<br>+<br>+        return 0;<br>+}<br>+<br>+/*<br>+ *<br>+*/<br>+<br>+static struct of_device_id ohci_hcd_ppc_of_match[] = {<br>+#ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE<br>+        {<br>+                .name = "usb",<br>+                .compatible = "ohci-bigendian",<br>+        },<br>+        {<br>+                .name = "usb",<br>+                .compatible = "ohci-be",<br>+        },<br>+#endif<br>+#ifdef CONFIG_USB_OHCI_HCD_PPC_OF_LE<br>+        {<br>+                .name = "usb",<br>+                .compatible = "ohci-littledian",<br>+        },<br>+        {<br>+                .name = "usb",<br>+                .compatible = "ohci-le",<br>+        },<br>+#endif<br>+        {},<br>+};<br>+<br>+static int __devinit<br>+ohci_hcd_ppc_of_drv_probe(struct of_device *op, const struct of_device_id *match)<br>+{<br>+        struct device_node *dev;<br>+        int ret;<br>+        int is_bigendian;<br>+<br>+        if (usb_disabled())<br>+                return -ENODEV;<br>+<br>+        dev = op-&gt;node;<br>+        is_bigendian = 0;<br>+<br>+        if ( device_is_compatible(dev, "ohci-bigendian") )<br>+                is_bigendian = 1;<br>+<br>+        if ( device_is_compatible(dev, "ohci-be") )<br>+                is_bigendian = 1;        <br>+<br>+        ret = usb_hcd_ppc_of_probe(&amp;ohci_ppc_of_hc_driver, op, is_bigendian);<br>+        return ret;<br>+}<br>+<br>+static struct of_platform_driver ohci_hcd_ppc_of_driver = {<br>+        .name        = "ppc-of-ohci",<br>+        .match_table        = ohci_hcd_ppc_of_match,<br>+        .probe                = ohci_hcd_ppc_of_drv_probe,<br>+        .remove                = ohci_hcd_ppc_of_drv_remove,<br>+        .shutdown         = ohci_hcd_ppc_of_drv_shutdown,<br>+#ifdef        CONFIG_PM<br>+        /*.suspend        = ohci_hcd_ppc_soc_drv_suspend,*/<br>+        /*.resume        = ohci_hcd_ppc_soc_drv_resume,*/<br>+#endif<br>+        .driver                = {<br>+                .name        = "ppc-of-ohci",<br>+                .owner        = THIS_MODULE,<br>+        },<br>+};<br>+<br>+static int __init ohci_hcd_ppc_of_init(void)<br>+{<br>+        pr_debug(DRIVER_INFO " (PPC OF)n");<br>+        pr_debug("block sizes: ed %d td %dn", sizeof(struct ed),<br>+                                                        sizeof(struct td));<br>+        <br>+        return of_register_driver(&amp;ohci_hcd_ppc_of_driver);    <br>+}<br>+<br>+static void __exit ohci_hcd_ppc_of_cleanup(void)<br>+{<br>+        of_unregister_driver(&amp;ohci_hcd_ppc_of_driver);<br>+}<br>+<br>+module_init(ohci_hcd_ppc_of_init);<br>+module_exit(ohci_hcd_ppc_of_cleanup);<br>--- a/drivers/usb/host/Kconfig        2006-11-01 09:18:56.000000000 +0100<br>+++ b/drivers/usb/host/Kconfig        2006-11-06 11:10:29.000000000 +0100<br>@@ -106,6 +106,25 @@ config USB_OHCI_HCD_PPC_SOC<br>           Enables support for the USB controller on the MPC52xx or<br>           STB03xxx processor chip.  If unsure, say Y.<br> <br>+config USB_OHCI_HCD_PPC_OF<br>+        bool "OHCI support for PPC USB controller for OpenFirmware platform"<br>+        depends on USB_OHCI_HCD &amp;&amp; PPC_OF<br>+        default y<br>+        ---help---<br>+          Enables support for the USB controller PowerPC OpenFirmware platform<br>+<br>+config USB_OHCI_HCD_PPC_OF_BE<br>+        bool "Support big endian HC"<br>+        depends on USB_OHCI_HCD_PPC_OF<br>+        default y<br>+        select USB_OHCI_BIG_ENDIAN<br>+<br>+config USB_OHCI_HCD_PPC_OF_LE<br>+        bool "Support little endian HC"<br>+        depends on USB_OHCI_HCD_PPC_OF<br>+        default n<br>+        select USB_OHCI_LITTLE_ENDIAN<br>+<br> config USB_OHCI_HCD_PCI<br>         bool "OHCI support for PCI-bus USB controllers"<br>         depends on USB_OHCI_HCD &amp;&amp; PCI &amp;&amp; (STB03xxx || PPC_MPC52xx)<br>--- a/drivers/usb/host/ohci-hcd.c        2006-11-01 09:18:56.000000000 +0100<br>+++ b/drivers/usb/host/ohci-hcd.c        2006-11-06 11:10:29.000000000 +0100<br>@@ -930,6 +930,10 @@ MODULE_LICENSE ("GPL");<br> #include "ohci-ppc-soc.c"<br> #endif<br> <br>+#ifdef CONFIG_USB_OHCI_HCD_PPC_OF<br>+#include "ohci-ppc-of.c"<br>+#endif<br>+<br> #if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261)<br> #include "ohci-at91.c"<br> #endif<br>@@ -950,6 +954,8 @@ MODULE_LICENSE ("GPL");<br>       || defined (CONFIG_ARCH_AT91RM9200) <br>       || defined (CONFIG_ARCH_AT91SAM9261) <br>       || defined (CONFIG_ARCH_PNX4008) <br>+      || defined (CONFIG_USB_OHCI_HCD_PPC_OF_LE) <br>+      || defined (CONFIG_USB_OHCI_HCD_PPC_OF_BE) <br>         )<br> #error "missing bus glue for ohci-hcd"<br> #endif<br><br></pre></BODY></HTML>