To allow multiple platforms to use the PXA27x OHCI driver, the platform
code needs to be moved into the board specific files in
arch/arm/mach-pxa. This patch does this for mainstone and adds
preliminary hooks to allow other boards to use the driver.

This has been compile tested for mainstone and successfully run on Spitz
(Sharp Zaurus SL-C3000) with the addition of an appropriate board
support file.

Signed-Off-By: Richard Purdie <[EMAIL PROTECTED]>
Signed-off-by: Nicolas Pitre <[EMAIL PROTECTED]>

Index: linux-2.6.13/drivers/usb/host/ohci-pxa27x.c
===================================================================
--- linux-2.6.13.orig/drivers/usb/host/ohci-pxa27x.c    2005-09-13 
16:38:45.000000000 +0100
+++ linux-2.6.13/drivers/usb/host/ohci-pxa27x.c 2005-09-13 16:39:13.000000000 
+0100
@@ -23,18 +23,12 @@
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
 #include <asm/arch/pxa-regs.h>
-
-
-#define PMM_NPS_MODE           1
-#define PMM_GLOBAL_MODE        2
-#define PMM_PERPORT_MODE       3
+#include <asm/arch/ohci.h>
 
 #define PXA_UHC_MAX_PORTNUM    3
 
 #define UHCRHPS(x)              __REG2( 0x4C000050, (x)<<2 )
 
-static int pxa27x_ohci_pmm_state;
-
 /*
   PMM_NPS_MODE -- PMM Non-power switching mode
       Ports are powered continuously.
@@ -47,8 +41,6 @@
  */
 static int pxa27x_ohci_select_pmm( int mode )
 {
-       pxa27x_ohci_pmm_state = mode;
-
        switch ( mode ) {
        case PMM_NPS_MODE:
                UHCRHDA |= RH_A_NPS;
@@ -68,7 +60,6 @@
                        "Invalid mode %d, set to non-power switch mode.\n", 
                        mode );
 
-               pxa27x_ohci_pmm_state = PMM_NPS_MODE;
                UHCRHDA |= RH_A_NPS;
        }
 
@@ -79,8 +70,13 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void pxa27x_start_hc(struct platform_device *dev)
+static int pxa27x_start_hc(struct device *dev)
 {
+       int retval = 0;
+       struct pxaohci_platform_data *inf;
+
+       inf = dev->platform_data;
+
        pxa_set_cken(CKEN10_USBHOST, 1);
 
        UHCHR |= UHCHR_FHR;
@@ -91,21 +87,11 @@
        while (UHCHR & UHCHR_FSBIR)
                cpu_relax();
 
-       /* This could be properly abstracted away through the
-          device data the day more machines are supported and
-          their differences can be figured out correctly. */
-       if (machine_is_mainstone()) {
-               /* setup Port1 GPIO pin. */
-               pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);  /* USBHPWR1 */
-               pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
-
-               /* Set the Power Control Polarity Low and Power Sense
-                  Polarity Low to active low. Supply power to USB ports. */
-               UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
-                       ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+       if (inf->init)
+               retval = inf->init(dev);
 
-               pxa27x_ohci_pmm_state = PMM_PERPORT_MODE;
-       }
+       if (retval < 0)
+               return retval;
 
        UHCHR &= ~UHCHR_SSE;
 
@@ -114,10 +100,19 @@
        /* Clear any OTG Pin Hold */
        if (PSSR & PSSR_OTGPH)
                PSSR |= PSSR_OTGPH;
+
+       return 0;
 }
 
