All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pawel Laszczak <pawell@cadence.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	<linux-usb@vger.kernel.org>, Felipe Balbi <balbi@kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <ltyrala@cadence.com>,
	<pawell@cadence.com>
Subject: [PATCH 13/15] Introduce Cadence USBSSP DRD Driver - added usbssp-pci-of-wrap.c file This file implements wrapper between PCI adn platform driver.
Date: Tue, 3 Jul 2018 20:57:57 +0100	[thread overview]
Message-ID: <1530647879-10007-14-git-send-email-pawell@cadence.com> (raw)
In-Reply-To: <1530647879-10007-1-git-send-email-pawell@cadence.com>

Signed-off-by: Laszczak Pawel <pawell@cadence.com>
---
 drivers/usb/usbssp/usbssp-pci-of-wrap.c | 229 ++++++++++++++++++++++++
 1 file changed, 229 insertions(+)
 create mode 100644 drivers/usb/usbssp/usbssp-pci-of-wrap.c

diff --git a/drivers/usb/usbssp/usbssp-pci-of-wrap.c b/drivers/usb/usbssp/usbssp-pci-of-wrap.c
new file mode 100644
index 000000000000..a8511f062133
--- /dev/null
+++ b/drivers/usb/usbssp/usbssp-pci-of-wrap.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * USBSSP device controller driver - PCIe wrapper
+ *
+ * Copyright (C) 2018 Cadence.
+ *
+ * Author: Pawel Laszczak
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+
+struct usbssp_pci {
+	struct platform_device *plat_cdns;
+	struct pci_dev *otg;
+	struct pci_dev *hg_dev;
+	struct resource res[5];
+};
+
+struct usbssp_pci usbssp;
+
+/**
+ * usbssp_pci_probe - Probe function for Cadence USB wrapper driver
+ * @pdev: platform device object
+ * @id: pci device id
+ *
+ * Returns 0 on success otherwise negative errno
+ */
+static int usbssp_pci_probe(struct pci_dev *pdev,
+			    const struct pci_device_id *id)
+{
+	int rv = 0;
+	struct platform_device *usbssp_plat;
+
+	if (pdev->devfn > 1)
+		return 0;
+
+	if (!id)
+		return -EINVAL;
+
+	if (pcim_enable_device(pdev) < 0) {
+		dev_err(&pdev->dev, "failed to enable PCI device\n");
+		return -ENOMEM;
+	}
+
+	pci_set_master(pdev);
+
+	/*
+	 * function 0: device(BAR_2) + host(BAR_0)
+	 * function 1: otg(BAR_0))cdns3_remove_roles
+	 */
+	if (pdev->devfn == 0 || pdev->devfn == 1) {
+		if (!usbssp.plat_cdns) {
+			usbssp_plat = platform_device_alloc("usbssp-dev",
+					PLATFORM_DEVID_AUTO);
+			memset(usbssp.res, 0x00, sizeof(struct resource) *
+					ARRAY_SIZE(usbssp.res));
+			usbssp.plat_cdns = usbssp_plat;
+
+			if (!usbssp_plat->dev.dma_mask) {
+				dma_coerce_mask_and_coherent(&usbssp_plat->dev,
+					DMA_BIT_MASK(32));
+			}
+		}
+	} else
+		return -EINVAL;
+
+	/* for GADGET device function number is 0 */
+	if (pdev->devfn == 0) {
+		usbssp.hg_dev = pdev;
+		//device resource
+		usbssp.res[0].start = pci_resource_start(pdev, 2);
+		usbssp.res[0].end = pci_resource_end(pdev, 2);
+		usbssp.res[0].name = "usbssp-dev-regs";
+		usbssp.res[0].flags = IORESOURCE_MEM;
+
+		/* Interrupt resource*/
+		usbssp.res[1].start = pdev->irq;
+		usbssp.res[1].name = "usbssp-dev-irq";
+		usbssp.res[1].flags = IORESOURCE_IRQ;
+	} else if (pdev->devfn == 1) {
+		usbssp.otg = pdev;
+		//OTG
+		usbssp.res[2].start = pci_resource_start(pdev, 0);
+		usbssp.res[2].end =   pci_resource_end(pdev, 0);
+		usbssp.res[2].name = "otg";
+		usbssp.res[2].flags = IORESOURCE_MEM;
+
+		usbssp.res[3].start = pci_resource_start(pdev, 1);
+		usbssp.res[3].end =   pci_resource_end(pdev, 1);
+		usbssp.res[3].name = "debug1";
+		usbssp.res[3].flags = IORESOURCE_MEM;
+
+		usbssp.res[4].start = pci_resource_start(pdev, 2);
+		usbssp.res[4].end =   pci_resource_end(pdev, 2);
+		usbssp.res[4].name = "debug2";
+		usbssp.res[4].flags = IORESOURCE_MEM;
+	} else {
+		return -EIO;
+	}
+
+	if (usbssp.otg && usbssp.hg_dev) {
+
+		struct pci_dev *pci_hg = usbssp.hg_dev;
+		struct platform_device *plat_dev = usbssp.plat_cdns;
+
+		rv = platform_device_add_resources(plat_dev, usbssp.res,
+				ARRAY_SIZE(usbssp.res));
+		if (rv) {
+			dev_err(&plat_dev->dev,
+				"couldn't add resources to cdns device\n");
+			return rv;
+		}
+
+		rv = platform_device_add(plat_dev);
+
+		if (rv) {
+			dev_err(&pci_hg->dev,
+				"failed to register cdns device\n");
+			platform_device_put(plat_dev);
+			return rv;
+		}
+	}
+
+	pci_set_drvdata(pdev, &usbssp);
+
+	return rv;
+}
+
+void usbssp_pci_remove(struct pci_dev *pdev)
+{
+	struct usbssp_pci *usbssp = pci_get_drvdata(pdev);
+
+	if (pdev->devfn > 1)
+		return;
+
+	if (pdev->devfn == 1)
+		usbssp->otg = NULL;
+	else if (pdev->devfn == 0)
+		usbssp->hg_dev = NULL;
+
+	if (!usbssp->hg_dev && !usbssp->otg)
+		platform_device_unregister(usbssp->plat_cdns);
+}
+
+#if CONFIG_PM || CONFIG_PM_SLEEP
+static int usbssp_generic_suspend(struct usbssp_pci *usbssp, int param)
+{
+	/*TODO*/
+	return -ENOSYS;
+}
+
+static int usbssp_generic_resume(struct usbssp_pci *usbssp, int param)
+{
+	/*TODO*/
+	return -ENOSYS;
+}
+
+#endif /*CONFIG_PM || CONFIG_PM_SLEEP*/
+
+#ifdef CONFIG_PM
+static int usbssp_runtime_suspend(struct device *dev)
+{
+	struct usbssp_pci		*usbssp = dev_get_drvdata(dev);
+
+	return usbssp_generic_suspend(usbssp, 0);
+}
+
+static int usbssp_runtime_resume(struct device *dev)
+{
+	struct usbssp_pci		*usbssp = dev_get_drvdata(dev);
+
+	return usbssp_generic_resume(usbssp, 0);
+}
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_PM_SLEEP
+static int usbssp_pci_suspend(struct device *dev)
+{
+	struct usbssp_pci		*usbssp = dev_get_drvdata(dev);
+
+	return usbssp_generic_suspend(usbssp, 0);
+}
+
+static int usbssp_pci_resume(struct device *dev)
+{
+	struct usbssp_pci		*usbssp = dev_get_drvdata(dev);
+
+	return usbssp_generic_resume(usbssp, 0);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops usbssp_pci_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(usbssp_runtime_suspend, usbssp_runtime_resume)
+	SET_RUNTIME_PM_OPS(usbssp_pci_suspend, usbssp_pci_resume,
+		NULL)
+};
+
+#define PCI_VENDOR_ID_CDZ 0x17CD
+static const struct pci_device_id usbssp_pci_ids[] = {
+	{PCI_VDEVICE(CDZ, 0x0100), },
+	{ /* terminate list */}
+};
+
+MODULE_DEVICE_TABLE(pci, usbssp_pci_ids);
+
+static struct pci_driver usbssp_pci_driver = {
+	.name = "usbssp-pci",
+	.id_table = &usbssp_pci_ids[0],
+	.probe = usbssp_pci_probe,
+	.remove = usbssp_pci_remove,
+	.driver		= {
+		.pm	= &usbssp_pci_dev_pm_ops,
+	}
+};
+
+MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Cadence USBSSP PCI Glue Layer");
+
+module_pci_driver(usbssp_pci_driver);
+
+
-- 
2.17.1


WARNING: multiple messages have this Message-ID (diff)
From: Pawel Laszczak <pawell@cadence.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-usb@vger.kernel.org, Felipe Balbi <balbi@kernel.org>
Cc: linux-kernel@vger.kernel.org, ltyrala@cadence.com, pawell@cadence.com
Subject: [13/15] Introduce Cadence USBSSP DRD Driver - added usbssp-pci-of-wrap.c file This file implements wrapper between PCI adn platform driver.
Date: Tue, 3 Jul 2018 20:57:57 +0100	[thread overview]
Message-ID: <1530647879-10007-14-git-send-email-pawell@cadence.com> (raw)

Signed-off-by: Laszczak Pawel <pawell@cadence.com>
---
 drivers/usb/usbssp/usbssp-pci-of-wrap.c | 229 ++++++++++++++++++++++++
 1 file changed, 229 insertions(+)
 create mode 100644 drivers/usb/usbssp/usbssp-pci-of-wrap.c

diff --git a/drivers/usb/usbssp/usbssp-pci-of-wrap.c b/drivers/usb/usbssp/usbssp-pci-of-wrap.c
new file mode 100644
index 000000000000..a8511f062133
--- /dev/null
+++ b/drivers/usb/usbssp/usbssp-pci-of-wrap.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * USBSSP device controller driver - PCIe wrapper
+ *
+ * Copyright (C) 2018 Cadence.
+ *
+ * Author: Pawel Laszczak
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+
+struct usbssp_pci {
+	struct platform_device *plat_cdns;
+	struct pci_dev *otg;
+	struct pci_dev *hg_dev;
+	struct resource res[5];
+};
+
+struct usbssp_pci usbssp;
+
+/**
+ * usbssp_pci_probe - Probe function for Cadence USB wrapper driver
+ * @pdev: platform device object
+ * @id: pci device id
+ *
+ * Returns 0 on success otherwise negative errno
+ */
+static int usbssp_pci_probe(struct pci_dev *pdev,
+			    const struct pci_device_id *id)
+{
+	int rv = 0;
+	struct platform_device *usbssp_plat;
+
+	if (pdev->devfn > 1)
+		return 0;
+
+	if (!id)
+		return -EINVAL;
+
+	if (pcim_enable_device(pdev) < 0) {
+		dev_err(&pdev->dev, "failed to enable PCI device\n");
+		return -ENOMEM;
+	}
+
+	pci_set_master(pdev);
+
+	/*
+	 * function 0: device(BAR_2) + host(BAR_0)
+	 * function 1: otg(BAR_0))cdns3_remove_roles
+	 */
+	if (pdev->devfn == 0 || pdev->devfn == 1) {
+		if (!usbssp.plat_cdns) {
+			usbssp_plat = platform_device_alloc("usbssp-dev",
+					PLATFORM_DEVID_AUTO);
+			memset(usbssp.res, 0x00, sizeof(struct resource) *
+					ARRAY_SIZE(usbssp.res));
+			usbssp.plat_cdns = usbssp_plat;
+
+			if (!usbssp_plat->dev.dma_mask) {
+				dma_coerce_mask_and_coherent(&usbssp_plat->dev,
+					DMA_BIT_MASK(32));
+			}
+		}
+	} else
+		return -EINVAL;
+
+	/* for GADGET device function number is 0 */
+	if (pdev->devfn == 0) {
+		usbssp.hg_dev = pdev;
+		//device resource
+		usbssp.res[0].start = pci_resource_start(pdev, 2);
+		usbssp.res[0].end = pci_resource_end(pdev, 2);
+		usbssp.res[0].name = "usbssp-dev-regs";
+		usbssp.res[0].flags = IORESOURCE_MEM;
+
+		/* Interrupt resource*/
+		usbssp.res[1].start = pdev->irq;
+		usbssp.res[1].name = "usbssp-dev-irq";
+		usbssp.res[1].flags = IORESOURCE_IRQ;
+	} else if (pdev->devfn == 1) {
+		usbssp.otg = pdev;
+		//OTG
+		usbssp.res[2].start = pci_resource_start(pdev, 0);
+		usbssp.res[2].end =   pci_resource_end(pdev, 0);
+		usbssp.res[2].name = "otg";
+		usbssp.res[2].flags = IORESOURCE_MEM;
+
+		usbssp.res[3].start = pci_resource_start(pdev, 1);
+		usbssp.res[3].end =   pci_resource_end(pdev, 1);
+		usbssp.res[3].name = "debug1";
+		usbssp.res[3].flags = IORESOURCE_MEM;
+
+		usbssp.res[4].start = pci_resource_start(pdev, 2);
+		usbssp.res[4].end =   pci_resource_end(pdev, 2);
+		usbssp.res[4].name = "debug2";
+		usbssp.res[4].flags = IORESOURCE_MEM;
+	} else {
+		return -EIO;
+	}
+
+	if (usbssp.otg && usbssp.hg_dev) {
+
+		struct pci_dev *pci_hg = usbssp.hg_dev;
+		struct platform_device *plat_dev = usbssp.plat_cdns;
+
+		rv = platform_device_add_resources(plat_dev, usbssp.res,
+				ARRAY_SIZE(usbssp.res));
+		if (rv) {
+			dev_err(&plat_dev->dev,
+				"couldn't add resources to cdns device\n");
+			return rv;
+		}
+
+		rv = platform_device_add(plat_dev);
+
+		if (rv) {
+			dev_err(&pci_hg->dev,
+				"failed to register cdns device\n");
+			platform_device_put(plat_dev);
+			return rv;
+		}
+	}
+
+	pci_set_drvdata(pdev, &usbssp);
+
+	return rv;
+}
+
+void usbssp_pci_remove(struct pci_dev *pdev)
+{
+	struct usbssp_pci *usbssp = pci_get_drvdata(pdev);
+
+	if (pdev->devfn > 1)
+		return;
+
+	if (pdev->devfn == 1)
+		usbssp->otg = NULL;
+	else if (pdev->devfn == 0)
+		usbssp->hg_dev = NULL;
+
+	if (!usbssp->hg_dev && !usbssp->otg)
+		platform_device_unregister(usbssp->plat_cdns);
+}
+
+#if CONFIG_PM || CONFIG_PM_SLEEP
+static int usbssp_generic_suspend(struct usbssp_pci *usbssp, int param)
+{
+	/*TODO*/
+	return -ENOSYS;
+}
+
+static int usbssp_generic_resume(struct usbssp_pci *usbssp, int param)
+{
+	/*TODO*/
+	return -ENOSYS;
+}
+
+#endif /*CONFIG_PM || CONFIG_PM_SLEEP*/
+
+#ifdef CONFIG_PM
+static int usbssp_runtime_suspend(struct device *dev)
+{
+	struct usbssp_pci		*usbssp = dev_get_drvdata(dev);
+
+	return usbssp_generic_suspend(usbssp, 0);
+}
+
+static int usbssp_runtime_resume(struct device *dev)
+{
+	struct usbssp_pci		*usbssp = dev_get_drvdata(dev);
+
+	return usbssp_generic_resume(usbssp, 0);
+}
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_PM_SLEEP
+static int usbssp_pci_suspend(struct device *dev)
+{
+	struct usbssp_pci		*usbssp = dev_get_drvdata(dev);
+
+	return usbssp_generic_suspend(usbssp, 0);
+}
+
+static int usbssp_pci_resume(struct device *dev)
+{
+	struct usbssp_pci		*usbssp = dev_get_drvdata(dev);
+
+	return usbssp_generic_resume(usbssp, 0);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops usbssp_pci_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(usbssp_runtime_suspend, usbssp_runtime_resume)
+	SET_RUNTIME_PM_OPS(usbssp_pci_suspend, usbssp_pci_resume,
+		NULL)
+};
+
+#define PCI_VENDOR_ID_CDZ 0x17CD
+static const struct pci_device_id usbssp_pci_ids[] = {
+	{PCI_VDEVICE(CDZ, 0x0100), },
+	{ /* terminate list */}
+};
+
+MODULE_DEVICE_TABLE(pci, usbssp_pci_ids);
+
+static struct pci_driver usbssp_pci_driver = {
+	.name = "usbssp-pci",
+	.id_table = &usbssp_pci_ids[0],
+	.probe = usbssp_pci_probe,
+	.remove = usbssp_pci_remove,
+	.driver		= {
+		.pm	= &usbssp_pci_dev_pm_ops,
+	}
+};
+
+MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Cadence USBSSP PCI Glue Layer");
+
+module_pci_driver(usbssp_pci_driver);
+
+

  parent reply	other threads:[~2018-07-03 20:00 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-03 19:57 Introduced new Cadence USBSSP DRD Driver Pawel Laszczak
2018-07-03 19:57 ` [PATCH 01/15] Introduce Cadence USBSSP DRD Driver - added gadget.c file Pawel Laszczak
2018-07-03 19:57   ` [01/15] " Pawel Laszczak
2018-07-04  9:13   ` [PATCH 01/15] " Greg Kroah-Hartman
2018-07-04  9:13     ` [01/15] " Greg Kroah-Hartman
2018-07-05 10:15     ` [PATCH 01/15] " Pawel Laszczak
2018-07-05 10:15       ` [01/15] " Pawel Laszczak
2018-07-05 15:14       ` [PATCH 01/15] " Greg Kroah-Hartman
2018-07-05 15:14         ` [01/15] " Greg Kroah-Hartman
2018-07-03 19:57 ` [PATCH 02/15] Introduce Cadence USBSSP DRD driver - added gadget-mem.c Pawel Laszczak
2018-07-03 19:57   ` [02/15] " Pawel Laszczak
2018-07-03 19:57 ` [PATCH 03/15] Introduce Cadence USBSSP DRD Driver - added gadget-ring.c file Pawel Laszczak
2018-07-03 19:57   ` [03/15] " Pawel Laszczak
2018-07-03 19:57 ` [PATCH 04/15] Introduce Cadence USBSSP DRD Driver - added gadget.h file Pawel Laszczak
2018-07-03 19:57   ` [04/15] " Pawel Laszczak
2018-07-03 19:57 ` [PATCH 05/15] Introduce Cadence USBSSP DRD Driver - added gadget-port.c file Pawel Laszczak
2018-07-03 19:57   ` [05/15] " Pawel Laszczak
2018-07-03 19:57 ` [PATCH 06/15] Introduce Cadence USBSSP DRD Driver - added gadget-ep0 file Pawel Laszczak
2018-07-03 19:57   ` [06/15] " Pawel Laszczak
2018-07-03 19:57 ` [PATCH 07/15] Introduce Cadence USBSSP DRD Driver - added gadget-if.c Driver implements interface between gadget drivers and USBSSP device driver Pawel Laszczak
2018-07-03 19:57   ` [07/15] " Pawel Laszczak
2018-07-03 19:57 ` [PATCH 08/15] Introduce Cadence USBSSP DRD driver - added gadget-ext-caps.h Pawel Laszczak
2018-07-03 19:57   ` [08/15] " Pawel Laszczak
2018-07-03 19:57 ` [PATCH 09/15] Introduce Cadence USBSSP DRD Driver - added debugfs files Pawel Laszczak
2018-07-03 19:57   ` [09/15] " Pawel Laszczak
2018-07-04  9:15   ` [PATCH 09/15] " Greg Kroah-Hartman
2018-07-04  9:15     ` [09/15] " Greg Kroah-Hartman
2018-07-05  9:44     ` [PATCH 09/15] " Pawel Laszczak
2018-07-05  9:44       ` [09/15] " Pawel Laszczak
2018-07-05 15:13       ` [PATCH 09/15] " Greg Kroah-Hartman
2018-07-05 15:13         ` [09/15] " Greg Kroah-Hartman
2018-07-03 19:57 ` [PATCH 10/15] Introduce Cadence USBSSP DRD Driver - added trace files Pawel Laszczak
2018-07-03 19:57   ` [10/15] " Pawel Laszczak
2018-07-03 19:57 ` [PATCH 11/15] Introduce Cadence USBSSP DRD driver - added gadget-dbg.c file Pawel Laszczak
2018-07-03 19:57   ` [11/15] " Pawel Laszczak
2018-07-03 19:57 ` [PATCH 12/15] Introduce Cadence USBSSP DRD Driver - added usbssp-plat.c file Pawel Laszczak
2018-07-03 19:57   ` [12/15] " Pawel Laszczak
2018-07-03 19:57 ` Pawel Laszczak [this message]
2018-07-03 19:57   ` [13/15] Introduce Cadence USBSSP DRD Driver - added usbssp-pci-of-wrap.c file This file implements wrapper between PCI adn platform driver Pawel Laszczak
2018-07-03 19:57 ` [PATCH 14/15] Introduce Cadence USBSSP DRD Driver - added Kconfig and Makefile files Pawel Laszczak
2018-07-03 19:57   ` [14/15] " Pawel Laszczak
2018-07-03 20:30   ` [PATCH 14/15] " Randy Dunlap
2018-07-03 20:30     ` [14/15] " Randy Dunlap
2018-07-03 19:57 ` [PATCH 15/15] Introduce Cadence USBSSP DRD Driver - added USBSSP in Makefile and Kconfig files Pawel Laszczak
2018-07-03 19:57   ` [15/15] " Pawel Laszczak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1530647879-10007-14-git-send-email-pawell@cadence.com \
    --to=pawell@cadence.com \
    --cc=balbi@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=ltyrala@cadence.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.