dm: usb: Add driver-model support to ehci-pci
authorSimon Glass <sjg@chromium.org>
Mon, 6 Jul 2015 22:47:53 +0000 (16:47 -0600)
committerSimon Glass <sjg@chromium.org>
Tue, 21 Jul 2015 23:39:40 +0000 (17:39 -0600)
Support driver model in this driver. This uses the normal USB driver search
mechanism. Any EHCI controllers will be set up as they are found during
usb_init().

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Marek Vasut <marex@denx.de>
drivers/usb/host/ehci-pci.c

index 3d333bd465630276245bc3fddef1a2174fd50692..0cb9fcc166dcc59f428cd4333ed58e06878b687d 100644 (file)
@@ -6,12 +6,45 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <pci.h>
 #include <usb.h>
 
 #include "ehci.h"
 
+/* Information about a USB port */
+struct ehci_pci_priv {
+       struct ehci_ctrl ehci;
+};
+
+static void ehci_pci_common_init(pci_dev_t pdev, struct ehci_hccr **ret_hccr,
+                                struct ehci_hcor **ret_hcor)
+{
+       struct ehci_hccr *hccr;
+       struct ehci_hcor *hcor;
+       uint32_t cmd;
+
+       hccr = (struct ehci_hccr *)pci_map_bar(pdev,
+                       PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+       hcor = (struct ehci_hcor *)((uint32_t) hccr +
+                       HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+       debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
+             (uint32_t)hccr, (uint32_t)hcor,
+             (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+       *ret_hccr = hccr;
+       *ret_hcor = hcor;
+
+       /* enable busmaster */
+       pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
+       cmd |= PCI_COMMAND_MASTER;
+       pci_write_config_dword(pdev, PCI_COMMAND, cmd);
+}
+
+#ifndef CONFIG_DM_USB
+
 #ifdef CONFIG_PCI_EHCI_DEVICE
 static struct pci_device_id ehci_pci_ids[] = {
        /* Please add supported PCI EHCI controller ids here */
@@ -20,7 +53,6 @@ static struct pci_device_id ehci_pci_ids[] = {
        {0x12D8, 0x400F},       /* Pericom */
        {0, 0}
 };
-#else
 #endif
 
 /*
@@ -31,9 +63,6 @@ int ehci_hcd_init(int index, enum usb_init_type init,
                struct ehci_hccr **ret_hccr, struct ehci_hcor **ret_hcor)
 {
        pci_dev_t pdev;
-       uint32_t cmd;
-       struct ehci_hccr *hccr;
-       struct ehci_hcor *hcor;
 
 #ifdef CONFIG_PCI_EHCI_DEVICE
        pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE);
@@ -44,23 +73,8 @@ int ehci_hcd_init(int index, enum usb_init_type init,
                printf("EHCI host controller not found\n");
                return -1;
        }
+       ehci_pci_common_init(pdev, ret_hccr, ret_hcor);
 
-       hccr = (struct ehci_hccr *)pci_map_bar(pdev,
-                       PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
-       hcor = (struct ehci_hcor *)((uint32_t) hccr +
-                       HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
-
-       debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
-                       (uint32_t)hccr, (uint32_t)hcor,
-                       (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
-
-       *ret_hccr = hccr;
-       *ret_hcor = hcor;
-
-       /* enable busmaster */
-       pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
-       cmd |= PCI_COMMAND_MASTER;
-       pci_write_config_dword(pdev, PCI_COMMAND, cmd);
        return 0;
 }
 
@@ -72,3 +86,46 @@ int ehci_hcd_stop(int index)
 {
        return 0;
 }
+#endif /* nCONFIG_DM_USB */
+
+#ifdef CONFIG_DM_USB
+static int ehci_pci_probe(struct udevice *dev)
+{
+       struct ehci_hccr *hccr;
+       struct ehci_hcor *hcor;
+
+       ehci_pci_common_init(pci_get_bdf(dev), &hccr, &hcor);
+
+       return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+}
+
+static int ehci_pci_remove(struct udevice *dev)
+{
+       int ret;
+
+       ret = ehci_deregister(dev);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+U_BOOT_DRIVER(ehci_pci) = {
+       .name   = "ehci_pci",
+       .id     = UCLASS_USB,
+       .probe = ehci_pci_probe,
+       .remove = ehci_pci_remove,
+       .ops    = &ehci_usb_ops,
+       .platdata_auto_alloc_size = sizeof(struct usb_platdata),
+       .priv_auto_alloc_size = sizeof(struct ehci_pci_priv),
+       .flags  = DM_FLAG_ALLOC_PRIV_DMA,
+};
+
+static struct pci_device_id ehci_pci_supported[] = {
+       { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0) },
+       {},
+};
+
+U_BOOT_PCI_DEVICE(ehci_pci, ehci_pci_supported);
+
+#endif /* CONFIG_DM_USB */