-static void pxa27x_stop_hc(struct platform_device *dev)
+static void pxa27x_stop_hc(struct device *dev)
 {
+       struct pxaohci_platform_data *inf;
+
+       inf = dev->platform_data;
+
+       if (inf->exit)
+               inf->exit(dev);
+
        UHCHR |= UHCHR_FHR;
        udelay(11);
        UHCHR &= ~UHCHR_FHR;
@@ -144,22 +139,28 @@
  * through the hotplug entry's driver_data.
  *
  */
-int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
-                         struct platform_device *dev)
+int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct device *dev)
 {
        int retval;
        struct usb_hcd *hcd;
+       struct pxaohci_platform_data *inf;
+       struct platform_device *pdev = to_platform_device(dev);
+
+       inf = dev->platform_data;
+
+       if (!inf)
+               return -ENODEV;
 
-       if (dev->resource[1].flags != IORESOURCE_IRQ) {
+       if (pdev->resource[1].flags != IORESOURCE_IRQ) {
                pr_debug ("resource[1] is not IORESOURCE_IRQ");
                return -ENOMEM;
        }
 
-       hcd = usb_create_hcd (driver, &dev->dev, "pxa27x");
+       hcd = usb_create_hcd (driver, dev, "pxa27x");
        if (!hcd)
                return -ENOMEM;
-       hcd->rsrc_start = dev->resource[0].start;
-       hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
+       hcd->rsrc_start = pdev->resource[0].start;
+       hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
 
        if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
                pr_debug("request_mem_region failed");
@@ -174,18 +175,22 @@
                goto err2;
        }
 
-       pxa27x_start_hc(dev);
+       if ((retval = pxa27x_start_hc(dev)) < 0) {
+               pr_debug("pxa27x_start_hc failed");
+               goto err3;
+       }
 
        /* Select Power Management Mode */
-       pxa27x_ohci_select_pmm(pxa27x_ohci_pmm_state);
+       pxa27x_ohci_select_pmm(inf->port_mode);
 
        ohci_hcd_init(hcd_to_ohci(hcd));
 
-       retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
+       retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
        if (retval == 0)
                return retval;
 
        pxa27x_stop_hc(dev);
+ err3:
        iounmap(hcd->regs);
  err2:
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@@ -208,7 +213,7 @@
  * context, normally "rmmod", "apmd", or something similar.
  *
  */
-void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev)
+void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct device *dev)
 {
        usb_remove_hcd(hcd);
        pxa27x_stop_hc(dev);
@@ -288,24 +293,19 @@
 
 static int ohci_hcd_pxa27x_drv_probe(struct device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       int ret;
-
        pr_debug ("In ohci_hcd_pxa27x_drv_probe");
 
        if (usb_disabled())
                return -ENODEV;
 
-       ret = usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev);
-       return ret;
+       return usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, dev);
 }
 
 static int ohci_hcd_pxa27x_drv_remove(struct device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
        struct usb_hcd *hcd = dev_get_drvdata(dev);
 
-       usb_hcd_pxa27x_remove(hcd, pdev);
+       usb_hcd_pxa27x_remove(hcd, dev);
        return 0;
 }
 
Index: linux-2.6.13/arch/arm/mach-pxa/pxa27x.c
===================================================================
--- linux-2.6.13.orig/arch/arm/mach-pxa/pxa27x.c        2005-09-13 
16:38:44.000000000 +0100
+++ linux-2.6.13/arch/arm/mach-pxa/pxa27x.c     2005-09-13 16:39:13.000000000 
+0100
@@ -21,6 +21,7 @@
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/ohci.h>
 
 #include "generic.h"
 
@@ -194,6 +195,11 @@
        .resource       = pxa27x_ohci_resources,
 };
 
+void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
+{
+       ohci_device.dev.platform_data = info;
+}
+
 static struct platform_device *devices[] __initdata = {
        &ohci_device,
 };
Index: linux-2.6.13/include/asm-arm/arch-pxa/ohci.h
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.13/include/asm-arm/arch-pxa/ohci.h        2005-09-13 
16:39:13.000000000 +0100
@@ -0,0 +1,18 @@
+#ifndef ASMARM_ARCH_OHCI_H
+#define ASMARM_ARCH_OHCI_H
+
+struct device;
+
+struct pxaohci_platform_data {
+       int (*init)(struct device *);
+       void (*exit)(struct device *);
+
+       int port_mode;
+#define PMM_NPS_MODE           1
+#define PMM_GLOBAL_MODE        2
+#define PMM_PERPORT_MODE       3
+};
+
+extern void pxa_set_ohci_info(struct pxaohci_platform_data *info);
+
+#endif
Index: linux-2.6.13/arch/arm/mach-pxa/mainstone.c
===================================================================
--- linux-2.6.13.orig/arch/arm/mach-pxa/mainstone.c     2005-09-13 
16:38:44.000000000 +0100
+++ linux-2.6.13/arch/arm/mach-pxa/mainstone.c  2005-09-13 16:39:13.000000000 
+0100
@@ -37,6 +37,7 @@
 #include <asm/arch/audio.h>
 #include <asm/arch/pxafb.h>
 #include <asm/arch/mmc.h>
+#include <asm/arch/ohci.h>
 
 #include "generic.h"
 
@@ -294,6 +295,25 @@
        .exit           = mainstone_mci_exit,
 };
 
+static int mainstone_ohci_init(struct device *dev)
+{
+       /* setup Port1 GPIO pin. */
+       pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);  /* USBHPWR1 */
+       pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
+
+       /* Set the Power Control Polarity Low and Power Sense
+          Polarity Low to active low. */
+       UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
+               ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+
+       return 0;
+}
+
+static struct pxaohci_platform_data mainstone_ohci_platform_data = {
+       .port_mode      = PMM_PERPORT_MODE,
+       .init           = mainstone_ohci_init,
+};
+
 static void __init mainstone_init(void)
 {
        /*
@@ -313,6 +333,7 @@
                set_pxa_fb_info(&toshiba_ltm035a776c);
 
        pxa_set_mci_info(&mainstone_mci_platform_data);
+       pxa_set_ohci_info(&mainstone_ohci_platform_data);
 }
 
 




-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to