This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / usb / host / ohci-omap.c
index e3f2f2a..d133ff2 100644 (file)
@@ -42,7 +42,21 @@ extern int ocpi_enable(void);
 static int omap_ohci_clock_power(int on)
 {
        if (on) {
-               /* for 1510, 48MHz DPLL is set up in usb init */
+               if (cpu_is_omap1510()) {
+                       /* Use DPLL, not APLL */
+                       omap_writel(omap_readl(ULPD_APLL_CTRL) & ~APLL_NDPLL_SWITCH,
+                              ULPD_APLL_CTRL);
+
+                       /* Enable DPLL */
+                       omap_writel(omap_readl(ULPD_DPLL_CTRL) | DPLL_PLL_ENABLE,
+                              ULPD_DPLL_CTRL);
+
+                       /* Software request for USB 48MHz clock */
+                       omap_writel(omap_readl(ULPD_SOFT_REQ) | SOFT_REQ_REG_REQ,
+                              ULPD_SOFT_REQ);
+
+                       while (!(omap_readl(ULPD_DPLL_CTRL) & DPLL_LOCK));
+               }
 
                if (cpu_is_omap16xx()) {
                        /* Enable OHCI */
@@ -84,16 +98,14 @@ static int omap_ohci_transceiver_power(int on)
 {
        if (on) {
                if (machine_is_omap_innovator() && cpu_is_omap1510())
-                       fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL)
-                               | ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), 
+                       fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) | 0x20, 
                               INNOVATOR_FPGA_CAM_USB_CONTROL);
                else if (machine_is_omap_osk()) {
                        /* FIXME: GPIO1 -> 1 on the TPS65010 I2C chip */
                }
        } else {
                if (machine_is_omap_innovator() && cpu_is_omap1510())
-                       fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL)
-                               & ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), 
+                       fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) & ~0x20, 
                               INNOVATOR_FPGA_CAM_USB_CONTROL);
                else if (machine_is_omap_osk()) {
                        /* FIXME: GPIO1 -> 0 on the TPS65010 I2C chip */
@@ -310,7 +322,7 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
 
        retval = omap_start_hc(ohci, pdev);
        if (retval < 0)
-               goto err1;
+               goto err2;
 
        retval = hcd_buffer_create (hcd);
        if (retval != 0) {
@@ -330,7 +342,6 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
 
        usb_bus_init (&hcd->self);
        hcd->self.op = &usb_hcd_operations;
-       hcd->self.release = &usb_hcd_release;
        hcd->self.hcpriv = (void *) hcd;
        hcd->self.bus_name = pdev->dev.bus_id;
        hcd->product_desc = "OMAP OHCI";
@@ -348,8 +359,9 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
 
  err2:
        hcd_buffer_destroy (hcd);
+       if (hcd)
+               driver->hcd_free(hcd);
  err1:
-       kfree(hcd);
        omap_stop_hc(pdev);
 
        release_mem_region(pdev->resource[0].start, 
@@ -375,6 +387,8 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
  */
 void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+       void *base;
+
        dev_info(&pdev->dev, "remove: state %x\n", hcd->state);
 
        if (in_interrupt ())
@@ -396,6 +410,9 @@ void usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
        usb_deregister_bus (&hcd->self);
 
+       base = hcd->regs;
+       hcd->driver->hcd_free (hcd);
+
        omap_stop_hc(pdev);
 
        release_mem_region(pdev->resource[0].start, 
@@ -411,18 +428,40 @@ ohci_omap_start (struct usb_hcd *hcd)
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
        int             ret;
 
-       if ((ret = ohci_init(ohci)) < 0)
+       config = hcd->self.controller->platform_data;
+       ohci->hcca = dma_alloc_coherent (hcd->self.controller,
+                       sizeof *ohci->hcca, &ohci->hcca_dma, 0);
+       if (!ohci->hcca)
+               return -ENOMEM;
+
+        memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
+       if ((ret = ohci_mem_init (ohci)) < 0) {
+               ohci_stop (hcd);
                return ret;
+       }
+       ohci->regs = hcd->regs;
 
-       config = hcd->self.controller->platform_data;
        if (config->otg || config->rwc)
                writel(OHCI_CTRL_RWC, &ohci->regs->control);
 
-       if ((ret = ohci_run (ohci)) < 0) {
+       if (hc_reset (ohci) < 0) {
+               ohci_stop (hcd);
+               return -ENODEV;
+       }
+
+       if (hc_start (ohci) < 0) {
                err ("can't start %s", ohci->hcd.self.bus_name);
                ohci_stop (hcd);
-               return ret;
+               return -EBUSY;
        }
+       if (ohci->power_budget)
+               hub_set_power_budget(ohci->hcd.self.root_hub,
+                                       ohci->power_budget);
+       create_debug_files (ohci);
+
+#ifdef DEBUG
+       ohci_dump (ohci, 1);
+#endif
        return 0;
 }
 
@@ -447,6 +486,7 @@ static const struct hc_driver ohci_omap_hc_driver = {
         * memory lifecycle (except per-request)
         */
        .hcd_alloc =            ohci_hcd_alloc,
+       .hcd_free =             ohci_hcd_free,
 
        /*
         * managing i/o requests and associated device resources