From: Peter Chen <peter.chen@cixtech.com>
To: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
gregkh@linuxfoundation.org, pawell@cadence.com,
rogerq@kernel.org
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-usb@vger.kernel.org, cix-kernel-upstream@cixtech.com,
linux-arm-kernel@lists.infradead.org, arnd@arndb.de,
Peter Chen <peter.chen@cixtech.com>
Subject: [PATCH 1/4] usb: cdns3: plat: Expose platform core driver as library
Date: Mon, 11 May 2026 10:42:41 +0800 [thread overview]
Message-ID: <20260511024244.981941-2-peter.chen@cixtech.com> (raw)
In-Reply-To: <20260511024244.981941-1-peter.chen@cixtech.com>
Split the Cadence USB3 platform probe/remove and PM paths into
cdns3_core_probe(), cdns3_core_remove(), and exported runtime/system
sleep helpers so SoC glue (e.g. Sky1) can instantiate the core on the
same platform_device deterministically.
Add glue.h documenting struct cdns3_probe_data and the public entry points.
Signed-off-by: Peter Chen <peter.chen@cixtech.com>
---
drivers/usb/cdns3/cdns3-plat.c | 138 ++++++++++++++++++++++-----------
drivers/usb/cdns3/glue.h | 51 ++++++++++++
2 files changed, 144 insertions(+), 45 deletions(-)
create mode 100644 drivers/usb/cdns3/glue.h
diff --git a/drivers/usb/cdns3/cdns3-plat.c b/drivers/usb/cdns3/cdns3-plat.c
index 3fe3109a3688..2219cbff1c59 100644
--- a/drivers/usb/cdns3/cdns3-plat.c
+++ b/drivers/usb/cdns3/cdns3-plat.c
@@ -21,6 +21,7 @@
#include "core.h"
#include "gadget-export.h"
+#include "glue.h"
#include "host-export.h"
#include "drd.h"
@@ -59,29 +60,21 @@ static int cdns3_plat_host_init(struct cdns *cdns)
}
/**
- * cdns3_plat_probe - probe for cdns3 core device
- * @pdev: Pointer to cdns3 core platform device
+ * cdns3_core_probe - Initialize the Cadence USB3 platform core
+ * @data: Controller context and platform device supplied by the glue layer
*
* Returns 0 on success otherwise negative errno
*/
-static int cdns3_plat_probe(struct platform_device *pdev)
+int cdns3_core_probe(const struct cdns3_probe_data *data)
{
+ struct platform_device *pdev = data->pdev;
struct device *dev = &pdev->dev;
- struct resource *res;
- struct cdns *cdns;
+ struct cdns *cdns = data->cdns;
+ struct resource *res;
void __iomem *regs;
int ret;
- cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL);
- if (!cdns)
- return -ENOMEM;
-
- cdns->dev = dev;
- cdns->pdata = dev_get_platdata(dev);
- if (cdns->pdata && cdns->pdata->override_apb_timeout)
- cdns->override_apb_timeout = cdns->pdata->override_apb_timeout;
-
- platform_set_drvdata(pdev, cdns);
+ dev_set_drvdata(dev, cdns);
ret = platform_get_irq_byname(pdev, "host");
if (ret < 0)
@@ -195,14 +188,41 @@ static int cdns3_plat_probe(struct platform_device *pdev)
return ret;
}
+EXPORT_SYMBOL_GPL(cdns3_core_probe);
/**
- * cdns3_plat_remove() - unbind drd driver and clean up
- * @pdev: Pointer to Linux platform device
+ * cdns3_plat_probe - probe for cdns3 core device
+ * @pdev: Pointer to cdns3 core platform device
+ *
+ * Returns 0 on success otherwise negative errno
*/
-static void cdns3_plat_remove(struct platform_device *pdev)
+static int cdns3_plat_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct cdns *cdns;
+ struct cdns3_probe_data probe_data;
+
+ cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL);
+ if (!cdns)
+ return -ENOMEM;
+
+ cdns->dev = dev;
+ cdns->pdata = dev_get_platdata(dev);
+ if (cdns->pdata && cdns->pdata->override_apb_timeout)
+ cdns->override_apb_timeout = cdns->pdata->override_apb_timeout;
+
+ probe_data.cdns = cdns;
+ probe_data.pdev = pdev;
+
+ return cdns3_core_probe(&probe_data);
+}
+
+/**
+ * cdns3_core_remove - Tear down the Cadence USB3 platform core
+ * @cdns: Controller context previously initialized by cdns3_core_probe()
+ */
+void cdns3_core_remove(struct cdns *cdns)
{
- struct cdns *cdns = platform_get_drvdata(pdev);
struct device *dev = cdns->dev;
pm_runtime_get_sync(dev);
@@ -213,24 +233,30 @@ static void cdns3_plat_remove(struct platform_device *pdev)
phy_exit(cdns->usb2_phy);
phy_exit(cdns->usb3_phy);
}
+EXPORT_SYMBOL_GPL(cdns3_core_remove);
+
+/**
+ * cdns3_plat_remove() - unbind drd driver and clean up
+ * @pdev: Pointer to Linux platform device
+ */
+static void cdns3_plat_remove(struct platform_device *pdev)
+{
+ cdns3_core_remove(platform_get_drvdata(pdev));
+}
#ifdef CONFIG_PM
-static int cdns3_set_platform_suspend(struct device *dev,
- bool suspend, bool wakeup)
+static int cdns3_set_platform_suspend(struct cdns *cdns, bool suspend, bool wakeup)
{
- struct cdns *cdns = dev_get_drvdata(dev);
- int ret = 0;
-
if (cdns->pdata && cdns->pdata->platform_suspend)
- ret = cdns->pdata->platform_suspend(dev, suspend, wakeup);
+ return cdns->pdata->platform_suspend(cdns->dev, suspend, wakeup);
- return ret;
+ return 0;
}
-static int cdns3_controller_suspend(struct device *dev, pm_message_t msg)
+static int cdns3_controller_suspend(struct cdns *cdns, pm_message_t msg)
{
- struct cdns *cdns = dev_get_drvdata(dev);
+ struct device *dev = cdns->dev;
bool wakeup;
unsigned long flags;
@@ -242,7 +268,7 @@ static int cdns3_controller_suspend(struct device *dev, pm_message_t msg)
else
wakeup = device_may_wakeup(dev);
- cdns3_set_platform_suspend(cdns->dev, true, wakeup);
+ cdns3_set_platform_suspend(cdns, true, wakeup);
set_phy_power_off(cdns);
spin_lock_irqsave(&cdns->lock, flags);
cdns->in_lpm = true;
@@ -252,9 +278,8 @@ static int cdns3_controller_suspend(struct device *dev, pm_message_t msg)
return 0;
}
-static int cdns3_controller_resume(struct device *dev, pm_message_t msg)
+static int cdns3_controller_resume(struct cdns *cdns, pm_message_t msg)
{
- struct cdns *cdns = dev_get_drvdata(dev);
int ret;
unsigned long flags;
@@ -277,7 +302,7 @@ static int cdns3_controller_resume(struct device *dev, pm_message_t msg)
if (ret)
return ret;
- cdns3_set_platform_suspend(cdns->dev, false, false);
+ cdns3_set_platform_suspend(cdns, false, false);
spin_lock_irqsave(&cdns->lock, flags);
cdns_resume(cdns);
@@ -293,26 +318,37 @@ static int cdns3_controller_resume(struct device *dev, pm_message_t msg)
return ret;
}
-static int cdns3_plat_runtime_suspend(struct device *dev)
+int cdns3_runtime_suspend(struct cdns *cdns)
{
- return cdns3_controller_suspend(dev, PMSG_AUTO_SUSPEND);
+ return cdns3_controller_suspend(cdns, PMSG_AUTO_SUSPEND);
}
+EXPORT_SYMBOL_GPL(cdns3_runtime_suspend);
-static int cdns3_plat_runtime_resume(struct device *dev)
+int cdns3_runtime_resume(struct cdns *cdns)
{
- return cdns3_controller_resume(dev, PMSG_AUTO_RESUME);
+ return cdns3_controller_resume(cdns, PMSG_AUTO_RESUME);
}
+EXPORT_SYMBOL_GPL(cdns3_runtime_resume);
-#ifdef CONFIG_PM_SLEEP
+static int cdns3_dev_runtime_suspend(struct device *dev)
+{
+ return cdns3_runtime_suspend(dev_get_drvdata(dev));
+}
+
+static int cdns3_dev_runtime_resume(struct device *dev)
+{
+ return cdns3_runtime_resume(dev_get_drvdata(dev));
+}
-static int cdns3_plat_suspend(struct device *dev)
+#ifdef CONFIG_PM_SLEEP
+int cdns3_pm_suspend(struct cdns *cdns)
{
- struct cdns *cdns = dev_get_drvdata(dev);
+ struct device *dev = cdns->dev;
int ret;
cdns_suspend(cdns);
- ret = cdns3_controller_suspend(dev, PMSG_SUSPEND);
+ ret = cdns3_controller_suspend(cdns, PMSG_SUSPEND);
if (ret)
return ret;
@@ -321,18 +357,30 @@ static int cdns3_plat_suspend(struct device *dev)
return ret;
}
+EXPORT_SYMBOL_GPL(cdns3_pm_suspend);
+
+int cdns3_pm_resume(struct cdns *cdns)
+{
+ return cdns3_controller_resume(cdns, PMSG_RESUME);
+}
+EXPORT_SYMBOL_GPL(cdns3_pm_resume);
+
+static int cdns3_dev_pm_suspend(struct device *dev)
+{
+ return cdns3_pm_suspend(dev_get_drvdata(dev));
+}
-static int cdns3_plat_resume(struct device *dev)
+static int cdns3_dev_pm_resume(struct device *dev)
{
- return cdns3_controller_resume(dev, PMSG_RESUME);
+ return cdns3_pm_resume(dev_get_drvdata(dev));
}
#endif /* CONFIG_PM_SLEEP */
#endif /* CONFIG_PM */
static const struct dev_pm_ops cdns3_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(cdns3_plat_suspend, cdns3_plat_resume)
- SET_RUNTIME_PM_OPS(cdns3_plat_runtime_suspend,
- cdns3_plat_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(cdns3_dev_pm_suspend, cdns3_dev_pm_resume)
+ SET_RUNTIME_PM_OPS(cdns3_dev_runtime_suspend,
+ cdns3_dev_runtime_resume, NULL)
};
#ifdef CONFIG_OF
diff --git a/drivers/usb/cdns3/glue.h b/drivers/usb/cdns3/glue.h
new file mode 100644
index 000000000000..67cd1073b555
--- /dev/null
+++ b/drivers/usb/cdns3/glue.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * glue.h - Cadence USB3 DRD glue header
+ */
+
+#ifndef __DRIVERS_USB_CDNS3_GLUE_H
+#define __DRIVERS_USB_CDNS3_GLUE_H
+
+#include <linux/types.h>
+
+#include "core.h"
+
+struct platform_device;
+
+/**
+ * struct cdns3_probe_data - Parameters passed to cdns3_core_probe()
+ * @cdns: Cadence DRD controller context (allocated by the glue driver)
+ * @pdev: Platform device for resources and IRQs
+ */
+struct cdns3_probe_data {
+ struct cdns *cdns;
+ struct platform_device *pdev;
+};
+
+/**
+ * cdns3_core_probe - Initialize the Cadence USB3 platform core
+ * @data: Controller context and platform device supplied by the glue layer
+ *
+ * Performs resource mapping, PHY setup, cdns_init(), role setup, and runtime PM
+ * configuration for the standard platform binding of the Cadence USB3/USBSSP DRD IP.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int cdns3_core_probe(const struct cdns3_probe_data *data);
+
+/**
+ * cdns3_core_remove - Tear down the Cadence USB3 platform core
+ * @cdns: Controller context previously initialized by cdns3_core_probe()
+ */
+void cdns3_core_remove(struct cdns *cdns);
+
+/*
+ * The following callbacks are for glue drivers to invoke from their own
+ * &dev_pm_ops, so platform-specific work can wrap the shared controller logic.
+ */
+int cdns3_runtime_suspend(struct cdns *cdns);
+int cdns3_runtime_resume(struct cdns *cdns);
+int cdns3_pm_suspend(struct cdns *cdns);
+int cdns3_pm_resume(struct cdns *cdns);
+
+#endif /* __DRIVERS_USB_CDNS3_GLUE_H */
--
2.50.1
next prev parent reply other threads:[~2026-05-11 2:43 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-11 2:42 [PATCH 0/4] Add CIX Sky1 Cadence USB3 support Peter Chen
2026-05-11 2:42 ` Peter Chen [this message]
2026-05-11 23:02 ` [PATCH 1/4] usb: cdns3: plat: Expose platform core driver as library sashiko-bot
2026-05-12 7:03 ` Peter Chen
2026-05-11 2:42 ` [PATCH 2/4] usb: cdns3: sky1: Add cdnsp-sky1 glue driver Peter Chen
2026-05-11 23:17 ` sashiko-bot
2026-05-12 7:43 ` Peter Chen
2026-05-11 2:42 ` [PATCH 3/4] dt-bindings: usb: add CIX Sky1 Cadence USB3 controller Peter Chen
2026-05-15 7:54 ` Krzysztof Kozlowski
2026-05-15 10:25 ` Peter Chen
2026-05-15 11:18 ` Krzysztof Kozlowski
2026-05-11 2:42 ` [PATCH 4/4] arm64: dts: cix: add Sky1 USB4 and USB5 controllers Peter Chen
2026-05-11 23:59 ` sashiko-bot
2026-05-12 3:10 ` Peter Chen
2026-05-15 7:54 ` Krzysztof Kozlowski
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=20260511024244.981941-2-peter.chen@cixtech.com \
--to=peter.chen@cixtech.com \
--cc=arnd@arndb.de \
--cc=cix-kernel-upstream@cixtech.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=pawell@cadence.com \
--cc=robh@kernel.org \
--cc=rogerq@kernel.org \
/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.