<!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 <nd@bplan-gmbh.de> <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 <weissg@vienna.at><br>+ * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net><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 <dale@farnsworth.org> from ohci-sa1111.c<br>+ *<br>+ * This file is licenced under the GPL.<br>+ */<br>+<br>+#include <linux/signal.h><br>+<br>+#include <asm/of_device.h><br>+#include <asm/prom.h><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->node, 0, &res)) != 0)<br>+                return ret;<br>+<br>+        hcd = usb_create_hcd(driver, &dev->dev, "PPC-OF USB");<br>+        if (!hcd)<br>+                return -ENOMEM;<br>+<br>+        hcd->rsrc_start = res.start;<br>+        hcd->rsrc_len = res.end - res.start + 1;<br>+<br>+        if (!request_mem_region(hcd->rsrc_start, hcd->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->node, 0);<br>+        if (irq == NO_IRQ) {<br>+                retval = -EBUSY;<br>+                goto err2;<br>+        }<br>+<br>+        hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);<br>+        if (!hcd->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->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->regs);<br>+ err2:<br>+        release_mem_region(hcd->rsrc_start, hcd->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->regs);<br>+        release_mem_region(hcd->rsrc_start, hcd->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)) < 0)<br>+                return ret;<br>+<br>+        if ((ret = ohci_run(ohci)) < 0) {<br>+                err("can't start %s", ohci_to_hcd(ohci)->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(&op->dev);<br>+        dev_set_drvdata(&op->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(&op->dev);<br>+<br>+ if (hcd->driver->shutdown)<br>+ hcd->driver->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->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(&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(&ohci_hcd_ppc_of_driver); <br>+}<br>+<br>+static void __exit ohci_hcd_ppc_of_cleanup(void)<br>+{<br>+        of_unregister_driver(&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 && 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 && PCI && (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>