On Tuesday 12 December 2006 10:11 am, Sylvain Munaut wrote:
> PPC embedded systems can have a ohci controller builtin. In the
> new model, it will end up as a driver on the of_platform bus,
> this patches takes care of them.
>
> Signed-off-by: Sylvain Munaut <[EMAIL PROTECTED]>
Acked-by: David Brownell <[EMAIL PROTECTED]>
> ---
> drivers/usb/host/Kconfig | 23 ++++
> drivers/usb/host/ohci-hcd.c | 20 +++
> drivers/usb/host/ohci-ppc-of.c | 232
> ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 274 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 8325998..6271187 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -112,9 +112,30 @@ config USB_OHCI_HCD_PPC_SOC
> Enables support for the USB controller on the MPC52xx or
> STB03xxx processor chip. If unsure, say Y.
>
> +config USB_OHCI_HCD_PPC_OF
> + bool "OHCI support for PPC USB controller on OF platform bus"
> + depends on USB_OHCI_HCD && PPC_OF
> + default y
> + ---help---
> + Enables support for the USB controller PowerPC present on the
> + OpenFirmware platform bus.
> +
> +config USB_OHCI_HCD_PPC_OF_BE
> + bool "Support big endian HC"
> + depends on USB_OHCI_HCD_PPC_OF
> + default y
> + select USB_OHCI_BIG_ENDIAN_DESC
> + select USB_OHCI_BIG_ENDIAN_MMIO
> +
> +config USB_OHCI_HCD_PPC_OF_LE
> + bool "Support little endian HC"
> + depends on USB_OHCI_HCD_PPC_OF
> + default n
> + select USB_OHCI_LITTLE_ENDIAN
> +
> config USB_OHCI_HCD_PCI
> bool "OHCI support for PCI-bus USB controllers"
> - depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx)
> + depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx ||
> USB_OHCI_HCD_PPC_OF)
> default y
> select USB_OHCI_LITTLE_ENDIAN
> ---help---
> diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
> index d052041..8797c39 100644
> --- a/drivers/usb/host/ohci-hcd.c
> +++ b/drivers/usb/host/ohci-hcd.c
> @@ -964,8 +964,14 @@ #include "ohci-pnx4008.c"
> #define PLATFORM_DRIVER usb_hcd_pnx4008_driver
> #endif
>
> +#ifdef CONFIG_USB_OHCI_HCD_PPC_OF
> +#include "ohci-ppc-of.c"
> +#define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver
> +#endif
> +
> #if !defined(PCI_DRIVER) && \
> !defined(PLATFORM_DRIVER) && \
> + !defined(OF_PLATFORM_DRIVER) && \
> !defined(SA1111_DRIVER)
> #error "missing bus glue for ohci-hcd"
> #endif
> @@ -989,6 +995,13 @@ #ifdef PLATFORM_DRIVER
> ls++;
> #endif
>
> +#ifdef OF_PLATFORM_DRIVER
> + retval = of_register_platform_driver(&OF_PLATFORM_DRIVER);
> + if (retval < 0)
> + goto error;
> + ls++;
> +#endif
> +
> #ifdef SA1111_DRIVER
> retval = sa1111_driver_register(&SA1111_DRIVER);
> if (retval < 0)
> @@ -1011,6 +1024,10 @@ #ifdef PLATFORM_DRIVER
> if (ls--)
> platform_driver_unregister(&PLATFORM_DRIVER);
> #endif
> +#ifdef OF_PLATFORM_DRIVER
> + if (ls--)
> + of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
> +#endif
> #ifdef SA1111_DRIVER
> if (ls--)
> sa1111_driver_unregister(&SA1111_DRIVER);
> @@ -1027,6 +1044,9 @@ #endif
> #ifdef SA1111_DRIVER
> sa1111_driver_unregister(&SA1111_DRIVER);
> #endif
> +#ifdef OF_PLATFORM_DRIVER
> + of_unregister_platform_driver(&OF_PLATFORM_DRIVER);
> +#endif
> #ifdef PLATFORM_DRIVER
> platform_driver_unregister(&PLATFORM_DRIVER);
> #endif
> diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
> new file mode 100644
> index 0000000..84b555b
> --- /dev/null
> +++ b/drivers/usb/host/ohci-ppc-of.c
> @@ -0,0 +1,232 @@
> +/*
> + * OHCI HCD (Host Controller Driver) for USB.
> + *
> + * (C) Copyright 1999 Roman Weissgaerber <[EMAIL PROTECTED]>
> + * (C) Copyright 2000-2002 David Brownell <[EMAIL PROTECTED]>
> + * (C) Copyright 2002 Hewlett-Packard Company
> + * (C) Copyright 2006 Sylvain Munaut <[EMAIL PROTECTED]>
> + *
> + * Bus glue for OHCI HC on the of_platform bus
> + *
> + * Modified for of_platform bus from ohci-sa1111.c
> + *
> + * This file is licenced under the GPL.
> + */
> +
> +#include <linux/signal.h>
> +
> +#include <asm/of_platform.h>
> +#include <asm/prom.h>
> +
> +
> +static int __devinit
> +ohci_ppc_of_start(struct usb_hcd *hcd)
> +{
> + struct ohci_hcd *ohci = hcd_to_ohci(hcd);
> + int ret;
> +
> + if ((ret = ohci_init(ohci)) < 0)
> + return ret;
> +
> + if ((ret = ohci_run(ohci)) < 0) {
> + err("can't start %s", ohci_to_hcd(ohci)->self.bus_name);
> + ohci_stop(hcd);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static const struct hc_driver ohci_ppc_of_hc_driver = {
> + .description = hcd_name,
> + .product_desc = "OF OHCI",
> + .hcd_priv_size = sizeof(struct ohci_hcd),
> +
> + /*
> + * generic hardware linkage
> + */
> + .irq = ohci_irq,
> + .flags = HCD_USB11 | HCD_MEMORY,
> +
> + /*
> + * basic lifecycle operations
> + */
> + .start = ohci_ppc_of_start,
> + .stop = ohci_stop,
> + .shutdown = ohci_shutdown,
> +
> + /*
> + * managing i/o requests and associated device resources
> + */
> + .urb_enqueue = ohci_urb_enqueue,
> + .urb_dequeue = ohci_urb_dequeue,
> + .endpoint_disable = ohci_endpoint_disable,
> +
> + /*
> + * scheduling support
> + */
> + .get_frame_number = ohci_get_frame,
> +
> + /*
> + * root hub support
> + */
> + .hub_status_data = ohci_hub_status_data,
> + .hub_control = ohci_hub_control,
> + .hub_irq_enable = ohci_rhsc_enable,
> +#ifdef CONFIG_PM
> + .bus_suspend = ohci_bus_suspend,
> + .bus_resume = ohci_bus_resume,
> +#endif
> + .start_port_reset = ohci_start_port_reset,
> +};
> +
> +
> +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 usb_hcd *hcd;
> + struct ohci_hcd *ohci;
> + struct resource res;
> + int irq;
> +
> + int rv;
> + int is_bigendian;
> +
> + if (usb_disabled())
> + return -ENODEV;
> +
> + is_bigendian =
> + device_is_compatible(dn, "ohci-bigendian") ||
> + device_is_compatible(dn, "ohci-be");;
> +
> + dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n");
> +
> + rv = of_address_to_resource(dn, 0, &res);
> + if (rv)
> + return rv;
> +
> + hcd = usb_create_hcd(&ohci_ppc_of_hc_driver, &op->dev, "PPC-OF USB");
> + if (!hcd)
> + return -ENOMEM;
> +
> + hcd->rsrc_start = res.start;
> + 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");
> + 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");
> + rv = -EBUSY;
> + goto err_irq;
> + }
> +
> + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
> + if (!hcd->regs) {
> + printk(KERN_ERR __FILE__ ": ioremap failed\n");
> + rv = -ENOMEM;
> + goto err_ioremap;
> + }
> +
> + ohci = hcd_to_ohci(hcd);
> + if (is_bigendian)
> + ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
> +
> + ohci_hcd_init(ohci);
> +
> + rv = usb_add_hcd(hcd, irq, 0);
> + if (rv == 0)
> + return 0;
> +
> + iounmap(hcd->regs);
> +err_ioremap:
> + irq_dispose_mapping(irq);
> +err_irq:
> + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
> +err_rmr:
> + usb_put_hcd(hcd);
> +
> + return rv;
> +}
> +
> +static int ohci_hcd_ppc_of_remove(struct of_device *op)
> +{
> + struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
> + dev_set_drvdata(&op->dev, NULL);
> +
> + dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n");
> +
> + usb_remove_hcd(hcd);
> +
> + iounmap(hcd->regs);
> + irq_dispose_mapping(hcd->irq);
> + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
> +
> + usb_put_hcd(hcd);
> +
> + return 0;
> +}
> +
> +static int ohci_hcd_ppc_of_shutdown(struct of_device *op)
> +{
> + struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
> +
> + if (hcd->driver->shutdown)
> + hcd->driver->shutdown(hcd);
> +
> + return 0;
> +}
> +
> +
> +static struct of_device_id ohci_hcd_ppc_of_match[] = {
> +#ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE
> + {
> + .name = "usb",
> + .compatible = "ohci-bigendian",
> + },
> + {
> + .name = "usb",
> + .compatible = "ohci-be",
> + },
> +#endif
> +#ifdef CONFIG_USB_OHCI_HCD_PPC_OF_LE
> + {
> + .name = "usb",
> + .compatible = "ohci-littledian",
> + },
> + {
> + .name = "usb",
> + .compatible = "ohci-le",
> + },
> +#endif
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match);
> +
> +#if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \
> + !defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE)
> +#error "No endianess selected for ppc-of-ohci"
> +#endif
> +
> +
> +static struct of_platform_driver ohci_hcd_ppc_of_driver = {
> + .name = "ppc-of-ohci",
> + .match_table = ohci_hcd_ppc_of_match,
> + .probe = ohci_hcd_ppc_of_probe,
> + .remove = ohci_hcd_ppc_of_remove,
> + .shutdown = ohci_hcd_ppc_of_shutdown,
> +#ifdef CONFIG_PM
> + /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/
> + /*.resume = ohci_hcd_ppc_soc_drv_resume,*/
> +#endif
> + .driver = {
> + .name = "ppc-of-ohci",
> + .owner = THIS_MODULE,
> + },
> +};
> +
> --
> 1.4.2
>
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel