From: Pawel Laszczak <pawell@cadence.com>
To: <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>, <rogerq@ti.com>,
<linux-kernel@vger.kernel.org>, <adouglas@cadence.com>,
<jbergsagel@ti.com>, <peter.chen@nxp.com>, <pjez@cadence.com>,
<kurahul@cadence.com>, <pawell@cadence.com>
Subject: [RFC PATCH v1 05/14] usb:cdns3: Added Wrapper to XCHI driver
Date: Sat, 3 Nov 2018 17:51:18 +0000 [thread overview]
Message-ID: <1541267487-3664-6-git-send-email-pawell@cadence.com> (raw)
In-Reply-To: <1541267487-3664-1-git-send-email-pawell@cadence.com>
Patch implements functions that allow to initialize, start and stop
XHCI host driver.
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
---
drivers/usb/cdns3/host.c | 230 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 227 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c
index 37300985e2d6..f3b100a27cd6 100644
--- a/drivers/usb/cdns3/host.c
+++ b/drivers/usb/cdns3/host.c
@@ -9,20 +9,244 @@
* Pawel Laszczak <pawell@cadence.com>
*/
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/pm_runtime.h>
+#include <linux/usb/of.h>
+
+#include "../host/xhci.h"
#include "core.h"
+#include "host-export.h"
+
+static struct hc_driver __read_mostly xhci_cdns3_hc_driver;
+
+static void xhci_cdns3_quirks(struct device *dev, struct xhci_hcd *xhci)
+{
+ /*
+ * As of now platform drivers don't provide MSI support so we ensure
+ * here that the generic code does not try to make a pci_dev from our
+ * dev struct in order to setup MSI
+ */
+ xhci->quirks |= XHCI_PLAT;
+}
+
+static int xhci_cdns3_setup(struct usb_hcd *hcd)
+{
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ u32 command;
+ int ret;
+
+ ret = xhci_gen_setup(hcd, xhci_cdns3_quirks);
+ if (ret)
+ return ret;
+
+ /* set usbcmd.EU3S */
+ command = readl(&xhci->op_regs->command);
+ command |= CMD_PM_INDEX;
+ writel(command, &xhci->op_regs->command);
+
+ return 0;
+}
+
+static const struct xhci_driver_overrides xhci_cdns3_overrides __initconst = {
+ .extra_priv_size = sizeof(struct xhci_hcd),
+ .reset = xhci_cdns3_setup,
+};
+
+struct cdns3_host {
+ struct device dev;
+ struct usb_hcd *hcd;
+};
+
+static irqreturn_t cdns3_host_irq(struct cdns3 *cdns)
+{
+ struct device *dev = cdns->host_dev;
+ struct usb_hcd *hcd;
+
+ if (dev)
+ hcd = dev_get_drvdata(dev);
+ else
+ return IRQ_NONE;
+
+ if (hcd)
+ return usb_hcd_irq(cdns->irq, hcd);
+ else
+ return IRQ_NONE;
+}
+
+static void cdns3_host_release(struct device *dev)
+{
+ struct cdns3_host *host = container_of(dev, struct cdns3_host, dev);
+
+ kfree(host);
+}
+
+static int cdns3_host_start(struct cdns3 *cdns)
+{
+ struct cdns3_host *host;
+ struct device *dev;
+ struct device *sysdev;
+ struct xhci_hcd *xhci;
+ int ret;
+
+ host = kzalloc(sizeof(*host), GFP_KERNEL);
+ if (!host)
+ return -ENOMEM;
+
+ dev = &host->dev;
+ dev->release = cdns3_host_release;
+ dev->parent = cdns->dev;
+ dev_set_name(dev, "xhci-cdns3");
+ cdns->host_dev = dev;
+ ret = device_register(dev);
+ if (ret)
+ goto err1;
+
+ sysdev = cdns->dev;
+ /* Try to set 64-bit DMA first */
+ if (WARN_ON(!sysdev->dma_mask))
+ /* Platform did not initialize dma_mask */
+ ret = dma_coerce_mask_and_coherent(sysdev,
+ DMA_BIT_MASK(64));
+ else
+ ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64));
+
+ /* If setting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
+ if (ret) {
+ ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
+ }
+
+ pm_runtime_set_active(dev);
+ pm_runtime_no_callbacks(dev);
+ pm_runtime_enable(dev);
+ host->hcd = __usb_create_hcd(&xhci_cdns3_hc_driver, sysdev, dev,
+ dev_name(dev), NULL);
+ if (!host->hcd) {
+ ret = -ENOMEM;
+ goto err2;
+ }
+
+ host->hcd->regs = cdns->xhci_regs;
+ host->hcd->rsrc_start = cdns->xhci_res->start;
+ host->hcd->rsrc_len = resource_size(cdns->xhci_res);
+
+ device_wakeup_enable(host->hcd->self.controller);
+ xhci = hcd_to_xhci(host->hcd);
+
+ xhci->main_hcd = host->hcd;
+ xhci->shared_hcd = __usb_create_hcd(&xhci_cdns3_hc_driver, sysdev, dev,
+ dev_name(dev), host->hcd);
+ if (!xhci->shared_hcd) {
+ ret = -ENOMEM;
+ goto err3;
+ }
+
+ host->hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);
+ xhci->shared_hcd->tpl_support = host->hcd->tpl_support;
+ ret = usb_add_hcd(host->hcd, 0, IRQF_SHARED);
+ if (ret)
+ goto err4;
+
+ ret = usb_add_hcd(xhci->shared_hcd, 0, IRQF_SHARED);
+ if (ret)
+ goto err5;
+
+ device_set_wakeup_capable(dev, true);
+
+ return 0;
+
+err5:
+ usb_remove_hcd(host->hcd);
+err4:
+ usb_put_hcd(xhci->shared_hcd);
+err3:
+ usb_put_hcd(host->hcd);
+err2:
+ device_del(dev);
+err1:
+ put_device(dev);
+ cdns->host_dev = NULL;
+ return ret;
+}
+
+static void cdns3_host_stop(struct cdns3 *cdns)
+{
+ struct device *dev = cdns->host_dev;
+ struct xhci_hcd *xhci;
+ struct usb_hcd *hcd;
+
+ if (dev) {
+ hcd = dev_get_drvdata(dev);
+ xhci = hcd_to_xhci(hcd);
+ usb_remove_hcd(xhci->shared_hcd);
+ usb_remove_hcd(hcd);
+ synchronize_irq(cdns->irq);
+ usb_put_hcd(xhci->shared_hcd);
+ usb_put_hcd(hcd);
+ cdns->host_dev = NULL;
+ pm_runtime_set_suspended(dev);
+ pm_runtime_disable(dev);
+ device_del(dev);
+ put_device(dev);
+ }
+}
+
+static int cdns3_host_suspend(struct cdns3 *cdns, bool do_wakeup)
+{
+ struct device *dev = cdns->host_dev;
+ struct xhci_hcd *xhci;
+
+ if (!dev)
+ return 0;
+
+ xhci = hcd_to_xhci(dev_get_drvdata(dev));
+ return xhci_suspend(xhci, do_wakeup);
+}
+
+static int cdns3_host_resume(struct cdns3 *cdns, bool hibernated)
+{
+ struct device *dev = cdns->host_dev;
+ struct xhci_hcd *xhci;
+
+ if (!dev)
+ return 0;
+
+ xhci = hcd_to_xhci(dev_get_drvdata(dev));
+ return xhci_resume(xhci, hibernated);
+}
int cdns3_host_init(struct cdns3 *cdns)
{
- //TODO: implements this function
+ struct cdns3_role_driver *rdrv;
+
+ rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
+ if (!rdrv)
+ return -ENOMEM;
+
+ rdrv->start = cdns3_host_start;
+ rdrv->stop = cdns3_host_stop;
+ rdrv->irq = cdns3_host_irq;
+ rdrv->suspend = cdns3_host_suspend;
+ rdrv->resume = cdns3_host_resume;
+ rdrv->name = "host";
+ cdns->roles[CDNS3_ROLE_HOST] = rdrv;
+
return 0;
}
void cdns3_host_remove(struct cdns3 *cdns)
{
- //TODO: implements this function
+ cdns3_host_stop(cdns);
}
void __init cdns3_host_driver_init(void)
{
- //TODO: implements this function
+ xhci_init_driver(&xhci_cdns3_hc_driver, &xhci_cdns3_overrides);
}
--
2.17.1
next prev parent reply other threads:[~2018-11-03 17:52 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-03 17:51 [RFC PATCH v1 00/14] Introduced new Cadence USBSS DRD Driver Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 01/14] usb:cdns3: add pci to platform driver wrapper Pawel Laszczak
2018-11-06 13:48 ` Roger Quadros
2018-11-07 8:42 ` Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 02/14] usb:cdns3: Device side header file Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 03/14] usb:cdns3: Driver initialization code Pawel Laszczak
2018-11-06 14:18 ` Roger Quadros
2018-11-07 13:14 ` Pawel Laszczak
2018-11-06 14:44 ` Roger Quadros
2018-11-08 11:38 ` Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 04/14] usb:cdns3: Added DRD support Pawel Laszczak
2018-11-06 14:32 ` Roger Quadros
2018-11-08 11:33 ` Pawel Laszczak
2018-11-03 17:51 ` Pawel Laszczak [this message]
2018-11-03 17:51 ` [RFC PATCH v1 06/14] usb:cdns3: Initialization code for Device side Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 07/14] usb:cdns3: Implements device operations part of the API Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 08/14] usb:cdns3: EpX " Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 09/14] usb:cdns3: Ep0 " Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 10/14] usb:cdns3: Implements ISR functionality Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 11/14] usb:cdns3: Adds enumeration related function Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 12/14] usb:cdns3: Adds transfer " Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 13/14] usb:cdns3: Adds debugging function Pawel Laszczak
2018-11-03 19:14 ` Joe Perches
2018-11-05 6:17 ` Pawel Laszczak
2018-11-08 9:34 ` Roger Quadros
2018-11-08 12:03 ` Pawel Laszczak
2018-11-03 17:51 ` [RFC PATCH v1 14/14] usb:cdns3: Feature for changing role Pawel Laszczak
2018-11-06 14:51 ` Roger Quadros
2018-11-08 11:51 ` Pawel Laszczak
2018-11-08 14:22 ` Roger Quadros
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=1541267487-3664-6-git-send-email-pawell@cadence.com \
--to=pawell@cadence.com \
--cc=adouglas@cadence.com \
--cc=gregkh@linuxfoundation.org \
--cc=jbergsagel@ti.com \
--cc=kurahul@cadence.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=peter.chen@nxp.com \
--cc=pjez@cadence.com \
--cc=rogerq@ti.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®