#include <asm/arch/pxafb.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/irda.h>
+#include <asm/arch/ohci.h>
 
 #include "generic.h"
 
        &mst_flash_device[1],
 };
 
+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)
 {
        int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
 
        pxa_set_mci_info(&mainstone_mci_platform_data);
        pxa_set_ficp_info(&mainstone_ficp_platform_data);
+       pxa_set_ohci_info(&mainstone_ohci_platform_data);
 }
 
 
 
 #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.
  */
 static int pxa27x_ohci_select_pmm( int mode )
 {
-       pxa27x_ohci_pmm_state = mode;
-
        switch ( mode ) {
        case PMM_NPS_MODE:
                UHCRHDA |= RH_A_NPS;
                        "Invalid mode %d, set to non-power switch mode.\n", 
                        mode );
 
-               pxa27x_ohci_pmm_state = PMM_NPS_MODE;
                UHCRHDA |= RH_A_NPS;
        }
 
 
 /*-------------------------------------------------------------------------*/
 
-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;
        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;
 
        /* 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;
  * 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 platform_device *pdev)
 {
        int retval;
        struct usb_hcd *hcd;
+       struct pxaohci_platform_data *inf;
+
+       inf = pdev->dev.platform_data;
 
-       if (dev->resource[1].flags != IORESOURCE_IRQ) {
+       if (!inf)
+               return -ENODEV;
+
+       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, &pdev->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");
                goto err2;
        }
 
-       pxa27x_start_hc(dev);
+       if ((retval = pxa27x_start_hc(&pdev->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);
+       pxa27x_stop_hc(&pdev->dev);
+ err3:
        iounmap(hcd->regs);
  err2:
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  * 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 platform_device *pdev)
 {
        usb_remove_hcd(hcd);
-       pxa27x_stop_hc(dev);
+       pxa27x_stop_hc(&pdev->dev);
        iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
 
 static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
 {
-       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, pdev);
 }
 
 static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)