[RFC/PATCH v2 03/11] usb: host: xhci: give xhci a platform_device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



it will make it simpler to re-use the stack
if it's not tied to a particular bus. Later
patches should come to phase PCI bus to a
separate piece of code which doesn't touch
xhci.c.

Signed-off-by: Felipe Balbi <balbi@xxxxxx>
---
 drivers/usb/host/xhci.c |  126 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 125 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index f5fe1ac..d6c9577 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
+#include <linux/platform_device.h>
 
 #include "xhci.h"
 
@@ -3028,6 +3029,127 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_LICENSE("GPL");
 
+static int xhci_probe(struct platform_device *pdev)
+{
+	struct xhci_platform_data *data;
+	struct usb_hcd		*hcd;
+	struct xhci_hcd		*xhci;
+	struct resource		*res;
+
+	int			irq;
+	int			ret;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	data = pdev->dev.platform_data;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "No IRQ found\n");
+		ret = irq;
+		goto err0;
+	}
+
+	hcd = usb_create_hcd(data->driver, &pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		ret = -ENOMEM;
+		goto err0;
+	}
+
+	platform_set_drvdata(pdev, hcd);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "missing memory resource\n");
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
+				data->driver->description)) {
+		dev_err(&pdev->dev, "controller already in use\n");
+		ret = -EBUSY;
+		goto err1;
+	}
+
+	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_err(&pdev->dev, "error mapping memory\n");
+		ret = -ENOMEM;
+		goto err2;
+	}
+
+	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add XHCI HCD\n");
+		goto err3;
+	}
+
+	xhci = hcd_to_xhci(hcd);
+	xhci->shared_hcd = usb_create_shared_hcd(data->driver, &pdev->dev,
+			dev_name(&pdev->dev), hcd);
+	if (!xhci->shared_hcd) {
+		dev_err(&pdev->dev, "failed to create shared HCD\n");
+		ret = -ENOMEM;
+		goto err4;
+	}
+
+	*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci;
+
+	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add shared HCD\n");
+		goto err5;
+	}
+
+	return 0;
+
+err5:
+	usb_put_hcd(xhci->shared_hcd);
+
+err4:
+	usb_remove_hcd(hcd);
+
+err3:
+	iounmap(hcd->regs);
+
+err2:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+
+err1:
+	usb_put_hcd(hcd);
+
+err0:
+	return ret;
+}
+
+static int __devexit xhci_remove(struct platform_device *pdev)
+{
+	struct usb_hcd		*hcd = platform_get_drvdata(pdev);
+	struct xhci_hcd		*xhci = hcd_to_xhci(hcd);
+
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_remove_hcd(hcd);
+	usb_put_hcd(hcd);
+	usb_remove_hcd(xhci->shared_hcd);
+	usb_put_hcd(xhci->shared_hcd);
+
+	return 0;
+}
+
+static struct platform_driver xhci_driver = {
+	.probe		= xhci_probe,
+	.remove		= __devexit_p(xhci_remove),
+	.driver		= {
+		.name	= "xhci",
+	},
+};
+
 static int __init xhci_hcd_init(void)
 {
 #ifdef CONFIG_PCI
@@ -3058,7 +3180,8 @@ static int __init xhci_hcd_init(void)
 	/* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
 	BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
 	BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
-	return 0;
+
+	return platform_driver_register(&xhci_driver);
 }
 module_init(xhci_hcd_init);
 
@@ -3067,5 +3190,6 @@ static void __exit xhci_hcd_cleanup(void)
 #ifdef CONFIG_PCI
 	xhci_unregister_pci();
 #endif
+	platform_driver_unregister(&xhci_driver);
 }
 module_exit(xhci_hcd_cleanup);
-- 
1.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux